js实现椭圆轨迹_Canvas实现直线与圆形的物理运动效果
導語:之前寫過幾篇關于canvas實現圓環動畫的文章,例如這篇:canvas繪制旋轉的圓環百分比進度條和使用HTML5 Canvas arc()繪制圓形/圓環,實現方法是通過循環繪制圓環(圓餅)等來實現,今天來看看這篇:基于canvas實現物理運動效果與動畫效果(一)。
以下為原文:
一、為什么要寫這篇文章
某年某月某時某種原因,我在慕課網上看到了一個大神實現了關于小球的拋物線運動的代碼,心中很是欣喜,故而寫這篇文章來向這位大神致敬,同時也為了彌補自己在運動效果和動畫效果制作方面的不足
二、幾種簡單的直線運動
這一部分主要講解的是簡單的運動效果的實現原理,其實所有的canvas動畫效果的實現在核心思想是一致的:都是先定義個初始的狀態,然后定義一個定時器,定時器內執行一個方法,記得在這個方法中要對當前的畫面清除,然后在這個方法中重新繪制需要變化的效果,由于人眼存在殘影,所以短時間內的中斷的變化可以看成是連續的變化,這個就是canva動畫運動原理
最簡單的要從勻速直線運動說起,然后是勻加速直線運動。
勻速直線運動
HTML代碼
canvas勻速直線運動你的瀏覽器不支持canvas,請跟換其他瀏覽器試一試
JS代碼
window.οnlοad=function(){
var canvas=document.getElementById('canvas');
canvas.height=728;
canvas.width=1024;
var context=canvas.getContext('2d');
context.fillStyle='red';
context.beginPath();
context.arc(800,300,30,0,2*Math.PI,true);
context.closePath();
context.fill();
setInterval(function(){
run(context);
}, 50);
};
var speed=0;
var startPoint=800;
function run(cxt){
speed=-7;
cxt.clearRect(0,0,1024,728);
//cxt.top+=speed;
startPoint+=speed;
cxt.beginPath();
cxt.arc(startPoint,300,30,0,2*Math.PI,true);
cxt.closePath();
cxt.fill();
}
運行效果如下:
PS:這里面畫面有點卡頓,是錄制的時候軟件的因素造成的,直接運行上訴代碼是可以看到正常運行的效果
重點代碼分析:
var speed=0;
var startPoint=800;
function run(cxt){
speed=-7;
cxt.clearRect(0,0,1024,728);
//cxt.top+=speed;
startPoint+=speed;
cxt.beginPath();
cxt.arc(startPoint,300,30,0,2*Math.PI,true);
cxt.closePath();
cxt.fill();
}
先把速度定義為0和獲取開始點,然后將canvas畫面的內容清除,接著是計算變化后的坐標,然后進行重繪(坐標重新計算是運動關鍵所在)
勻變速直線運動
勻變速直線運動的定義:在直線運動中,把加速度的大小和方向都不改變的運動(加速度為正時),稱之為勻加速直線運動。
基本公式:
速度公式: V=V0+at
位移公式: x=V0t+1/2at^2
所以我們依次需要定義這樣的幾個變量加速度a,初始速度V0,位移量x,隨時間變化的速度v,時間time,這幾個變量的初始化值均為0,代碼如下所示:
HTML代碼:
canvas勻加速直線運動你的瀏覽器不支持canvas,請跟換其他瀏覽器試一試
JavaScript代碼:
window.οnlοad=function(){
var canvas=document.getElementById('canvas');
canvas.height=728;
canvas.width=1024;
var context=canvas.getContext('2d');
context.fillStyle='red';
context.beginPath();
context.arc(800,300,30,0,2*Math.PI,true);
context.closePath();
context.fill();
setInterval(function(){
run(context);
}, 50);
};
var v0=0;//初始速度
var a=0;//加速度
var v=0;//變化的速度
var time=0;//時間
var x=0;//位移量
var startPoint=800;//起始點
// V=V0+at
// x=v0t+1/2at^2
// v^2-V^2=2ax
function run(cxt){
time+=0.05;
a=10;
x=-(0.5*a*(time*time));//位移公式代入
startPoint+=x;
cxt.clearRect(0,0,1024,728);
cxt.beginPath();
cxt.arc(startPoint,300,30,0,2*Math.PI,true);
cxt.closePath();
cxt.fill();
}
運行的效果如下:
基本上直線運動比較典型的也就是這兩種,如有遺漏其他運動或者是需要博主講解其他運動的制作的,請在留言板上留言
三、簡單的曲線運動的實現
說到簡單的曲線運動,我們就從最簡單的也是我認為最基礎的運動圓周運動說起
1、勻速圓周運動
圓周運動的定義:質點沿圓周運動,如果在任意相等的時間里通過的圓弧長度都相等,這種運動就叫做“勻速圓周運動”,亦稱“勻速率圓周運動”。因為物體作圓周運動時速率不變,但速度方向隨時發生變化。所以勻速圓周運動的線速度是每時每刻都在發生變化的。
勻速圓周運動的實現與分析
勻速圓周運動的實現第一反應我們會選擇通過勻速圓周運動的物理公式進行計算得到,但是物理公式中沒有哪條明確的公式是可以把單位時間的變化量和所在點的具體坐標相關聯的,顯然這樣的一條思路是行不通的,從物理公式上面是來說是不具有可行性的,所以我們應該要換另外的一種方法來實現,這個時候我們應該要看透勻速圓周運動的本質,本質上來說,勻速圓周運動的實現其實就是通過一個原點,然后在這個原點的基礎之上對一個物體進行360度的旋轉。好的,相信對canvas api熟悉的小伙伴已經想到了,是的,我們可以通過旋轉或者是矩陣來實現
canvas實現圓周運動你的瀏覽器不支持canvas,請跟換其他瀏覽器試一試
相關的JavaScript代碼:
window.οnlοad=function(){
var canvas=document.getElementById('canvas');
canvas.height=728;
canvas.width=1024;
var context=canvas.getContext('2d');
drawNotChange(context);
context.fillStyle='blue';
context.beginPath();
context.arc(500,550,30,0,2*Math.PI,true);
context.closePath();
context.fill();
setInterval(function(){
run(context);
}, 50);
};
var time=0;//定義運動的執行次數
function run(cxt){
cxt.clearRect(0,0,1024,728);
drawNotChange(cxt);
cxt.save();//將當前以左上角坐標為(0,0)的上下文環境進行保存,這樣是為了在接下來中要進行畫布偏移后,可以進行還原當前的環境
cxt.translate(500,400);
cxt.rotate(time*8*Math.PI/180);//設定每次旋轉的度數
cxt.fillStyle='blue';
cxt.beginPath();
cxt.arc(0,150,30,0,2*Math.PI,false);
cxt.closePath();
cxt.fill();
cxt.restore();//將當前為(500,400)的點還原為(0,0),其實在save中就是將上下文環境保存到棧中,在restore下面對其進行還原
time+=1;
}
//繪制不變因素
function drawNotChange(context){
context.fillStyle='red';
context.beginPath();
context.arc(500,400,30,0,2*Math.PI,true);
context.closePath();
context.fill();
context.beginPath();
context.arc(500,400,150,0,2*Math.PI,true);
context.closePath();
context.stroke();
}
運行的結果如下:
為了讓讀者能夠明白其中的原理,我會在注釋中盡量將代碼注釋清楚
2、橢圓運動
可能有些小伙伴們對于高中的知識都已經遺忘了,但是這個不妨礙,因為在接下來我們會通過一步一步的復習相關數學知識最后才來實現效果,但是如果對高中知識比較熟悉的小伙伴,建議跳過這個階段,直接看代碼就行了,以免浪費時間
橢圓的定義:橢圓(Ellipse)是平面內到定點F1、F2的距離之和等于常數(大于|F1F2|)的動點P的軌跡,F1、F2稱為橢圓的兩個焦點。其數學表表達式為:|PF1|+|PF2|=2a(2a>|F1F2|)
橢圓圖解:
長軸長我們用2a表示,短軸長我們用2b表示
假設橢圓的長軸與X軸平行,那么表達式如下所示:
根據三角函數之間的關系我們可以推導出:
x=a+cos(t)
y=b+sin(t)
這里面的t代表的是單位是單位時間內旋轉的弧度
具體的推導會在以后有時間,為大家專門寫一篇博文來講解一些公式的推導過程
關于橢圓的數學知識已經講完了,還是不太清楚的同學請執行去復習高中的知識,在這里就不再累贅了。
我們還開始代碼實現之前還有先假設好一些參數,我們假設原點O(500,300),繞橢圓運動的物體為圓形半徑為30,其中長半軸長a=200,短半軸長為b=100,每次重新獲取物體的運動后的移動位置的時候,x都會變化一個單位,旋轉為順時針旋轉,開始位置為原點的正左邊的端點,最后原點我們以一個黑色且半徑為10的小球表示。注意:上述的數據可以讀者自行定義,但是要注意這個前提是必須保證a>b,如果a
我們先來實現橢圓的軌跡效果:
HTML代碼:
canvas實現橢圓運動你的瀏覽器不支持canvas,請跟換其他瀏覽器試一試
JavaScript代碼:
var a=200,
b=100,
radius=30;
window.οnlοad=function(){
var canvas=document.getElementById('canvas');
canvas.height=668;
canvas.width=1024;
var cxt=canvas.getContext('2d');
cxt.beginPath();
cxt.arc(300,300,10,0,2*Math.PI,true)
cxt.closePath();
cxt.fill();
route(cxt,300,300,200,100);
};
//橢圓路線繪制
function route(context,x,y,a,b){
//max是等于1除以長軸值a和b中的較大者
//i每次循環增加1/max,表示度數的增加
//這樣可以使得每次循環所繪制的路徑(弧線)接近1像素
var step = (a > b) ? 1 / a : 1 / b;
context.beginPath();
context.moveTo(x + a, y); //從橢圓的左端點開始繪制
for (var i = 0; i < 2 * Math.PI; i += step)
{
//參數方程為x = a * cos(i), y = b * sin(i),
//參數為i,表示度數(弧度)
context.lineTo(x + a * Math.cos(i), y + b * Math.sin(i));
}
context.closePath();
context.stroke();
}
橢圓的軌跡的思路是:通過循環,將極小的線段首尾相連,繪制了一個類似于橢圓的一個圖像,但是由于線段太過細小導致了我們肉眼看上去就成了一個橢圓
運行的效果是:
橢圓上小球的運動實現
這個的制作思路跟上面的思路是一樣的,所以這里就不再分析
這次我們就先看一看效果如何:
HTML代碼和上面的例子相同
JavaScript代碼如下:
var a=200,
b=100,
radius=30;
time=0;//循環的次數
window.οnlοad=function(){
var canvas=document.getElementById('canvas');
canvas.height=768;
canvas.width=1024;
var cxt=canvas.getContext('2d');
centerPoint(cxt);
arcRoute(cxt,300,300,a,b,radius);
setInterval(function(){
arcRoute(cxt,300,300,a,b,radius);
}, 70);
};
//繪制原點
function centerPoint(cxt){
cxt.fillStyle="black";
cxt.beginPath();
cxt.arc(300,300,10,0,2*Math.PI,true)
cxt.closePath();
cxt.fill();
}
//橢圓路線繪制
function route(context,x,y,a,b){
var step = (a > b) ? 1 / a : 1 / b;
context.beginPath();
context.moveTo(x + a, y); //從橢圓的左端點開始繪制
for (var i = 0; i < 2 * Math.PI; i += step)
{
context.lineTo(x + a * Math.cos(i), y + b * Math.sin(i));
}
context.closePath();
context.stroke();
}
//橢圓上小球運動的實現
function arcRoute(context,x,y,a,b,r){
context.clearRect(0,0,1024,768);
route(context,x,x,a,b);
centerPoint(context);
var step = (a > b) ? 1 / a : 1 / b;
context.fillStyle="red";
if(time==0){
context.beginPath();
context.arc(x,y,r,0,2*Math.PI,true);
context.closePath();
context.fill();
}else{
context.beginPath();
context.arc(x+a*Math.cos(time),y+b*Math.sin(time),r,0,2*Math.PI,true);
context.closePath();
context.fill();
}
time+=1;
}
四、相關的參考資料
火狐開發者中心
沈佳洋
使用HTML5 Canvas arc()繪制圓形/圓環
CSS3制作圓環進度動畫效果
好了,這一節的內容就先結束了,下一節預告,下一節:會談談一些其他的運動效果的實現和這些運動效果的另一種實現方式,同時還會有一些關于碰撞的檢測等等的知識,敬請期待。如果有什么不懂或者是錯誤的地方,歡迎給位朋友在留言板留下你的想法,你的支持是我前進的動力
更多關于canvas文章:圓環繪制
總結
以上是生活随笔為你收集整理的js实现椭圆轨迹_Canvas实现直线与圆形的物理运动效果的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: babylonjs 分部加载模型_如何使
- 下一篇: pycharm如何分两页阅读_雅思高分喜