web-dev-qa-db-fra.com

Détection du support 'transform: translate3d'

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.

36
Jamie

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");
}
42
Lorenzo Polidori

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.

10
Jonathan Tran

Vous pouvez essayer CCS3 @supports :

@supports (transform: translate3d) {
  div {
    transform : translate3d(20px,0,0);
  }
}

@supports not (transform: translate3d) {
  div {
    transform: translate(20px,0);
  }
}

Puis-je utiliser @support

9
//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());
}
4
elrasguno

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.

4
Spudley

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
}
1
souporserious

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);
    }
}
0
Sergej

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;
}
0
Dan