Est-ce que quelqu'un sait comment je détecterais que transform: translate3d(x,y,z)
est disponible?
Mon problème est que je veux utiliser translate3d
sur tous les navigateurs où il est pris en charge, car il a tendance à utiliser l'accélération matérielle et donc plus fluide pour l'animation, puis à retomber à translate
où ce n'est pas le cas.
Découvrez cette solution .
Il est basé sur le fait que si un navigateur prend en charge les transformations, la valeur de
window.getComputedStyle(el).getPropertyValue('transform')
sera une chaîne contenant la matrice de transformation, lorsqu'une transformation 3D sera appliquée à l'élément el
. Sinon, ce sera undefined
ou la chaîne 'none'
, comme dans le cas d'Opera 12.02.
Cela fonctionne sur tous les principaux navigateurs.
Le code:
function has3d() {
if (!window.getComputedStyle) {
return false;
}
var el = document.createElement('p'),
has3d,
transforms = {
'webkitTransform':'-webkit-transform',
'OTransform':'-o-transform',
'msTransform':'-ms-transform',
'MozTransform':'-moz-transform',
'transform':'transform'
};
// Add it to the body to get the computed style.
document.body.insertBefore(el, null);
for (var t in transforms) {
if (el.style[t] !== undefined) {
el.style[t] = "translate3d(1px,1px,1px)";
has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]);
}
}
document.body.removeChild(el);
return (has3d !== undefined && has3d.length > 0 && has3d !== "none");
}
Le billet de blog original annonçant les transformations 3D comporte une démo image flip , qui le fait avec une requête multimédia, comme ceci:
@media all and (-webkit-transform-3d) {
/* Use the media query to determine if 3D transforms are supported */
#flip-container {
-webkit-perspective: 1000;
}
#flip-card {
width: 100%;
height: 100%;
-webkit-transform-style: preserve-3d;
-webkit-transition: -webkit-transform 1s;
}
#flip-container:hover #flip-card {
-webkit-transform: rotateY(180deg);
}
}
Cet article de blog contient une bonne introduction aux requêtes des médias. This a quelques détails supplémentaires.
Vous pouvez essayer CCS3 @supports :
@supports (transform: translate3d) {
div {
transform : translate3d(20px,0,0);
}
}
@supports not (transform: translate3d) {
div {
transform: translate(20px,0);
}
}
//The following is based on iScroll4's tests to determine if a browser supports CSS3 3D transforms.
var has3d = function() {
return ('WebKitCSSMatrix' in window && 'm11' in new WebKitCSSMatrix());
}
Je suggère d'utiliser Modernizr .
Il permet la détection de toute une gamme de fonctionnalités du navigateur, y compris les transformations 3D. Il fournit également une méthode de spécification de règles CSS pour les navigateurs dotés de fonctionnalités différentes ou non.
J'espère que cela pourra aider.
Je bricolais avec un moyen de vérifier le support 3d .. utilisait cette implémentation de Jeffery Way dans cet article . Permet moins de code et plus de cas d'utilisation;)
/**
* Test For CSS3 property support
* use 'perspective' to test for 3d support
*/
var supports = (function() {
'use strict';
var div = document.createElement('div'),
vendors = 'Khtml ms O Moz Webkit'.split(' '),
len = vendors.length;
return function(prop) {
if (prop in div.style) return true;
prop = prop.replace(/^[a-z]/, function(val) {
return val.toUpperCase();
});
while(len--) {
if (vendors[len] + prop in div.style) {
return true;
}
}
return false;
};
})();
if(supports('perspective')) {
// do 3d stuff
}
Bootstrap utilise le code suivant:
@media all and (transform-3d), (-webkit-transform-3d) {
.carousel-inner > .carousel-item {
transition: transform 0.6s ease-in-out;
backface-visibility: hidden;
perspective: 1000px;
}
.carousel-inner > .carousel-item.next,
.carousel-inner > .carousel-item.active.right {
left: 0;
transform: translate3d(100%, 0, 0);
}
.carousel-inner > .carousel-item.prev,
.carousel-inner > .carousel-item.active.left {
left: 0;
transform: translate3d(-100%, 0, 0);
}
.carousel-inner > .carousel-item.next.left,
.carousel-inner > .carousel-item.prev.right,
.carousel-inner > .carousel-item.active {
left: 0;
transform: translate3d(0, 0, 0);
}
}
Ce code est ajusté pour tester Transformations 3D support et autres fonctionnalités CSS3.
L'avantage de ce code est qu'il détecte le préfixe du fournisseur pris en charge (le cas échéant). Appeler:
testCSSSupport('transform')
Valeurs de retour possibles:
false
, si fonctionnalité non prise en charge, ou
{
vendor: 'moz',
cssStyle: '-moz-transform',
jsStyle: 'MozTransform'
}
quand fonctionnalité prise en charge
/**
* Test for CSS3 feature support. Single-Word properties only by now.
* This function is not generic, but it works well for transition and transform at least
*/
testCSSSupport: function (feature, cssTestValue/* optional */) {
var testDiv,
featureCapital = feature.charAt(0).toUpperCase() + feature.substr(1),
vendors = ['', 'webkit', 'moz', 'ms'],
jsPrefixes = ['', 'Webkit', 'Moz', 'ms'],
defaultTestValues = {
transform: 'translateZ(0.5em) rotateY(10deg) scale(2)'
// This will test for 3D transform support
// Use translateX to test 2D transform
},
testFunctions = {
transform: function (jsProperty, computed) {
return computed[jsProperty].substr(0, 9) === 'matrix3d(';
}
};
function isStyleSupported(feature, jsPrefixedProperty) {
if (jsPrefixedProperty in testDiv.style) {
var testVal = cssTestValue || defaultTestValues[feature],
testFn = testFunctions[feature];
if (!testVal) {
return false;
}
//Assume browser without getComputedStyle is either IE8 or something even more poor
if (!window.getComputedStyle) {
return false;
}
testDiv.style[jsPrefixedProperty] = testVal;
var computed = window.getComputedStyle(testDiv);
if (testFn) {
return testFn(jsPrefixedProperty, computed);
}
else {
return computed[jsPrefixedProperty] === testVal;
}
}
}
//Create a div for tests and remove it afterwards
if (!testDiv) {
testDiv = document.createElement('div');
document.body.appendChild(testDiv);
setTimeout(function () {
document.body.removeChild(testDiv);
testDiv = null;
}, 0);
}
var cssPrefixedProperty,
jsPrefixedProperty;
for (var i = 0; i < vendors.length; i++) {
if (i === 0) {
cssPrefixedProperty = feature; //todo: this code now works for single-Word features only!
jsPrefixedProperty = feature; //therefore box-sizing -> boxSizing won't work here
}
else {
cssPrefixedProperty = '-' + vendors[i] + '-' + feature;
jsPrefixedProperty = jsPrefixes[i] + featureCapital;
}
if (isStyleSupported(feature, jsPrefixedProperty)) {
return {
vendor: vendors[i],
cssStyle: cssPrefixedProperty,
jsStyle: jsPrefixedProperty
};
}
}
return false;
}