Fermer

décembre 22, 2018

Dessin et animation performants en CSS


Dans le dernier blog, nous vous avons montré comment améliorer les performances d'animation en CSS avec un exemple sur le thème des vacances. Maintenant, nous y retournons pour nous attaquer au dessin!

J'ai trouvé cette jolie animation en ligne et je l'ai nettoyé un peu pour une application Secret Santa sur laquelle mon mari et moi avons travaillé pour les vacances. Cependant, nous avons dû commenter l'animation et l'arbre de Noël, car cela causait un crash de notre ancien ordinateur portable MacBook. Même si mon nouveau MacBook n’a pas mieux résisté, les fans nous ont dit que nous étions sur le point de partir dans l’espace extra-atmosphérique lorsque l’animation a duré plus de quelques minutes.

 Je répète que notre animation tombe de la neige devant un bloc rectangulaire de Noël vert arbre

Une partie de notre problème de peinture tenait à la façon dont nous animions la neige qui tombait. J'ai écrit cet article pour couvrir «Animating Performantly in CSS», où nous réanimons ces choses de manière plus saine. J'ai aussi pensé que cet article serait trop monstrueux si j'apprenais à dessiner ET à animer, alors jetez un œil à cette première partie. Voici le départ StackBlitz .

Pour résumer, cependant, au lieu d’animer la position de fond de la neige, nous avons utilisé transform pour déplacer la neige sur l’écran. Si vous parvenez à animer quelque chose à l'aide d'une transformation ou d'un changement d'opacité, FAITES-LE.

Les navigateurs modernes peuvent animer quatre choses à moindre coût: la position, l'échelle, la rotation et l'opacité. – Paul Lewis & Paul Irish

Après avoir modifié l'animation, nous avons constaté une amélioration des performances. Plus précisément, les avertissements de notre tableau de bord ont disparu! Hourra! Cependant, nous avons toujours un problème de peinture. Voici un aperçu peut-être trop détaillé des performances en coulisse:

Remarque: pour une meilleure lisibilité, certaines de nos captures d’écran montrent que DevTools est désamarré dans une fenêtre distincte.

 Panneau de performances affichant du code non optimisé avec un processeur plus élevé [19659004] J'ai ralenti le processeur 6x pour simuler un MacBook chugging (je l'aurais mis plus bas si j'avais pu). Remarque: Tous nos tests seront exécutés avec un processeur 6 fois plus lent, même notre dernier code performant, pour une comparaison homogène. </p>
<p> Comme l'explique Paul Lewis dans son article <a href= «Simplifiez la complexité de la peinture et réduisez les zones de peinture» :

La peinture est le processus de remplissage des pixels qui finissent par être composés sur les écrans des utilisateurs. C'est souvent la tâche la plus longue de toutes les tâches en cours et à éviter autant que possible.

Cela peut sembler une tâche qui ne ressemble pas beaucoup à la peinture, mais si vous parcourez la chronologie, vous constaterez que chaque image a une sorte de peinture:

 gif nettoyant à travers les cadres du "mauvais" dessin en css

Alors que nous optimisons ce mauvais garçon, nous ne verrons qu'un processeur inactif dans nos futurs cadres:

 gif scruter les cadres du "bon" dessin en css

Alors, qu'avons-nous optimisé? Voyons maintenant comment l'arbre et la neige sont dessinés.

Ainsi, l'arbre est dessiné sous forme de gradients linéaires multiples sur l'image de fond .christmas :

. image:
  // Haut
  gradient linéaire ($ gradient-angel, assombrir ($ feuille-couleur, 0%) 8%, transparent 8.5%),
  dégradé linéaire (- $ ange en dégradé, assombrir ($ couleur feuille, 1,5%) 8%, transparent 8,5%),
  // milieu
  gradient linéaire ($ gradient-angel, assombrir ($ feuille-couleur, 3%) 10%, transparent 10,5%),
  dégradé linéaire (- $ ange en dégradé, assombrir ($ couleur feuille, 4.5%) 10%, transparent 10.5%),
  // bas
  gradient linéaire ($ gradient-angel, assombrir ($ feuille-couleur, 6%) 12%, transparent 12,5%),
  gradient linéaire (- $ ange-gradient, assombrir ($ couleur-feuille, 7.5%) 12%, transparent 12.5%),
  // tronc
  gradient linéaire (80deg, assombrir ($ trunk-color, 0%) 5%, transparent 5,5%),
  gradient linéaire (-80deg, assombrir ($ trunk-color, 1,5%) 5%, transparent 5,5%);
position de fond:
  // laisse-dessus
  $ taille / 2 $ taille / 2.5, $ taille / 2 $ taille / 2.5,
  // laisse-milieu
  $ taille / 2 $ taille / 1.8, $ taille / 2 $ taille / 1.8,
  // feuilles en bas
  $ taille / 2 $ taille / 1.4, $ taille / 2 $ taille / 1.4,
  // tronc
  $ size / 2 $ size / 1.25, $ size / 2 $ size / 1.25; 

Commençons par supprimer tous les styles d’arbres de christmas.scss . Ensuite, créez un fichier nommé tree.scss que nous veillerons à importer dans le fichier styles.scss .

 de notre fichier styles.scss

O Tannenbaum, How Lovely Are Vos branches positionnées

Je sais que dessiner / positionner / animer en CSS peut parfois être effrayant, alors allons-y lentement et prenons-les étape par étape. Voici la structure de l'arbre:

  
  
    
    
    
    
  

Premièrement, nous devons positionner notre arbre-mère .tree de manière à ce que les feuilles et le tronc puissent être positionnés.

Position: absolute; Position basée sur le parent positionné non statique le plus proche (hors du flux de page)

 // tree.scss

$ hauteur-arbre: $ taille / 2;
.tree {
  en haut: calc (50% - # {$ tree-height / 2});
  à gauche: 50%;
  position: absolue;
  largeur: 0;
  hauteur: $ tree-height;
} 

Nous fixons le sommet de .tree à 50% de .christmas (moins la moitié de $ hauteur d’arbre ). La gauche de .tree est à 50% (le milieu).

Nous donnons la position absolue de l'arbre (plutôt que la position fixée comme .christmas ) parce que nous voulons l'arbre et ses enfants seront toujours placés au milieu de .christmas . Pour l'instant .Christmas est en position fixe, cependant, si nous voulions changer cela et le déplacer sur la page, nous aurions besoin de .tree pour rester en position absolue, pour rester à l'intérieur .christmas .

Nous voudrons positionner les feuilles et le tronc par rapport à la position centrale de Noël, nous lui avons donc attribué une largeur de 0. Si vous commentez cela, vous ne remarquerez aucun changement, Chrome devine la largeur que devrait avoir cet .tree . Mais chaque fois que vous positionnez les enfants en fonction de l’emplacement exact de leurs parents, vous ne voulez pas laisser la largeur (ou la hauteur) au hasard et à l’interprétation du navigateur. Logiquement, la hauteur doit être aussi grande que l'arbre: hauteur: $ arbre-hauteur; .

Je vais donner à l'avant .tree pour que vous puissiez voyez où il se trouve à l’écran:

 capture d’écran de la classe d’arbres entourée d’un cadre rouge

C’est exactement là où nous avons besoin de .tree nous sommes prêts à commencez à dessiner les feuilles et le tronc!

Dessin des triangles

La prochaine étape à laquelle nous devons nous attaquer est de dessiner les triangles pour fabriquer les feuilles! Dessiner un triangle en CSS implique une combinaison de largeur / hauteur et d’utilisation de bordures. Découvrez ce post tueur sur CSS Tricks intitulé «Les formes de CSS» pour des formes plus amusantes.

Si vous prenez l’avance et regardez le StackBlitz vous pourriez être submergé par les 75 lignes de CSS que nous utilisions pour dessiner les feuilles. Cependant, une fois décomposé en morceaux, vous verrez que nous réutilisons simplement la même forme de triangle:

 capture d'écran de notre feuille de style d'arbre

 $ leaf-size: $ tree -hauteur / 7;
$ largeur du tronc: $ hauteur-arbre / 6;

.feuilles {
  à droite: 50%;
  position: absolue;
  
  &::avant après {
    position: absolue;
    largeur: 0px;
    hauteur: 0px;
    bloc de visualisation;
    contenu: '';
    bordure: $ taille feuille transparente pleine;
  }
} 

Cette première partie prépare le terrain pour le succès des feuilles d’arbre de Noël. Seul, cela semble ridicule, mais nous avons mis beaucoup de styles réutilisables pour tous les éléments :: avant et :: après . Chaque div a essentiellement un :: avant et :: après que nous pouvons utiliser pour styler un triangle. Ainsi, les trois parties des feuilles (haut, milieu et bas) nous donnent chacune un :: avant et :: après créant ainsi six feuilles au total:

 capture d'écran de notre arbre montrant les segments du haut, du milieu et du bas

Passons maintenant au dessin de nos triangles:

 & :: before {
  à droite: 0;
  border-right-color: $ feuille-couleur;
  border-bottom-color: $ feuille-couleur;
}
&::après {
  gauche: 0;
  couleur de bordure à gauche: assombrit (couleur de feuille, 1,5%);
  couleur de bordure inférieure: fonce (couleur de la feuille, 1,5%);
} 

Comme vous pouvez le constater, la largeur et la hauteur de chaque triangle sont définies sur zéro. Nous donnons maintenant les éléments :: avant les limites inférieure et droite, et les éléments :: après afin de créer les deux angles droits nécessaires.

Nous Je vais réutiliser ces deux :: avant et :: après formes de feuilles sur les . feuilles mortes. et . feuilles mortes .bottom . Nous allons simplement ajuster la taille et le positionnement, ainsi que l'indice z. Nous sommes également en train de changer la couleur de la feuille pour qu’elle devienne légèrement plus sombre à mesure que nous descendons dans l’arbre, afin d’obtenir ce bel effet superposé.

Il ne nous manque plus maintenant qu’un magnifique tronc! Pour cela, nous allons dessiner un trapèze!

 $ trunk-edge: $ trunk-width / 2;
.tronc {
  right: calc (50% - # {($ tronc-largeur + ($ tronc-bords * 2)) / 2});
  en bas: 0;
  z-index: 1;
  position: absolue;
  width: $ trunk-width;
  hauteur: 0;
  border-right: $ trunk-edge solid transparent;
  border-bottom: $ trunk-width solide $ trunk-color;
  border-left: $ trunk-edge solid transparent;
} 

Avec cette belle CSS, nous utilisons à nouveau les bordures pour dessiner la forme souhaitée. Nous centrons le tronc de l'arbre et le plaçons au bas de .christmas . Enfin, nous lui donnons l'indice z le plus bas, c'est donc derrière toutes les feuilles.


capture d'écran montrant une paire de flocons de neige près de l'arbre de Noël

Redessiner la neige

La dernière étape de notre animation et de notre dessin de la perfection des arbres de Noël est… LA NEIGE! Nous devons supprimer les derniers bits de dégradés radiaux dans l’arrière-plan-image:

 capture d’écran du mauvais code

Nous allons supprimer tout ce qui est lié à la neige dans christmas.scss et créer un nouveau fichier snow.scss (que nous avons importé dans notre styles.scss ). Maintenant, dessiner des sphères est étonnamment plus facile que dessiner des triangles ou des trapèzes. Un cercle est tout simplement un carré dont les angles sont arrondis à 50%.

Le but de notre code HTML est donc de pouvoir ajouter de plus en plus d’éléments et, par conséquent, d’ajouter de plus en plus de neige à l’écran. Une rafale de neige sera composée de deux morceaux de neige (une plus petite, une plus grande) et placés «au hasard» dans la scène .christmas .


capture d'écran de index.html à côté du panneau de prévisualisation

Semblable à la façon dont nous avons utilisé :: avant et :: après pseudo-éléments pour styliser deux feuilles sur les arbres, nous allons faire la même chose pour deux flocons de neige dans une rafale. Tous les codes en double seront à l'intérieur .snow-flurry .

 $ snow-size: 5px;
.Rafales de neige {
  position: absolue;
  largeur: 0;
  hauteur: 0;
  z-index: 5;

  &::avant après {
    position: absolue;
    couleur de fond: blanc;
    rayon de bordure: 50%;
    contenu: '';
    box-shadow: 0 0 5px 2px blanc;
  }
} 

La seconde moitié de ces styles dessine les averses de neige rondes pour :: avant et :: après . Elle crée également un flou sur les bords à l’aide de Box-Shadow. Il s’agit bien sûr d’un choix de style et n’est pas obligatoire pour le survol!

Comme nous l’avons déjà mentionné, l’objectif est d’avoir des morceaux de neige plus petits et d’autres plus gros. Ce code nous permet d'accomplir ceci avec une multiplication amusante:

 $ snow-size: $ snow-size * 1.8;
&::avant {
  largeur: $ taille neige;
  hauteur: $ taille de la neige;
}

// pour des flocons de neige plus petits
$ taille de la neige: $ taille de la neige * .5;
&::après {
  largeur: $ taille neige;
  hauteur: $ taille de la neige;
} 

Enfin, nous allons porter nos compétences SASS à un niveau supérieur avec ce prochain bloc-code:

 $ flurry-groups-on-screen: 9;
@for $ i de 1 à $ flurry-groups-on-screen {
  &: nth-child (# {$ i}) :: before {
    en haut: # {aléatoire ($ taille)} px;
    gauche: # {aléatoire ($ taille)} px;
  }
  &: nth-child (# {$ i}) :: after {
    en haut: # {aléatoire ($ taille)} px;
    gauche: # {aléatoire ($ taille)} px;
  }
} 

Accrochez-vous à vos chapeaux de fête, ce n'est vraiment pas que compliqué. Tout d’abord, vous verrez la variable que j’ai appelée avec amour $ flurry-groups-at-screen qui spécifie de manière choquante le nombre de groupes survolés à l’écran. Nous utilisons ce nombre pour parcourir en boucle chaque groupe, puis nous plaçons chacun :: avant et :: après de manière aléatoire dans la taille de .christmas .

 $ groupes sur écran: 9;
@for $ i de 1 à $ flurry-groups-on-screen {
  &: nth-child (# {$ i}) :: before {
    en haut: # {aléatoire ($ taille)} px;
    gauche: # {aléatoire ($ taille)} px;
  }
  &: nth-child (# {$ i}) :: after {
    en haut: # {aléatoire ($ taille)} px;
    gauche: # {aléatoire ($ taille)} px;
  }
  // donc la neige tombe à des rythmes différents
  &: nième enfant (# {$ i}) {
    animation: il neige # {random (40) + 20} s en avant infinis linéaires;
  }
} 

Comme nous sommes déjà en train de boucler, j'ai pensé qu'il serait dommage de ne pas en profiter pour obtenir un effet vraiment cool. La dernière partie que je veux ajouter à ce morceau appellera notre animation (une version légèrement modifiée d’avant). Cependant, la durée de l'animation sera aléatoire, ce qui fera tomber la neige à des rythmes différents! SO COOL!

Nous sommes maintenant prêts à ajouter de l’animation et à le lancer dans le navigateur!

 $ snow-size: 5px;
.Rafales de neige {
  position: absolue;
  largeur: 0;
  hauteur: 0;
  z-index: 5;
  
  @configurations neigeuses {
    0% {
      transformer: traduire (0, - # {$ size});
    }
    100% {
      transform: translate (40px, $ size);
    }
  }
} 

Notre point de départ pour l'animation commence à 0, - taille $ et se termine à 40px, taille $ . Ça a l'air de tuer, surtout avec nos différentes minuties sur les flocons de neige qui tombent!

Remarque: j'ai ajusté les couleurs de certaines choses pour un aspect un peu plus agréable.

 gif de la scène de Noël finale [19659004] Découvrez le <a href= final StackBlitz .

J'espère que vous en apprendrez un peu plus sur la réalisation de dessins et d'animations performants en CSS! Je sais que cela peut être délicat, mais si gratifiant si vous y tenez! Nous avons (bien sûr!) Terminé avec une utilisation moindre du processeur et BEAUCOUP moins de peinture – nous pouvons même exécuter cette animation maintenant dans notre application Secret Santa!

 capture d'écran du panneau de performances après l'optimisation des animations et des dessins [19659004] Si cela ne vous suffisait pas et que Angular était votre truc, je vous encourage à lire ce billet que j'ai écrit à propos des animations personnalisées de <a href= dans Angular . Comme toujours, heureux de coder tout le monde et les vacances les plus heureuses !!


Les commentaires sont désactivés en mode Prévisualisation.






Source link