qu'est-ce que -webkit-transform: translate3d (0,0,0); exactement faire? Appliquer sur le corps?

88

que fait -webkit-transform: translate3d(0,0,0); exactement? At-il des problèmes de performances? Dois-je simplement l'appliquer au corps ou à des éléments individuels? Il semble améliorer considérablement les événements de défilement.

Merci pour la leçon!

WIWIWWIISpitFire
la source
4
Ce que les réponses manquent: Cela traduit en fait l'élément de 0 pixel sur les axes x, y et z. ;)
insérer
Il a également un impact sur le rendu des polices, particulièrement visible sur les grandes tailles de police. Sinon, les bords lisses apparaissent à nouveau crénelés. Cela peut être spécifique au navigateur ou au système d'exploitation, observé dans Chrome 33 sur Windows 7.
patrickj
1
@patrickj J'ai également commencé à remarquer un comportement légèrement différent avec translate3d(0,0,0)Chrome 33 (33.0.1750.117m) sous Windows 7. Cela rendait l'un de mes éléments invisible, je l'ai donc supprimé.
David Sherret
2
Pour référence future: will-changeséparera également l'élément html dans sa propre couche. developer.mozilla.org/en-US/docs/Web/CSS/will-change . will-changeremplacera le -webkit-transform:translate3d(0,0,0)hack.
Jason Lydon
ne l'utilisez pas avec le sélecteur * css tous mes liens sont devenus inactifs :)
stefan

Réponses:

111

-webkit-transform: translate3d(0,0,0); permet à certains appareils d'exécuter leur accélération matérielle.

Une bonne lecture se trouve ici

Les applications natives peuvent accéder à l'unité de traitement graphique (GPU) de l'appareil pour faire voler les pixels. Les applications Web, en revanche, fonctionnent dans le contexte du navigateur, ce qui permet au logiciel de faire la plupart (sinon la totalité) du rendu, ce qui réduit la puissance des transitions. Mais le Web rattrape son retard et la plupart des éditeurs de navigateurs proposent désormais une accélération matérielle graphique au moyen de règles CSS particulières.

L'utilisation -webkit-transform: translate3d(0,0,0);mettra le GPU en action pour les transitions CSS, les rendant plus fluides (FPS plus élevés).

Remarque: translate3d(0,0,0) ne fait rien par rapport à ce que vous voyez. il déplace l'objet de 0px sur les axes x, y et z. Ce n'est qu'une technique pour forcer l'accélération matérielle.


Une alternative est -webkit-transform: translateZ(0). Et s'il y a un scintillement sur Chrome et Safari en raison de transformations, essayez -webkit-backface-visibility: hiddenet -webkit-perspective: 1000. Pour plus d'informations, reportez-vous à cet article .

Yotam Omer
la source
Je ne suis pas sûr que l'application d'une transformation matricielle sur la texture en cache améliorerait vraiment les avantages. Lorsque le contenu est déplacé de la texture mise en cache vers le framebuffer, la transformation améliore les performances pour les opérations complexes, mais ne présente aucun avantage pour les événements de peinture normaux. Cela ne fera aucun mal et n'aura aucun avantage. Corrigez-moi si je me trompe?
Mathew Kurian
Je pense que même les peintures normales seront accélérées .. l'un des critères de création de calque est "les propriétés CSS de transformation 3D ou perspective".
Yotam Omer
Par exemple, le carrousel de bootstrap l'utilise, tout en déplaçant l'image affichée de droite à gauche.
Ethan
@YotamOmer Peut-on alternativement utiliser translateZ (0) ou scale3d (1,1,1) pour engager l'accélérateur h / w?
Ethan
1
@Ethan Oui, selon cela, les deux devraient fonctionner. Je ne connaissais que la transformation 3D, mais apparemment, cela translateZfera également l'affaire dans la plupart des navigateurs.
Yotam Omer
12

Je n'ai pas vu de réponse ici qui explique cela. De nombreuses transformations peuvent être effectuées en calculant chacune des divoptions et ses options à l'aide d'un ensemble complexe de validation. Cependant, si vous utilisez une fonction 3D, chacun des éléments 2D dont vous disposez est considéré comme des éléments 3D et nous pouvons effectuer une transformation matricielle sur ces éléments à la volée. Cependant, la plupart des éléments sont déjà "techniquement" accélérés par le matériel car ils utilisent tous le GPU. Mais, les transformations 3D fonctionnent directement sur les versions mises en cache de chacun de ces rendus 2D (ou versions mises en cache du div) et utilisent directement une transformation matricielle sur elles (qui sont vectorisées et parallélisées FP mathématiques).

Il est important de noter que les transformations 3D apportent UNIQUEMENT des modifications aux entités d'un div 2D mis en cache (en d'autres termes, le div est déjà une image rendue). Ainsi, des choses comme changer la largeur et la couleur de la bordure ne sont plus "3D" pour être vaguement parlant. Si vous y réfléchissez, la modification de la largeur des bordures vous oblige à restituer le divcar et à le remettre en cache afin que les transformations 3D puissent être appliquées.

J'espère que cela a du sens et faites-moi savoir si vous avez d'autres questions.

Pour répondre à votre question, translate3d: 0x 0y 0zne ferait rien puisque les transformations travaillent directement sur la texture qui est formée en exécutant les sommets du divdans le shader GPU. Cette ressource shader est maintenant mise en cache et une matrice sera appliquée lors du dessin sur le frame buffer. Donc, fondamentalement, il n'y a aucun avantage à faire cela.

C'est ainsi que le navigateur fonctionne en interne.

Étape 1: analyser l'entrée

<div style = "position:absolute;left:0;right:0;bottom:0;top:0;"></div>

Étape 2: Développer une couche composite

CompositeLayer compLayer = new CompositeLayer();
compLayer.setPosition(0, 0, 0, 0);
compLayer.setPositioning(ABSOLUTE); // Note. this is psuedocode. The actual code
Pipeline.add(compLayer, zIndex); // would be significantly more complex.

Étape 3: Rendu de la couche composite

for (CompositeLayer compLayer : allCompositeLayers){

     // Create and set cacheTexture as active target
     Texture2D cacheTexture = new Texture2D();
     cacheTexture.setActive();

     // Draw to cachedTexture
     Pipeline.renderVertices(compLayer.getVertices());
     Pipeline.setTexture(compLayer.getBackground());
     Pipeline.drawIndexed(compLayer.getVertexCount());

     // Set the framebuffer as active target
     frameBuffer.setActive();

     // Render to framebuffer from texture and **applying transformMatrix**
     Pipeline.renderFromCache(cacheTexture, transformMatrix);
}
Mathew Kurian
la source
6

Il y a un bogue avec le défilement dans MobileSafary (iOS 5) qui conduit à apparaître des artefacts comme des copies d'éléments d'entrée dans le conteneur de défilement.

L'utilisation de translate3d pour chaque élément enfant peut corriger cet étrange bogue. Voici un exemple de CSS qui m'a sauvé la journée.

.scrolling-container {
    overflow: auto;
    -webkit-overflow-scrolling: touch;
}

.scrolling-container .child-element {
    position: relative;
    -webkit-transform: translate3d(0,0,0);
}
Serge Seletskyy
la source
5

Translate3D force l'accélération matérielle. Les animations, transitions et transitions CSS ne sont pas automatiquement accélérées par GPU et s'exécutent à la place à partir du moteur de rendu logiciel plus lent du navigateur.Pour utiliser GPU, nous utilisons translate3d

Actuellement, les navigateurs comme Chrome, FireFox, Safari, IE9 + et la dernière version d'Opera sont tous livrés avec une accélération matérielle, ils ne l'utilisent que lorsqu'ils ont une indication qu'un élément DOM en bénéficierait.

Prasanna Aarthi
la source
3

Sachez que cela crée un contexte d'empilement (plus ce que les autres réponses ont dit), il ne possède potentiellement un effet sur ce que vous voyez, par exemple , faire quelque chose apparaît sur une superposition quand il est pas censé.

Jason Young
la source