Maison >interface Web >tutoriel CSS >Transitions de dactylographie et de fenêtre dans CSS avec tan (atan2 ())

Transitions de dactylographie et de fenêtre dans CSS avec tan (atan2 ())

Joseph Gordon-Levitt
Joseph Gordon-Levittoriginal
2025-03-07 16:41:09736parcourir

Typecasting and Viewport Transitions in CSS With tan(atan2())

CSS a pu obtenir la longueur de la fenêtre, et le temps peut être retracé à ... (notes de vue) ... 2013! Étonnamment, c'était il y a plus de dix ans. De nos jours, obtenir la largeur de la fenêtre est aussi simple que l'écriture 100vw, mais qu'est-ce que cela signifie dans les pixels? Qu'en est-il des autres propriétés, telles que celles qui prennent des pourcentages, des angles ou des entiers?

Envisagez de modifier l'opacité d'un élément basé sur la taille de l'écran, de le faire tourner ou de définir la progression d'une animation. Tout d'abord, vous avez besoin de la fenêtre comme un entier - C'est actuellement impossible dans CSS, non?

Ce dont je veux parler ensuite n'est pas une découverte révolutionnaire, que Jane Oriin a décrite à merveille en 2023. En bref, nous pouvons utiliser une astuce (ou un attribut) étrange impliquant des fonctions trigonométriques tan() et atan2() pour convertir les types de longueur (tels que la fenêtre) en entiers. Cela ouvre de nombreuses nouvelles possibilités de mise en page pour , mais ma première expérience a été lors de la rédaction d'une entrée d'almanac, et je voulais juste rendre l'opacité de l'image réactive.

redimensionner le codepen, à mesure que la taille de l'écran devient plus petite, l'image devient plus transparente, et bien sûr, il y a des limites afin qu'elle ne devienne pas invisible:

C'est la façon la plus simple que nous puissions faire, mais il y en a plus. Par exemple, j'ai essayé de combiner de nombreux effets liés à la fenêtre pour faire cette démonstration. Redimensionner la démo et la page sera pleine de vitalité: les objets se déplacent, les changements d'arrière-plan et les wraps de texte en douceur.

Je pense que c'est vraiment cool, mais je ne suis pas un designer, donc c'est la meilleure façon dont mon cerveau peut penser. Cependant, cela peut être un peu trop pour l'introduction de cette technique de conversion de type, donc en tant que terrain d'entente, je ne me concentrerai que sur la conversion de titre pour montrer comment tout cela fonctionne:

Paramètres

L'idée derrière elle est de convertir

