In the recent project, I need to make a new demand: realize custom path animation in Canvas. The so -called custom path here not only includes a straight line, maybe multiple straight -line motion combinations, and even include the Bessel curve. Therefore, this animation may be like the following:
So how can we achieve this animation effect in Canvas? In fact, it is very simple. The SVG is very good for the processing of the path, so we need to use the power of SVG in Canvas to achieve custom path animation in Canvas.
Create PATHBefore making animation, we must get the path of the animation first. In this regard, we can directly use the PATH definition rules of the SVG. ), And then, we need to import the defined path into a newly generated Path element (we just use the SVG API, so it does not need to insert it to the page)
Const Path = 'M0,33.90861 25.90861,16 48,16 C70.09139,16 88,33.90861 88,56 C88,78.09139 105.90861 128,92 C150.09139 160,72 160,56 C1 60,40 148,24 128,24 C108,24 96,40 96,56 C96,72 105.90861,92 128,92 C154,93 168,78 168,56 C168,33.90861 185.90861,16 208,16 C230.09139,16 248,33.90861 248,56 C248,78.09139 230.09139,96 208,96 L48,96 C25.90861,96 8,78.09139 8,56 Z '; CONST PATHELEMENT = DOCUMENT.CREATEELEMENTNS (' http://www.w3.or g/2000/svg ', Path); Pathelement.Setattributens (NULL,' D ', PATH); gettotallength and getpointtlengthThe two APIs provided by SVGPathelement are critical. It can be said that it is the core place to realize path animation (realizing custom path animation in SVG is generally solved through these two APIs) For details, please poke: SVGPathelement MDN MDN
Gettotallength method can get the total length of SVGPathelement
The getpointtlength method is passed into a length X, which will return the end coordinates of the length of the starting point of the SVGPathelement.
Use these two APIs to continuously update the graphics coordinates drawn in Canvas through a cycle, and the path animation can be achieved:
const length = pathelement.gettotallength (); const duration = 1000; // The total length of the animation const interval = length / duration; continuous ; const context = canvas.getContext ('2d'); Let Time = 0, STEP = 0; Const Timer = SetInterval (Function () {if (time <= duration) {const x = PATHELEMENT (Pathelement.getpointtlength (STEP) .x); const y = p ARSEINT (Pathelement.getpointtlength ( step).y); move(x, y); // 更新canvas所绘制图形的坐标step++; } else { clearInterval(timer) }}, interval);function move(x, y) { context.clearRect(0 , 0, canvas.width, canvas.head); context.beginpath (); context.arc (x, y, 25, 0, math.pi*2, true); context.fillStyle = '#f0f'; context. file (); context.closepath ();}Finally, we encapsulate it to realize a simple function that realizes custom animation in Canvas:
FUNCTION CUSTMEPATH (PATH, FUNC) {const forms = document.createElementns ('http://www.w3.org/2000/svg', Path); 'd', path); const length = Pathelement.gettotalLength (); const duration = 1000; const interval = length / duration; let time = 0, step = 0; const timer = SetInterval () () {if () {if e <= Duration) {const x = PATHEINT (Pathelement .getpointtlength (step) .x); const y = PARSEINT (Pathelement.getpointtlength (Step) .y); func (x, y); Step ++;} Else {clearinterval (timer)}}, In Terval);} const Path = 'M0, 0 C8,33.9961 25.90861,16 48,16 C70.09139,16 88,33.90861 88,56 C88,78.09139 105.90862 128,92 C150.09139,72 160,56 C160,40 148 24 128,24 C108,24 96,40 96,56 C96,72 105.90861,92 128,92 C154,93 168,78 168,56 C168,33.90861 185.90861,16 208,16 C230.09139,16 248,33.90861 248,56 C248,78.09139 230.09139,96 208,96 L48,96 C25.90861,96 8,78.09139 8,56 Z '; Const canvas = documeeryselector (' canvas'); Const Context = Canva s.getContext ('2D'); Function Move (x, y) {context.clearrect (0, 0, canvas.width, canvas.Height); context.beginpath (); context.arc (x, y, 25, math.pi*2, true ).;Implementing ideas is roughly as described above, but this is not the ultimate result. When we decide to make custom path animation in Canvas, we must not only consider how to achieve it, but also consider performance optimization. For example, can we reduce unnecessary rendering times in this implementation thinking? How to control the frame rate to the optimal? etc.
Although they are not in the scope of the discussion of this article, they should be worth thinking about.
The above is all the contents of this article. I hope it will be helpful to everyone's learning. I also hope that everyone will support VEVB Wulin.com.