简体   繁体   中英

How to animate shape or image file along SVG paths with the Vivus js?

I am using vivusjs library to animate SVG, i want to animate an image file or a shape along animated SVG. somthing like as below:

在此处输入图像描述

White line is an animating SVG path and green pen is my image file. i need it in Vivusjs library.

No need for a library, you can do all with native JavaScript

Create your own Web Component <draw-path> (supported in all modern browsers)

Do all animations with JavaScript. Key is to set the pathLength to 1 and use getPointAtLength to position the SVG pen at the correct location.

Then all HTML required to display (see SO snippet below):

is:

<draw-path d='M25 50a25 25 0 1 1 80 0a25 25 0 1 1-80 0'></draw-path>
<draw-path d='M25 25h50v50h-50v-50z' stroke='green' stroke-width='5' speed="0.007"></draw-path>
<draw-path stroke='red' stroke-width='5' speed=".01"></draw-path>

 window.customElements.define("draw-path", class extends HTMLElement { constructor() { let template = (id) => document.getElementById(id).content.cloneNode(true); super() // super sets and returns this scope.attachShadow({mode: "open"}) // sets and returns this.shadowRoot.append(template(this.nodeName)); this.line = this.shadowRoot.querySelector("#line"); this.line.setAttribute("d", this.getAttribute("d") || "m10 60c30-70 55-70 75 0s55 70 85 0"); this.line.setAttribute("stroke", this.getAttribute("stroke") || "black"); this.line.setAttribute("stroke-width", this.getAttribute("stroke-width") || "2"); this.pen = this.shadowRoot.querySelector("#pen"); this.onmouseover = (evt) => this.draw(); } connectedCallback() { this.draw(); } showpen(state = true, scale) { this.pen.style.display = state? 'initial': 'none'; } draw() { clearInterval(this.drawing); this.showpen(); this.dashoffset = 1; this.pathlength = this.line.getTotalLength(); this.drawing = setInterval(() => this.update(), 50); } update() { this.dashoffset -= this.getAttribute("speed") || 0.02; let {x,y} = this.line.getPointAtLength(this.pathlength - this.dashoffset * this.pathlength); this.pen.setAttribute("transform", `translate(${x-2} ${y-2})`); this.line.style.strokeDashoffset = this.dashoffset; if (this.dashoffset <= 0) this.end(); } end() { clearInterval(this.drawing); this.showpen(false); //console.log("end",this.line); clearTimeout(this.timeout); this.timeout = setTimeout(()=>this.draw(),2000); } });
 <draw-path d='M25 50a25 25 0 1 1 80 0a25 25 0 1 1-80 0'></draw-path> <draw-path d='M25 25h50v50h-50v-50z' stroke='green' stroke-width='5' speed="0.007"></draw-path> <draw-path stroke='red' stroke-width='8' speed=".01"></draw-path> <template id="DRAW-PATH"> <style>:host { display: inline-block } svg { width: 180px; height: 130px; background: beige } </style> <svg xmlns="http://www.w3.org/2000/svg"> <path id='line' pathlength='1' stroke-dasharray='1' stroke-dashoffse='1' fill='transparent'/> <path id='pen' stroke='black' stroke-width='2' fill='gold' d='m12 19l7-7l3 3l-7 7l-3-3zm6-6l-2-8l-14-3l4 15l7 1l5-5zm-16-11l8 8m-1 1a2 2 0 104 0a2 2 0 10-4 0'/> </svg> </template>

Note:

Be aware M or m (moves) in paths create a new stroke , drawn at the same time, not sequentially.

So stroke-dash* settings are applied concurrent.

That is why in all blogs you only see single stroke simple paths or polylines used.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM