


Comment créer un graphique animé de carrés imbriqués à l'aide de masques
Mar 18, 2025 am 11:03 AMNous avons de nombreux types de graphiques bien connus: bar, beignet, ligne, tarte, vous l'appelez. Toutes les bibliothèques de graphiques populaires les soutiennent. Ensuite, il existe les types de graphiques qui n'ont même pas de nom. Découvrez ce tableau de rêve avec des carrés empilés (imbriqués) qui peuvent aider à visualiser les tailles relatives, ou comment les différentes valeurs se comparent les unes aux autres:
Ce que nous faisons
Sans aucune interactivité, la création de ce design est assez simple. Une fa?on de le faire est d'empiler des éléments (par exemple, des éléments SVG
Mais les choses deviennent plus difficiles une fois que nous avons introduit une certaine interactivité. Voici comment cela devrait être: lorsque nous dépla?ons notre souris sur l'une des formes, nous voulons que les autres se fanent et s'éloignent.
Nous allons créer ces formes irrégulières à l'aide de rectangles et de masques - littéral
Maintenant, avant de commencer, vous vous demandez peut-être si une meilleure alternative au SVG à l'utilisation de formes personnalisées. C'est vraiment une possibilité! Mais des formes de dessin avec un
Par exemple, voici comment nous devrions représenter la plus grande forme bleue en utilisant un
<svg viewbox="0 0 320 320" width="320" height="320"> <chemin d="M320 0H0V56H264V320H320V0Z" fill="# 264653"></chemin> </svg>
Si le 0h0v56… n'a aucun sens pour vous, consultez ?la syntaxe du chemin SVG: un guide illustré? pour une explication approfondie de la syntaxe.
Les bases du graphique
étant donné un ensemble de données comme ceci:
type dataSetEntry = { étiquette: cha?ne; valeur: numéro; }; type dataSet = dataSetEntry []; const RawDataset: DataSet = [ {label: 'bad', valeur: 1231}, {label: 'début', valeur: 6321}, {étiquette: ?développement?, valeur: 10028}, {label: 'accompli', valeur: 12123}, {étiquette: 'exemplaire', valeur: 2120} ]]
… Nous voulons nous retrouver avec un SVG comme ceci:
<svg viewbox="0 0 320 320" width="320" height="320"> <rect width="320" height="320" y="0" fill="..."> rect> <rect width="264" height="264" y="56" fill="..."> rect> <rect width="167" height="167" y="153" fill="..."> <rect width="56" height="56" y="264" fill="..."> rect> <rect width="32" height="32" y="288" fill="..."> rect> </rect></rect></rect></rect></rect></svg>
Déterminer la valeur la plus élevée
Cela deviendra évident dans un instant pourquoi nous avons besoin de la valeur la plus élevée. Nous pouvons utiliser le math.max () pour l'obtenir. Il accepte n'importe quel nombre d'arguments et renvoie la valeur la plus élevée dans un ensemble.
const dataSetHighestValue: Number = Math.max ( ... RawDataset.map ((Entrée: DataSeTentry) => Entry.Value) ));
Comme nous avons un petit ensemble de données, nous pouvons simplement dire que nous obtiendrons 12123.
Calcul de la dimension des rectangles
Si nous regardons la conception, le rectangle représentant la valeur la plus élevée (12123) couvre toute la zone du graphique.
Nous avons arbitrairement choisi 320 pour les dimensions SVG. étant donné que nos rectangles sont des carrés, la largeur et la hauteur sont égales. Comment pouvons-nous faire 12123 égal à 320? Et les valeurs moins ?spéciales?? Quelle est la taille du rectangle 6321?
Interrogé une autre manière, comment cartographier un nombre d'une plage ([0, 12123]) à un autre ([0, 320])? Ou, en termes plus mathématiques, comment pouvons-nous évoluer une variable à un intervalle de [a, b]?
Pour nos fins, nous allons implémenter la fonction comme celle-ci:
const RemapValue = ( Valeur: numéro, Frommin: numéro, Frommax: numéro, Tomin: numéro, Tomax: numéro ): numéro => { return ((valeur - fromin) / (Frommax - fromin)) * (tomax - tomin) tomin; }; RemapValue (1231, 0, 12123, 0, 320); // 32 RemapValue (6321, 0, 12123, 0, 320); // 167 RemapValue (12123, 0, 12123, 0, 320); // 320
étant donné que nous cartographions les valeurs sur la même plage dans notre code, au lieu de passer les minimums et les maximums encore et encore, nous pouvons créer une fonction de wrapper:
const ValueReMapper = ( Frommin: numéro, Frommax: numéro, Tomin: numéro, Tomax: numéro ) => { return (valeur: nombre): numéro => { return remapValue (valeur, Frommin, Frommax, tomin, tomax); }; }; const RemapDatasetValuetOsvgDimension = ValueRemapper ( 0, dataSetHiGhestValue, 0, svgdimension ));
Nous pouvons l'utiliser comme ceci:
remapdatasetvalutosvgdimension (1231); // 32 remapdatasetvalutosvgdimension (6321); // 167 RemapdatasetvalutOsvgdimension (12123); // 320
Créer et insérer les éléments DOM
Ce qui reste a à voir avec la manipulation DOM. Nous devons créer les éléments
Notez que nous utilisons les CreateElementns au lieu de la création plus courante. C'est parce que nous travaillons avec un SVG. Les éléments HTML et SVG ont des spécifications différentes, donc ils relèvent d'un autre espace de noms URI. Il arrive juste que le CreateElement utilise facilement l'espace de noms HTML! Donc, pour créer un SVG, nous devons être aussi verbeux:
Document.CreateElementns ('http://www.w3.org/2000/svg', 'svg') en tant que svgsvgementment;
Nous pouvons s?rement créer une autre fonction d'assistance:
const CreateSVGNElement = (élément: String): svgement => { return document.createElementns ('http://www.w3.org/2000/svg', élément); };
Lorsque nous ajoutons les rectangles au DOM, nous devons prêter attention à leur commande. Sinon, nous devions spécifier explicitement l'indice Z. Le premier rectangle doit être le plus grand, et le dernier rectangle doit être le plus petit. Mieux vaut trier les données avant la boucle.
const data = rawdataset.sort ( (A: DataSeTentry, B: DataSeTentry) => B.Value - A.Value )); data.ForEach ((d: dataSetEntry, index: numéro) => { const REct: svGrecedElement = créeSvGnSelement (?rect?) comme svGrecedElement; const REctDimension: Number = remapDataSetValuetoSvgdimension (d.Value); rect.setAttribute ('width', `$ {rectdimension}`); rect.setAttribute ('height', `$ {rectdimension}`); rect.setAttribute ('y', `$ {svgdimension - rectdimension}`); SVG.APPEndChild (RECT); });
Le système de coordonnées commence par le haut à gauche; C'est là que le [0, 0] est. Nous allons toujours dessiner les rectangles du c?té gauche. L'attribut x, qui contr?le la position horizontale, est par défaut à 0, nous n'avons donc pas à le définir. L'attribut Y contr?le la position verticale.
Pour donner l'impression visuelle que tous les rectangles proviennent du même point qui touche leurs coins inférieurs à gauche, nous devons pousser les rectangles vers le bas pour parler. Par combien? Le montant exact que le rectangle ne remplit pas. Et cette valeur est la différence entre la dimension du graphique et le rectangle particulier. Si nous assemblons tous les bits, nous nous retrouvons avec ceci:
Nous avons déjà ajouté le code de l'animation à cette démo à l'aide de CSS.
Découper des rectangles
Nous devons transformer nos rectangles en formes irrégulières qui ressemblent au numéro sept, ou la lettre L tourna de 180 degrés.
Si nous nous concentrons sur les ?parties manquantes?, nous pouvons voir qu'ils découpent les mêmes rectangles avec lesquels nous travaillons déjà.
Nous voulons cacher ces découpes. C'est ainsi que nous allons finir avec les formes L que nous voulons.
Masquage 101
Un masque est quelque chose que vous définissez et appliquez plus tard à un élément. En règle générale, le masque est incliné dans l'élément
<svg> <masque> mask> </masque></svg>
Dans la balise
<svg> <masque> mask> <rect mask="url (#MycleVerlyNamedMask)"> </rect></masque></svg>
Ce n'est pas le seul moyen de définir ou d'appliquer un masque, mais c'est le moyen le plus simple pour cette démo. Faisons un peu d'expérimentation avant d'écrire un code pour générer les masques.
Nous avons dit que nous voulons couvrir les zones de découpe qui correspondent aux tailles des rectangles existants. Si nous prenons le plus grand élément et que nous appliquons le rectangle précédent comme masque, nous nous retrouvons avec ce code:
<svg viewbox="0 0 320 320" width="320" height="320"> <masque> <rect width="264" height="264" y="56" fill=""> mask> <rect width="320" height="320" y="0" fill="# 264653" mask="url (#themask)"> </rect></rect></masque></svg>
L'élément à l'intérieur du masque a besoin d'une valeur de remplissage. Qu'est-ce que cela devrait être? Nous verrons des résultats entièrement différents en fonction de la valeur de remplissage (couleur) que nous choisissons.
Le remplissage blanc
Si nous utilisons une valeur blanche pour le remplissage, nous obtenons ceci:
Maintenant, notre grand rectangle est la même dimension que le rectangle de masquage. Pas exactement ce que nous voulions.
Le remplissage noir
Si nous utilisons à la place une valeur noire, cela ressemble à ceci:
Nous ne voyons rien. C'est parce que ce qui est rempli de noir est ce qui devient invisible. Nous contr?lons la visibilité des masques à l'aide de remplissages blancs et noirs. Les lignes en pointillés sont là comme une aide visuelle pour référencer les dimensions de la zone invisible.
Le remplissage gris
Maintenant, utilisons quelque chose entre le blanc et le noir, disons gris:
Ce n'est ni entièrement opaque ni solide; c'est transparent. Donc, maintenant, nous savons que nous pouvons contr?ler le ?degré de visibilité? ici en utilisant quelque chose de différent des valeurs blanches et noires, ce qui est une bonne astuce à garder dans nos poches arrière.
Le dernier bit
Voici ce que nous avons couvert et appris sur les masques jusqu'à présent:
- L'élément à l'intérieur du
contr?le la dimension de la zone masquée. - Nous pouvons rendre le contenu de la zone masquée visible, invisible ou transparent.
Nous n'avons utilisé qu'une seule forme pour le masque, mais comme pour n'importe quelle balise HTML à usage général, nous pouvons nicher autant d'éléments enfants que nous le souhaitons. En fait, l'astuce pour réaliser ce que nous voulons consulter deux éléments SVG
<svg viewbox="0 0 320 320" width="320" height="320"> <masque> <rect width="320" height="320" y="0" fill="???"> <rect width="264" height="264" y="56" fill="???"> mask> <rect width="320" height="320" y="0" fill="# 264653" mask="url (# maskw320)"> </rect></rect></rect></masque></svg>
L'un de nos rectangles de masquage est rempli de blanc; l'autre est rempli de noir. Même si nous connaissons les règles, essayons les possibilités.
<masque> <rect width="320" height="320" y="0" fill="noir"> <rect width="264" height="264" y="56" fill="white"> mask></rect></rect></masque>
Le
Maintenant, faisons tourner les choses où le rectangle noir est au-dessus:
<masque> <rect width="320" height="320" y="0" fill="white"> <rect width="264" height="264" y="56" fill="noir"> mask></rect></rect></masque>
C'est ce que nous voulons!
Tout dans le plus grand rectangle rempli de blanc est visible, mais le plus petit rectangle noir est au-dessus (plus près de nous sur l'axe Z), masquant cette partie.
Générer les masques
Maintenant que nous savons ce que nous devons faire, nous pouvons créer les masques avec une relative facilité. C'est similaire à la fa?on dont nous avons généré les rectangles colorés en premier lieu - nous créons une boucle secondaire où nous créons le masque et les deux rectes.
Cette fois, au lieu d'ajouter les rectes directement au SVG, nous l'ajoutons au masque:
data.ForEach ((d: dataSetEntry, index: numéro) => { const Mask: svgmaskElement = CreateSvGnSelement ('mask') comme svgmaskElement; const REctDimension: Number = remapDataSetValuetoSvgdimension (d.Value); const REct: svGrecedElement = créeSvGnSelement (?rect?) comme svGrecedElement; rect.setAttribute ('width', `$ {rectdimension}`); // ... définir le reste des attributs ... mask.setAttribute ('id', `maskw $ {rectdimension.tofixed ()}`); masque.ApendChild (RECT); // ... Création et définition des attributs pour le plus petit rectangle ... SVG.APPEndChild (masque); }); data.ForEach ((d: dataSetEntry, index: numéro) => { // ... notre code pour générer les rectangles colorés ... });
Nous pourrions utiliser l'index comme identifiant du masque, mais cela semble une option plus lisible, du moins pour moi:
mask.setAttribute ('id', `maskw $ {rectdimension.tofixed ()}`); // maskw320, masw240, ...
En ce qui concerne l'ajout du rectangle plus petit dans le masque, nous avons facilement accès à la valeur dont nous avons besoin car nous avons précédemment commandé les valeurs rectangulaires du plus haut au plus bas. Cela signifie que l'élément suivant de la boucle est le rectangle plus petit, celui que nous devons référencer. Et nous pouvons le faire par son index.
// ... partie précédente où nous avons créé le masque et le rectangle ... const smallErrectIndex = index 1; // il n'y a pas de prochain quand nous sommes sur le plus petit if (data [smallErrectIndex]! == Undefined) { const SmallErrectDimension: nombre = remapdatasetvaluetosvgdimension ( données [smallErrectIndex] .Value )); const smallErrect: svGrecedElement = CreateSVGNELlement ( 'rect' ) comme svGreceLelement; // ... définir les attributs du rectangle ... masque.APPEndChild (Small Earrect); } SVG.APPEndChild (masque);
Ce qui reste, c'est d'ajouter l'attribut de masque au rectangle coloré dans notre boucle d'origine. Il devrait correspondre au format que nous avons choisi:
rect.setAttribute ('mask', `url (# maskw $ {rectdimension.tofixed ()})`); // maskw320, maskw240, ...
Le résultat final
Et nous avons fini! Nous avons réussi à faire un graphique fabriqué à partir de carrés imbriqués. Il se sépare même de survoler de la souris. Et tout ce qu'il a fallu, c'était un SVG en utilisant l'élément
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!

Outils d'IA chauds

Undress AI Tool
Images de déshabillage gratuites

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
échangez les visages dans n'importe quelle vidéo sans effort grace à notre outil d'échange de visage AI entièrement gratuit?!

Article chaud

Outils chauds

Bloc-notes++7.3.1
éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

CSS bloque le rendu de la page car les navigateurs affichent le CSS en ligne et le CSS externe comme des ressources clés par défaut, en particulier avec les feuilles de styles importées, les grandes quantités de CSS en ligne et les styles de requête multimédia non optimisés. 1. Extraire CSS critique et l'intégrez-la dans HTML; 2. Retard Chargement CSS non critique via JavaScript; 3. Utilisez des attributs multimédias pour optimiser le chargement tel que les styles d'impression; 4. Comprimer et fusionner CSS pour réduire les demandes. Il est recommandé d'utiliser des outils pour extraire les CS de clé, combiner le chargement asynchrone rel = "précharge" et utiliser le chargement retardé des médias raisonnablement pour éviter une division excessive et un contr?le de script complexe.

TheBestApproachForCSSDependSonTheproject'sspecificneeds.ForLargerProjects, externalcsisBetterDueTomaintainiabilityAndReUsability; ForsmallerProjectsorSingle-pageApplications, internecssigh

NON, CSSDOOSNOTHAVETOBEINLOWLOWERCASE.CI, USING USINGERCASERASERISROMEND pour: 1) Cohérence et réadaptation, 2) évitant les technologies de perception liées à la pertinence, 3) Potentiel PerformanceBenefits, and4) Amélioration de la collaboration.

