खोज…
2 डी संदर्भ और अनुरोध के साथ सरल एनीमेशन
यह उदाहरण आपको दिखाएगा कि कैनवास और 2 डी संदर्भ का उपयोग करके एक सरल एनीमेशन कैसे बनाया जाए। यह माना जाता है कि आप जानते हैं कि DOM को कैनवस बनाने और जोड़ने के लिए और संदर्भ कैसे प्राप्त करें
// this example assumes ctx and canvas have been created
const textToDisplay = "This is an example that uses the canvas to animate some text.";
const textStyle = "white";
const BGStyle = "black"; // background style
const textSpeed = 0.2; // in pixels per millisecond
const textHorMargin = 8; // have the text a little outside the canvas
ctx.font = Math.floor(canvas.height * 0.8) + "px arial"; // size the font to 80% of canvas height
var textWidth = ctx.measureText(textToDisplay).width; // get the text width
var totalTextSize = (canvas.width + textHorMargin * 2 + textWidth);
ctx.textBaseline = "middle"; // not put the text in the vertical center
ctx.textAlign = "left"; // align to the left
var textX = canvas.width + 8; // start with the text off screen to the right
var textOffset = 0; // how far the text has moved
var startTime;
// this function is call once a frame which is approx 16.66 ms (60fps)
function update(time){ // time is passed by requestAnimationFrame
if(startTime === undefined){ // get a reference for the start time if this is the first frame
startTime = time;
}
ctx.fillStyle = BGStyle;
ctx.fillRect(0, 0, canvas.width, canvas.height); // clear the canvas by drawing over it
textOffset = ((time - startTime) * textSpeed) % (totalTextSize); // move the text left
ctx.fillStyle = textStyle; // set the text style
ctx.fillText(textToDisplay, textX - textOffset, canvas.height / 2); // render the text
requestAnimationFrame(update);// all done request the next frame
}
requestAnimationFrame(update);// to start request the first frame
Jsfiddle पर इस उदाहरण का एक डेमो
एक निर्दिष्ट अंतराल पर चेतन करें (हर 1 सेकंड में एक नई आयत जोड़ें)
यह उदाहरण कैनवास पर हर 1 सेकंड (== 1 सेकंड का अंतराल) में एक नई आयत जोड़ता है
एनोटेट कोड:
<!doctype html>
<html>
<head>
<style>
body{ background-color:white; }
#canvas{border:1px solid red; }
</style>
<script>
window.onload=(function(){
// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
// animation interval variables
var nextTime=0; // the next animation begins at "nextTime"
var duration=1000; // run animation every 1000ms
var x=20; // the X where the next rect is drawn
// start the animation
requestAnimationFrame(animate);
function animate(currentTime){
// wait for nextTime to occur
if(currentTime<nextTime){
// request another loop of animation
requestAnimationFrame(animate);
// time hasn't elapsed so just return
return;
}
// set nextTime
nextTime=currentTime+duration;
// add another rectangle every 1000ms
ctx.fillStyle='#'+Math.floor(Math.random()*16777215).toString(16);
ctx.fillRect(x,30,30,30);
// update X position for next rectangle
x+=30;
// request another loop of animation
requestAnimationFrame(animate);
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=512 height=512></canvas>
</body>
</html>
निर्दिष्ट समय पर चेतन (एक एनिमेटेड घड़ी)
यह उदाहरण सेकंड को भरे हुए पच्चर के रूप में दिखाने वाली घड़ी को एनिमेट करता है
एनोटेट कोड:
<!doctype html>
<html>
<head>
<style>
body{ background-color:white; }
#canvas{border:1px solid red; }
</style>
<script>
window.onload=(function(){
// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
// canvas styling for the clock
ctx.strokeStyle='lightgray';
ctx.fillStyle='skyblue';
ctx.lineWidth=5;
// cache often used values
var PI=Math.PI;
var fullCircle=PI*2;
var sa=-PI/2; // == the 12 o'clock angle in context.arc
// start the animation
requestAnimationFrame(animate);
function animate(currentTime){
// get the current seconds value from the system clock
var date=new Date();
var seconds=date.getSeconds();
// clear the canvas
ctx.clearRect(0,0,cw,ch);
// draw a full circle (== the clock face);
ctx.beginPath();
ctx.moveTo(100,100);
ctx.arc(100,100,75,0,fullCircle);
ctx.stroke();
// draw a wedge representing the current seconds value
ctx.beginPath();
ctx.moveTo(100,100);
ctx.arc(100,100,75,sa,sa+fullCircle*seconds/60);
ctx.fill();
// request another loop of animation
requestAnimationFrame(animate);
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=512 height=512></canvas>
</body>
</html>
ऐनिमेशन लूप के लिए requestAnimationFrame () सेट नहीं करेंइंटरवाल () का उपयोग करें
requestAnimationFrame
के समान है, लेकिन इसमें ये महत्वपूर्ण सुधार हैं:
एनीमेशन कोड दक्षता के लिए प्रदर्शन रिफ्रेश के साथ सिंक्रनाइज़ किया गया है। स्पष्ट + रीड्रा कोड निर्धारित है, लेकिन तुरंत निष्पादित नहीं किया गया है। ब्राउज़र स्पष्ट + redraw कोड को केवल तभी निष्पादित करेगा जब प्रदर्शन ताज़ा करने के लिए तैयार हो। रिफ्रेश चक्र के साथ यह सिंक्रनाइज़ेशन आपके कोड को पूरा करने के लिए सबसे उपलब्ध समय देकर आपके एनीमेशन प्रदर्शन को बढ़ाता है।
प्रत्येक लूप हमेशा एक और लूप शुरू करने की अनुमति देने से पहले पूरा हो जाता है। यह "फाड़" को रोकता है, जहां उपयोगकर्ता ड्राइंग का अधूरा संस्करण देखता है। आंखें विशेष रूप से आंसू को नोटिस करती हैं और फाड़ होने पर विचलित हो जाती हैं। इसलिए आंसू रोकने से आपका एनीमेशन चिकना और अधिक सुसंगत दिखाई देता है।
- जब उपयोगकर्ता एक अलग ब्राउज़र टैब पर स्विच करता है, तो एनीमेशन स्वचालित रूप से बंद हो जाता है। यह मोबाइल उपकरणों पर बिजली की बचत करता है क्योंकि डिवाइस एक एनीमेशन को पावर कंप्यूटिंग बर्बाद नहीं कर रहा है जिसे उपयोगकर्ता वर्तमान में नहीं देख सकता है।
डिवाइस डिस्प्ले प्रति सेकंड लगभग 60 बार रिफ्रेश करेगा इसलिए रिक्वेस्टएनीमेशनफ्रेम लगातार 60 "फ्रेम" प्रति सेकंड पर रीड्रा कर सकता है। आंख 20-30 फ्रेम प्रति सेकंड पर गति देखती है इसलिए अनुरोध करता है। नामकरण आसानी से गति का भ्रम पैदा कर सकता है।
ध्यान दें कि requestAnimationFrame को प्रत्येक चेतन के अंत में वापस बुलाया जाता है। ऐसा इसलिए है क्योंकि प्रत्येक 'requestAnimatonFrameonly एनीमेशन फ़ंक्शन के एकल निष्पादन का अनुरोध करता है।
उदाहरण: simple `requestAnimationFrame
<!doctype html>
<html>
<head>
<style>
body{ background-color:white; }
#canvas{border:1px solid red; }
</style>
<script>
window.onload=(function(){
// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
// start the animation
requestAnimationFrame(animate);
function animate(currentTime){
// draw a full randomly circle
var x=Math.random()*canvas.width;
var y=Math.random()*canvas.height;
var radius=10+Math.random()*15;
ctx.beginPath();
ctx.arc(x,y,radius,0,Math.PI*2);
ctx.fillStyle='#'+Math.floor(Math.random()*16777215).toString(16);
ctx.fill();
// request another loop of animation
requestAnimationFrame(animate);
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=512 height=512></canvas>
</body>
</html>
RequestAnimationFrame के फायदों को समझाने के लिए इस स्टैकओवरफ्लो प्रश्न का लाइव डेमो है
कैनवस पर एक छवि चेतन करें
यह उदाहरण कैनवस के पार लोड और एनिमेशन और छवि बनाता है
महत्वपूर्ण संकेत! सुनिश्चित करें कि आप image.onload
का उपयोग करके अपनी छवि को पूरी तरह से लोड करने का समय image.onload
।
एनोटेट कोड
<!doctype html>
<html>
<head>
<style>
body{ background-color:white; }
#canvas{border:1px solid red; }
</style>
<script>
window.onload=(function(){
// canvas related variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
// animation related variables
var minX=20; // Keep the image animating
var maxX=250; // between minX & maxX
var x=minX; // The current X-coordinate
var speedX=1; // The image will move at 1px per loop
var direction=1; // The image direction: 1==righward, -1==leftward
var y=20; // The Y-coordinate
// Load a new image
// IMPORTANT!!! You must give the image time to load by using img.onload!
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/sun.png";
function start(){
// the image is fully loaded sostart animating
requestAnimationFrame(animate);
}
function animate(time){
// clear the canvas
ctx.clearRect(0,0,cw,ch);
// draw
ctx.drawImage(img,x,y);
// update
x += speedX * direction;
// keep "x" inside min & max
if(x<minX){ x=minX; direction*=-1; }
if(x>maxX){ x=maxX; direction*=-1; }
// request another loop of animation
requestAnimationFrame(animate);
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=512 height=512></canvas>
</body>
</html>
अपने ईवेंट हैंडलर में एनिमेशन न बनाएं (एक साधारण स्केच ऐप)
mousemove
दौरान आप प्रति सेकंड 30 माउस घटनाओं से भर जाते हैं। हो सकता है कि आप अपने ड्रॉइंग को 30 गुना प्रति सेकंड के हिसाब से दोबारा न पा सकें। यहां तक कि अगर आप कर सकते हैं, तो आप संभवतः कंप्यूटिंग शक्ति को आकर्षित कर रहे हैं, जब ब्राउज़र ड्रॉ करने के लिए तैयार नहीं है (प्रदर्शन ताज़ा चक्रों में व्यर्थ ==)।
इसलिए यह आपके उपयोगकर्ता इनपुट घटनाओं (जैसे मूसमव) को आपके एनिमेशन के ड्राइंग से अलग करने के लिए समझ में आता है।
ईवेंट हैंडलर में, उन सभी ईवेंट वैरिएबल्स को सेव करें जो कंट्रोल करते हैं जहां चित्र कैनवस पर तैनात हैं। लेकिन वास्तव में कुछ भी आकर्षित नहीं करते हैं।
एक
requestAnimationFrame
लूप में, सहेजे गए जानकारी का उपयोग करके सभी आरेखण को कैनवस पर रेंडर करें।
ईवेंट हैंडलर में नहीं खींचकर, आप कैनवस को माउस इवेंट की गति पर जटिल चित्र को ताज़ा करने के लिए मजबूर नहीं कर रहे हैं।
requestAnimationFrame
में सभी ड्रॉइंग करने से आप यहां वर्णित सभी लाभों को प्राप्त करते हैं , एनीमेशन लूप के लिए 'requestanimationFrame' का उपयोग करें 'setInterval' नहीं ।
एनोटेट कोड:
<!doctype html>
<html>
<head>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red; }
</style>
<script>
window.onload=(function(){
function log(){console.log.apply(console,arguments);}
// canvas variables
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
// set canvas styling
ctx.strokeStyle='skyblue';
ctx.lineJoint='round';
ctx.lineCap='round';
ctx.lineWidth=6;
// handle windows scrolling & resizing
function reOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }
// vars to save points created during mousemove handling
var points=[];
var lastLength=0;
// start the animation loop
requestAnimationFrame(draw);
canvas.onmousemove=function(e){handleMouseMove(e);}
function handleMouseMove(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// get the mouse position
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// save the mouse position in the points[] array
// but don't draw anything
points.push({x:mouseX,y:mouseY});
}
function draw(){
// No additional points? Request another frame an return
var length=points.length;
if(length==lastLength){requestAnimationFrame(draw);return;}
// draw the additional points
var point=points[lastLength];
ctx.beginPath();
ctx.moveTo(point.x,point.y)
for(var i=lastLength;i<length;i++){
point=points[i];
ctx.lineTo(point.x,point.y);
}
ctx.stroke();
// request another animation loop
requestAnimationFrame(draw);
}
}); // end window.onload
</script>
</head>
<body>
<h4>Move mouse over Canvas to sketch</h4>
<canvas id="canvas" width=512 height=512></canvas>
</body>
</html>
रॉबर्ट पेनर्स समीकरणों का उपयोग करना आसान है
एक सहजता एक अवधि में असमान रूप से बदलने के लिए कुछ चर का कारण बनती है।
"चर" को एक संख्या के रूप में व्यक्त करने में सक्षम होना चाहिए, और एक उल्लेखनीय विविधता का प्रतिनिधित्व कर सकता है:
- एक एक्स-समन्वय,
- एक आयत की चौड़ाई,
- रोटेशन का कोण,
- आर, जी, बी रंग का लाल घटक।
- कुछ भी जो एक संख्या के रूप में व्यक्त किया जा सकता है।
"अवधि" को एक संख्या के रूप में व्यक्त किया जा सकता है और यह विभिन्न प्रकार की भी हो सकती है:
- समयावधि,
- यात्रा की जाने वाली दूरी,
- एनीमेशन छोरों की एक मात्रा को निष्पादित किया जाना है,
- जो कुछ भी व्यक्त किया जा सकता है
"असमान" का अर्थ है कि चर शुरू से अंत तक मूल्यों को असमान रूप से आगे बढ़ता है:
- शुरुआत में तेज और अंत में धीमा - या वीज़ा-वर्सा,
- समाप्ति को ओवरशूट करता है, लेकिन अवधि पूरी होने तक समाप्त हो जाता है,
- अवधि के दौरान बार-बार अग्रिम / पीछे हटना,
- अवधि खत्म होते ही आराम करने के लिए "बाउंस" समाप्त हो जाता है।
विशेषता: रॉबर्ट पेनर ने सहजता के कार्यों का "स्वर्ण मानक" बनाया है।
उद्धृत: https://github.com/danro/jquery-easing/blob/master/jquery.easing.s
// t: elapsed time inside duration (currentTime-startTime),
// b: beginning value,
// c: total change from beginning value (endingValue-startingValue),
// d: total duration
var Easings={
easeInQuad: function (t, b, c, d) {
return c*(t/=d)*t + b;
},
easeOutQuad: function (t, b, c, d) {
return -c *(t/=d)*(t-2) + b;
},
easeInOutQuad: function (t, b, c, d) {
if ((t/=d/2) < 1) return c/2*t*t + b;
return -c/2 * ((--t)*(t-2) - 1) + b;
},
easeInCubic: function (t, b, c, d) {
return c*(t/=d)*t*t + b;
},
easeOutCubic: function (t, b, c, d) {
return c*((t=t/d-1)*t*t + 1) + b;
},
easeInOutCubic: function (t, b, c, d) {
if ((t/=d/2) < 1) return c/2*t*t*t + b;
return c/2*((t-=2)*t*t + 2) + b;
},
easeInQuart: function (t, b, c, d) {
return c*(t/=d)*t*t*t + b;
},
easeOutQuart: function (t, b, c, d) {
return -c * ((t=t/d-1)*t*t*t - 1) + b;
},
easeInOutQuart: function (t, b, c, d) {
if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
return -c/2 * ((t-=2)*t*t*t - 2) + b;
},
easeInQuint: function (t, b, c, d) {
return c*(t/=d)*t*t*t*t + b;
},
easeOutQuint: function (t, b, c, d) {
return c*((t=t/d-1)*t*t*t*t + 1) + b;
},
easeInOutQuint: function (t, b, c, d) {
if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
return c/2*((t-=2)*t*t*t*t + 2) + b;
},
easeInSine: function (t, b, c, d) {
return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
},
easeOutSine: function (t, b, c, d) {
return c * Math.sin(t/d * (Math.PI/2)) + b;
},
easeInOutSine: function (t, b, c, d) {
return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
},
easeInExpo: function (t, b, c, d) {
return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
},
easeOutExpo: function (t, b, c, d) {
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
},
easeInOutExpo: function (t, b, c, d) {
if (t==0) return b;
if (t==d) return b+c;
if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
},
easeInCirc: function (t, b, c, d) {
return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
},
easeOutCirc: function (t, b, c, d) {
return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
},
easeInOutCirc: function (t, b, c, d) {
if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
},
easeInElastic: function (t, b, c, d) {
var s=1.70158;var p=0;var a=c;
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
if (a < Math.abs(c)) { a=c; var s=p/4; }
else var s = p/(2*Math.PI) * Math.asin (c/a);
return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
},
easeOutElastic: function (t, b, c, d) {
var s=1.70158;var p=0;var a=c;
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
if (a < Math.abs(c)) { a=c; var s=p/4; }
else var s = p/(2*Math.PI) * Math.asin (c/a);
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
},
easeInOutElastic: function (t, b, c, d) {
var s=1.70158;var p=0;var a=c;
if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
if (a < Math.abs(c)) { a=c; var s=p/4; }
else var s = p/(2*Math.PI) * Math.asin (c/a);
if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
},
easeInBack: function (t, b, c, d, s) {
if (s == undefined) s = 1.70158;
return c*(t/=d)*t*((s+1)*t - s) + b;
},
easeOutBack: function (t, b, c, d, s) {
if (s == undefined) s = 1.70158;
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
},
easeInOutBack: function (t, b, c, d, s) {
if (s == undefined) s = 1.70158;
if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
},
easeInBounce: function (t, b, c, d) {
return c - Easings.easeOutBounce (d-t, 0, c, d) + b;
},
easeOutBounce: function (t, b, c, d) {
if ((t/=d) < (1/2.75)) {
return c*(7.5625*t*t) + b;
} else if (t < (2/2.75)) {
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
} else if (t < (2.5/2.75)) {
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
} else {
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
}
},
easeInOutBounce: function (t, b, c, d) {
if (t < d/2) return Easings.easeInBounce (t*2, 0, c, d) * .5 + b;
return Easings.easeOutBounce (t*2-d, 0, c, d) * .5 + c*.5 + b;
},
};
उदाहरण उपयोग:
// include the Easings object from above
var Easings = ...
// Demo
var startTime;
var beginningValue=50; // beginning x-coordinate
var endingValue=450; // ending x-coordinate
var totalChange=endingValue-beginningValue;
var totalDuration=3000; // ms
var keys=Object.keys(Easings);
ctx.textBaseline='middle';
requestAnimationFrame(animate);
function animate(time){
var PI2=Math.PI*2;
if(!startTime){startTime=time;}
var elapsedTime=Math.min(time-startTime,totalDuration);
ctx.clearRect(0,0,cw,ch);
ctx.beginPath();
for(var y=0;y<keys.length;y++){
var key=keys[y];
var easing=Easings[key];
var easedX=easing(
elapsedTime,beginningValue,totalChange,totalDuration);
if(easedX>endingValue){easedX=endingValue;}
ctx.moveTo(easedX,y*15);
ctx.arc(easedX,y*15+10,5,0,PI2);
ctx.fillText(key,460,y*15+10-1);
}
ctx.fill();
if(time<startTime+totalDuration){
requestAnimationFrame(animate);
}
}
अनुरोध का उपयोग करके फ्रेम दर निर्धारित करें
RequestAnimationFrame का उपयोग करना कुछ सिस्टम पर 60fps की तुलना में प्रति सेकंड अधिक फ्रेम में अपडेट हो सकता है। 60fps डिफॉल्ट रेट है अगर रेंडरिंग बरकरार रह सकता है। कुछ सिस्टम 120fps पर शायद अधिक चलेंगे।
यदि आप निम्नलिखित विधि का उपयोग करते हैं, तो आपको केवल फ्रेम दर का उपयोग करना चाहिए जो कि पूर्णांक विभाजन है 60 (60 / FRAMES_PER_SECOND) % 1 === 0
true
या आपको असंगत फ्रेम दर मिलेगी।
const FRAMES_PER_SECOND = 30; // Valid values are 60,30,20,15,10...
// set the mim time to render the next frame
const FRAME_MIN_TIME = (1000/60) * (60 / FRAMES_PER_SECOND) - (1000/60) * 0.5;
var lastFrameTime = 0; // the last frame time
function update(time){
if(time-lastFrameTime < FRAME_MIN_TIME){ //skip the frame if the call is too early
requestAnimationFrame(update);
return; // return as there is nothing to do
}
lastFrameTime = time; // remember the time of the rendered frame
// render the frame
requestAnimationFrame(update); // get next farme
}
requestAnimationFrame(update); // start animation
[X0, y0] से [X1, y1] तक चेतन
वृद्धिशील [x, y] को [startX, startY] से [endX, endY] की गणना करने के लिए वैक्टर का उपयोग करें
// dx is the total distance to move in the X direction
var dx = endX - startX;
// dy is the total distance to move in the Y direction
var dy = endY - startY;
// use a pct (percentage) to travel the total distances
// start at 0% which == the starting point
// end at 100% which == then ending point
var pct=0;
// use dx & dy to calculate where the current [x,y] is at a given pct
var x = startX + dx * pct/100;
var y = startY + dx * pct/100;
उदाहरण कोड:
// canvas vars
var canvas=document.createElement("canvas");
document.body.appendChild(canvas);
canvas.style.border='1px solid red';
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
// canvas styles
ctx.strokeStyle='skyblue';
ctx.fillStyle='blue';
// animating vars
var pct=101;
var startX=20;
var startY=50;
var endX=225;
var endY=100;
var dx=endX-startX;
var dy=endY-startY;
// start animation loop running
requestAnimationFrame(animate);
// listen for mouse events
window.onmousedown=(function(e){handleMouseDown(e);});
window.onmouseup=(function(e){handleMouseUp(e);});
// constantly running loop
// will animate dot from startX,startY to endX,endY
function animate(time){
// demo: rerun animation
if(++pct>100){pct=0;}
// update
x=startX+dx*pct/100;
y=startY+dy*pct/100;
// draw
ctx.clearRect(0,0,cw,ch);
ctx.beginPath();
ctx.moveTo(startX,startY);
ctx.lineTo(endX,endY);
ctx.stroke();
ctx.beginPath();
ctx.arc(x,y,5,0,Math.PI*2);
ctx.fill()
// request another animation loop
requestAnimationFrame(animate);
}