en radians (un moyen d'écrire des angles) en utilisant atan2() et de revenir à sa valeur d'origine en utilisant 100vw, l'avantage est qu'il apparaît comme un entier. Il doit être mis en œuvre comme ceci: tan()

<code>:root {
  --int-width: tan(atan2(100vw, 1px));
}</code>
Mais! Les navigateurs ne soutiennent pas beaucoup cette approche, donc plus d'emballage est nécessaire pour le faire fonctionner dans tous les navigateurs. Ce qui suit peut ressembler à de la magie (ou un non-sens), donc je recommande de lire l'article de Jane pour mieux le comprendre, mais que cela fonctionne dans tous les navigateurs:

<code>@property --100vw {
  syntax: "<length>";
  initial-value: 0px;
  inherits: false;
}

:root {
  --100vw: 100vw;
  --int-width: calc(10000 * tan(atan2(var(--100vw), 10000px)));
}</length></code>
Ne vous inquiétez pas trop. Ce qui compte, c'est notre précieuse variable

, ce qui sauve la taille de la fenêtre comme un entier! --int-width

Largeur: un nombre domine tout

Maintenant, nous avons la fenêtre comme un entier, mais ce n'est que la première étape. Cet entier n'est pas très utile en soi. Nous devons le convertir en quelque chose d'autre ensuite parce que:

  • différents attributs ont des unités et
  • différentes
  • Nous voulons que chaque attribut passe de la valeur de début à la valeur finale.

Considérons que l'opacité de l'image passe de 0 à 1, l'objet tourne de 0Deg à 360deg, ou l'élément offset-distance change de 0% à 100%. Nous voulons interpoler entre ces valeurs à mesure que --int-width devient plus gros, mais maintenant c'est juste un entier qui change généralement entre 0 et 1600, ce qui est inflexible et ne peut pas être facilement converti en aucune valeur finale.

La meilleure solution consiste à convertir --int-width en un nombre de 0 à 1. Ainsi, à mesure que l'écran s'agrandit, nous pouvons le multiplier par la valeur finale souhaitée. En raison de l'absence d'un meilleur nom, j'appelle cette valeur de "0 à 1" --wideness. Si nous avons --wideness, tous les derniers exemples sont possibles:

<code>:root {
  --int-width: tan(atan2(100vw, 1px));
}</code>

Par conséquent, --wideness est une valeur entre 0 et 1, indiquant la largeur de l'écran: 0 signifie lorsque l'écran est étroit et 1 signifie lorsque l'écran est large. Mais nous devons encore définir la signification de ces valeurs dans la fenêtre. Par exemple, nous pourrions vouloir que 0 soit 400px et 1 pour être 1200px et notre conversion de la fenêtre fonctionnera entre ces valeurs. Les valeurs en dessous et au-dessus sont serrées à 0 et 1, respectivement.

Dans CSS, nous pouvons l'écrire comme ceci:

<code>@property --100vw {
  syntax: "<length>";
  initial-value: 0px;
  inherits: false;
}

:root {
  --100vw: 100vw;
  --int-width: calc(10000 * tan(atan2(var(--100vw), 10000px)));
}</length></code>

En plus des conversions simples, la variable --wideness nous permet également de définir les limites inférieures et supérieures où la conversion doit fonctionner. Encore mieux, nous pouvons définir la zone de conversion au milieu afin que l'utilisateur puisse l'apprécier pleinement. Sinon, l'écran doit être 0px pour que --wideness atteigne 0, et qui sait à quel point il doit être large pour atteindre 1.

Nous avons - la sensibilisation. Quelle est la prochaine étape?

Tout d'abord, la balise de titre est divisée en portées, car il n'y a pas de méthode CSS pour sélectionner des mots spécifiques dans la phrase:

<code>/* 如果 `--wideness` 为 0.5 */

.element {
  opacity: var(--wideness); /* 为 0.5 */
  translate: rotate(calc(wideness(400px, 1200px) * 360deg)); /* 为 180deg */
  offset-distance: calc(var(--wideness) * 100%); /* 为 50% */
}</code>

Puisque nous allons nous envelopper, il est très important de ne pas défaire certaines valeurs par défaut:

<code>:root {
  /* 两个边界都是无单位的 */
  --lower-bound: 400;
  --upper-bound: 1200;

  --wideness: calc(
    (clamp(var(--lower-bound), var(--int-width), var(--upper-bound)) - var(--lower-bound)) / (var(--upper-bound) - var(--lower-bound))
  );
}</code>
La conversion

devrait fonctionner sans le style de base, mais il semble trop ordinaire. Si vous souhaitez les copier dans votre feuille de style, ils ressemblent à ceci:

Enfin, nos compétences actuelles sont les suivantes:

<code><h1>Resize and enjoy!</h1></code>

D'accord, c'est tout pour le paramètre. Il est maintenant temps d'utiliser nos nouvelles valeurs et d'effectuer la conversion de la fenêtre. Nous devons d'abord déterminer comment le titre doit être réorganisé pour s'adapter au petit écran: comme vous pouvez le voir dans la démo initiale, le premier span se déplace vers le haut et à droite, tandis que le second span se déplace dans la direction opposée, en bas et à gauche. Par conséquent, les positions finales des deux span sont converties aux valeurs suivantes:

<code>h1 {
  position: absolute; /* 保持文本居中 */
  white-space: nowrap; /* 禁用换行 */
}</code>

Les deux formules sont fondamentalement les mêmes, mais les symboles sont différents avant de continuer. Nous pouvons les réécrire immédiatement en introduisant une nouvelle variable --direction. Ce sera 1 ou -1 et définira la direction pour exécuter la transformation:

<code>:root {
  --int-width: tan(atan2(100vw, 1px));
}</code>

L'étape suivante consiste à introduire --wideness dans la formule afin que la valeur soit modifiée lorsque l'écran est redimensionné. Cependant, nous ne pouvons pas tout multiplier par --wideness. Pourquoi? Voyons ce qui se passe si nous faisons ceci:

<code>@property --100vw {
  syntax: "<length>";
  initial-value: 0px;
  inherits: false;
}

:root {
  --100vw: 100vw;
  --int-width: calc(10000 * tan(atan2(var(--100vw), 10000px)));
}</length></code>

Comme vous le verrez, tout est inversé! Lorsque l'écran est trop large, le mot enveloppera la ligne et lorsque l'écran est trop étroit, le mot enveloppera la ligne:

Contrairement à notre premier exemple, dans le premier exemple, la conversion se termine par --wideness passant de 0 à 1, nous voulons terminer la conversion car --wideness diminue de 1 à 0, c'est-à-dire que l'écran devient plus petit, la propriété doit atteindre sa valeur finale. Ce n'est pas grave, car nous pouvons réécrire notre formule comme soustraction, où la soustraction augmente à mesure que --wideness:

<code>/* 如果 `--wideness` 为 0.5 */

.element {
  opacity: var(--wideness); /* 为 0.5 */
  translate: rotate(calc(wideness(400px, 1200px) * 360deg)); /* 为 180deg */
  offset-distance: calc(var(--wideness) * 100%); /* 为 50% */
}</code>

Maintenant, lors du redimensionnement de l'écran, tout se déplacera dans la bonne direction!

Cependant, vous remarquerez comment les mots se déplacent en ligne droite et comment certains mots se chevauchent lors de la redimensionnement. Nous ne permettons pas cela car les utilisateurs avec une taille d'écran spécifique peuvent être coincés à ce stade de la conversion. La conversion de la fenêtre est cool, mais pas au détriment de la gâter l'expérience de certaines tailles d'écran.

Les mots ne doivent pas se déplacer en ligne droite, mais plutôt dans une courbe afin qu'ils contournent le mot central. Ne vous inquiétez pas, faire des courbes ici est plus facile qu'il n'y paraît: faites simplement bouger la travée deux fois plus vite que l'axe y sur l'axe des x. Cela peut être fait en multipliant --wideness par 2, bien que nous devons le limiter à 1 afin qu'il ne dépasse pas la valeur finale.

<code>:root {
  /* 两个边界都是无单位的 */
  --lower-bound: 400;
  --upper-bound: 1200;

  --wideness: calc(
    (clamp(var(--lower-bound), var(--int-width), var(--upper-bound)) - var(--lower-bound)) / (var(--upper-bound) - var(--lower-bound))
  );
}</code>

Regardez la belle courbe, et évitez simplement le texte central:

Ce n'est que le début!

Étonnamment à quel point il peut être puissant d'avoir une fenêtre en tant qu'entière, et encore plus fou, le dernier exemple est l'une des conversions les plus élémentaires que vous puissiez faire avec ce type de conversion. Une fois que vous avez terminé la configuration initiale, je peux imaginer qu'il y a plus de conversions possibles, et --wideness est très utile, tout comme maintenant avec une nouvelle fonctionnalité CSS.

J'espère en voir plus sur la "conversion de la fenêtre" à l'avenir, car ils font que le site Web se sent plus "en direct" que les sites Web adaptatifs.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:Création d'un flux "étoilé"Article suivant:Création d'un flux "étoilé"