CSSismostlyCase-insensible, buturlsandfontfamilyNamesaSaSase-sensible.1) Propriéties andvaluesLikEcolor: Red; arenotcase-sensible.2) UrlSMustMatchTheServer'scase, par exemple, / images / Logo.png.3) FontFamilyNamesliNe'apensans's'mUstBeexact.

AutoPrefixer est un outil qui ajoute automatiquement les préfixes des fournisseurs aux attributs CSS en fonction de la portée du navigateur cible. 1. Il résout le problème de maintenir manuellement les préfixes avec des erreurs; 2. Travaillez le formulaire de plug-in PostCSS, analyse CSS, analysez les attributs qui doivent être préfixés et générer du code en fonction de la configuration; 3. Les étapes d'utilisation incluent l'installation de plug-ins, la définition de la liste de navigateurs et leur permettant dans le processus de construction; 4. Les notes ne comprennent pas manuellement les préfixes, le maintien des mises à jour de la configuration, les préfixes pas tous des attributs, et il est recommandé de les utiliser avec le préprocesseur.

CSSCOUNTERSCANAUTOMAMATIQUE UNEUXESECTIONS ET LISTS.1) USECOUNTER-RESEDTOINITINALIALIALISE, COMPTENDREMENTTOINCREAD, andCounter () Orcounters () toDisplayValues.2) combinewithjavascriptfordynamiccontentoenSureAcurateupdates.

Dans CSS, les noms de sélecteur et d'attribut sont sensibles à la casse, tandis que les valeurs, les couleurs nommées, les URL et les attributs personnalisés sont sensibles à la casse. 1. Les noms de sélecteur et d'attribut sont insensibles à la casse, tels que la couleur arrière et la couleur arrière-plan sont les mêmes. 2. La couleur hexadécimale de la valeur est sensible à la casse, mais la couleur nommée est sensible à la casse, comme le rouge et le rouge n'est pas valide. 3. Les URL sont sensibles à la casse et peuvent causer des problèmes de chargement de fichiers. 4. Les propriétés personnalisées (variables) sont sensibles à la caisse, et vous devez faire attention à la cohérence du cas lorsque vous les utilisez.

THECONCON-GRADIENT () FURMATINGEnSSSCREATSCICLULARD GRODIENTSTHATATATECOLORSTOPSAROUNDacentralpoint.1.IiSIDEALFORPIECHARTS, PROGRESSINDICATEURS, Colorweels, andDecorativeBackgrounds.2.itworksByDefiningColOrStopSatSpiecificangles, FactuallylyTartingfromadefinin
