Utilisation de chemins SVG dans le canevas pour déplacer des objets

Si pour animer un objet dans le canevas (et pas seulement), vous devez le déplacer le long du chemin souhaité, peut-être même plusieurs qui peuvent être sélectionnés de manière aléatoire ou séquentielle, alors cela peut être fait en utilisant des chemins svg. Commençons par commencer par un carré simple mais vert le long du chemin.

image


Pour ce faire, nous allons créer ou emprunter des svg, avec un ou plusieurs chemins.

Créez un élément à l'aide de la fonction document.createElementNS . MDN nous indique que la méthode a un support de base dans tous les navigateurs modernes. Ajoutez ensuite le chemin d'accès à l'élément créé.

let path = document.createElementNS("http://www.w3.org/2000/svg", "path"); path.setAttribute('d', 'M148.185,118.975c0,0-92.592,39.507-80.247,79.013,s79.012,143.21,129.629,124.691s64.198-113.856,120.988-100.755s118.518,30.384,116.049,109.397s-82.715,118.519-97.53,201.235,s-92.593,139.505,0,159.259'); 

Ici, dans les attributs, le premier chemin accrocheur à partir d'un fichier svg est introduit, la méthode copier-coller. Bien sûr, ce n'est pas le seul et, de plus, pas le moyen le plus pratique, mais suffisamment clair pour être utilisé dans le premier exemple.

Maintenant dans la boucle, nous allons obtenir les coordonnées des points de cheminement et les affecter à notre objet. Deux méthodes SVGGeometryElement suffisent pour cela :

 path.getTotalLength() 

renvoie la valeur calculée de la longueur totale du chemin et

  path.getPointAtLength(index) 

Il prend un argument flottant et retourne un objet SVGPoint qui a les coordonnées x et y qui nous intéressent. Si les valeurs d'argument sont inférieures à zéro ou supérieures à la longueur du chemin, le premier ou le dernier point, respectivement, sera renvoyé comme résultat.

Lors de la mise à jour du cadre, nous obtenons le point et utilisons ses coordonnées pour le mouvement.

→ Exemple de code complet sur codepen

Mais, vous pouvez utiliser une option plus intéressante pour déplacer l'objet le long des coordonnées de plusieurs chemins, par exemple ceci:

image


Encore une fois, prenez un fichier svg avec plusieurs chemins. Celui qui a été utilisé dans l'exemple est réalisé dans l'éditeur Inscape. Maintenant, vous devez obtenir ces chemins, cela est possible en analysant l'objet ou, si svg a été reçu sous forme de fichier texte, puis la fonction suivante, en utilisant des expressions régulières, vous pouvez les obtenir sous forme de chaînes.

 extractPathsfromSvg: function(svg){ let results = svg.match(/<path\b([\s\S]*?)><\/path>/g); let paths = []; let len = results.length; for(let i = 0; i < len; i++){ let str = results[i]; let data = str.match(/[^\w]d="([\s\S]*?)"/); paths.push(data[1]); } return paths; } 

Après avoir créé un tableau de chemins, il reste à les extraire tour à tour et à les traiter de la même manière que le seul chemin pour le déplacement du carré. obtenir des effets intéressants.
Voir le code complet pour l'exemple ci-dessous.

Pour ajouter plus de contrôle lors du déplacement d'un objet le long des coordonnées du chemin, vous pouvez utiliser des jumeaux. Pour les cas de test, j'ai pris la première bibliothèque GreenSock qui a attiré mon attention, mais elle aurait pu en être une autre.

Dans le premier cas, lorsque le carré se déplace le long d'un seul chemin, créez un assistant d'objet intermédiaire et transmettez-le pour créer l'interpolation.

 var helper = {progress: 0} helper.update = function(value){ point = path.getPointAtLength(totalLength * helper.progress); x = point.x; y = point.y; ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(img, x, y ); } var tw = new TweenLite.to(helper, 5, {progress: 0, }); tw.eventCallback("onUpdate", helper.update); 

Vous pouvez voir le mouvement du carré le long du chemin en utilisant l'interpolation, dans le premier exemple sur codepen, en cochant utiliser l'interpolation.

Lorsque nous nous déplaçons sur plusieurs chemins, nous procédons comme suit. Comme précédemment, créez un objet d'assistance avec la propriété progress. Nous calculons la longueur totale de tous les chemins d'accès et l'assignons à handler.progress. Créons une variable traversée dans laquelle les chemins déjà couverts seront résumés.

Pour obtenir un point sur le chemin actuel, soustrayez de helper.progress, qui change dans l'interpolation, le chemin déjà parcouru est parcouru. Nous utilisons les coordonnées du point comme d'habitude.

 var traversed = 0; helper.progress = totalLenghtAllPath; helper.update = function() { var localPoint = helper.progress - traversed; if(localPoint > curPath.getTotalLength()){ traversed += curPath.getTotalLength(); curPath = paths[next()]; if(curPath){ return false; } localPoint = helper.progress - traversed; } /*       */ } var tw = TweenLite.to( helper, 25, {progress: totalLenghtAllPath, ease: Power2.easeOut } ); tw.eventCallback("onUpdate", helper.update); 

Le code est simplifié, le code complet est ici:

Source: https://habr.com/ru/post/fr432114/


All Articles