溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

HTML5 canvas 動(dòng)畫基礎(chǔ)自學(xué)分享 2

發(fā)布時(shí)間:2020-08-05 22:52:12 來源:網(wǎng)絡(luò) 閱讀:524 作者:QQ844033231 欄目:移動(dòng)開發(fā)

2.canvas模擬重力

上一章中,知道了怎么在canvas中畫圖,知道了球是怎么運(yùn)動(dòng)起來的.那么就來模擬一下球在重力下的運(yùn)動(dòng).思路有2個(gè).

1.設(shè)球的初始位置是: x0,y0.時(shí)間是t.那么用公式  S = x0 + v0 * t +0.5 * a * t *t;

就是路程 = 初速度*時(shí)間 + 1/2*加速度*時(shí)間的平方.

我們可以得到客戶端的時(shí)間,沒一幀都用初始點(diǎn)來計(jì)算.

2.我們可以算出每一幀的速度,然后進(jìn)行移動(dòng).

來看看下面的代碼:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>小球自由落體</title>
<!------------------------------------------------------------------------------>
<style type="text/css">
body{margin:0px;
    background:#154654;}
#myCanvas{
    border:1px #0000FF solid;}
</style>
<!------------------------------------------------------------------------------>
<script type="text/javascript">
var SCREEN_WIDTH = screen.availWidth;
var SCREEN_HEIGHT = screen.availHeight;
</script>
</head>
<body>
<canvas id="myCanvas" <!-- -->>
your browser is not support canvas.
</canvas>
<!---------------------------------------------------------------------------->
<script type="text/javascript">
function ballMove(canvasID)
{
    var canvas = document.getElementById(canvasID); //得到canvas
    canvas.width = SCREEN_WIDTH;
    canvas.height = SCREEN_HEIGHT;
    var canvas2D = canvas.getContext("2d");
    var refreshRate = ~~(1000/30);      //刷新速率
    var radius = 100;   //園的半徑  
    var ballColor = "rgba(255,255,0,1)" //圓的顏色
    var x = 0;      //圓心的運(yùn)動(dòng)坐標(biāo)
    var y = 0;
    var x0 = 100;       //球的起始位置
    var y0 = 600;
    var yt = 0;         //縱坐標(biāo)時(shí)間
    var xt = 0;         //橫坐標(biāo)時(shí)間
    var flashT = 0.05;  //踩點(diǎn)率 越低越精致
    var vx = 100;           //求的起始速度,注意方向.
    var vy = -100;
    var rate_x = vx;        //球的實(shí)際速度
    var rate_y = vy;
    var ax = 0;     //X方向加速度
    var ay = 15;        //y方向加速度
    var x_off = 10;     //x方向移動(dòng)速度
    var y_off = 10;     //y方向移動(dòng)速度
    var damping = 0;    //球的阻尼效果
    var damping_off = 0;
    var flagx = 1;      //標(biāo)志變量
    var flagy = 1;
    var flag = 1;
    var carshRight = SCREEN_WIDTH - radius;             //碰撞的實(shí)際寬度
    var carshButtom = SCREEN_HEIGHT - radius;           //碰撞的實(shí)際高度
    var carshLeft = 0 + radius;
    var carshTop = 0 +radius;
    stopBall = setInterval(
            function()
            {
                //第一幀
                x = x0 + (vx*xt + 0.5*ax*xt*xt);
                y = y0 + (vy*yt + 0.5*ay*yt*yt);
                //判斷
                if(y > carshButtom)              //到底了
                {
                    y = carshButtom;
                    y0 = carshButtom;
                    if(flag == 1)
                    {
                        vate_y = vy + ay*yt;
                        flag = -1;
                    }
                    vy = vate_y * -1;
                    vate_y = vate_y - damping;
                    damping = damping - damping_off;
                    yt = 0;
                    if(vy > 0) clearInterval(stopBall);          //球停止了.
                    //alert(damping);
                    //if(damping <= 9)alert(1);//clearInterval(stopBall);
                }
                //畫圖
                canvas2D.beginPath();                               ////下面兩句是清除畫布的功能
                canvas2D.clearRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
                canvas2D.arc(x,y,radius,0,Math.PI*2,false);
                canvas2D.fillStyle = ballColor;
                canvas2D.fill();
                //改變
/*              x = x + flagx * x_off;
                y = y + flagy * y_off;
                if( (x+radius) > SCREEN_WIDTH || (x-radius) < 0)flagx *= -1;
                if( (y+radius) > SCREEN_HEIGHT || (y-radius) < 0)flagy *= -1;
                if( x > carshRight || x < carshLeft)flagx *= -1;
                if( y > carshButtom || y < carshTop)flagy *= -1;*/
                                                                                            
                xt = xt + flashT;
                yt = yt + flashT;
/*              if(y > carshButtom)              //到底了
                {
                    if(flagx == 1)
                    {
                    vate_y = vy + 9.8*t;
                    vy = vate_y * -1;
                    t = 0;
                    flagx = -1;
                    }
                }
                if(t > 1)flagx = 1;*/
            }
            ,refreshRate);
                                                                                        
}
//canvas 的寬和高默認(rèn)為 300 * 150,注意設(shè)置數(shù)值都時(shí)候,不用加單位,不用加"PX";
ballMove("myCanvas");
//go canvas painer
</script>
</body>
</html>

這個(gè)是用時(shí)間來改變的.其實(shí)我們可以用向量.自己定義一個(gè)向量類,用向量就能實(shí)驗(yàn)了.這個(gè)時(shí)候,小球就能進(jìn)行自由下落了.我們可以給他的初速度用拖動(dòng)來控制.例如這樣:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>小球自由落體+拖動(dòng)</title>
<!------------------------------------------------------------------------------>
<style type="text/css">
body{margin:0px;}
#myCanvas{
    border:1px #0000FF solid;}
</style>
<!------------------------------------------------------------------------------>
<script type="text/javascript">
var SCREEN_WIDTH = screen.availWidth;
var SCREEN_HEIGHT = screen.availHeight - 150;
</script>
</head>
<body>
<!--<div >
小球的半徑<input type="text" value="" />
小球的顏色<input type="text" value="" />
水平方向加速度<input type="text" value="" />
豎直方向加速度<input type="text" value="" />
</div>-->
<canvas id="myCanvas"  >
your browser is not support canvas.
</canvas>
<!---------------------------------------------------------------------------->
<script type="text/javascript">
function ballMove(canvasID,x0,y0,vx,vy,ax,ay,radius,damping,flashT)
{
    var canvas = document.getElementById(canvasID); //得到canvas
    canvas.width = SCREEN_WIDTH;
    canvas.height = SCREEN_HEIGHT;
    var canvas2D = canvas.getContext("2d");
    var refreshRate = ~~(1000/60);      //刷新速率
    var radius = radius||30;    //園的半徑    
    var ballColor = lineColor//圓的顏色
    var x = 0;      //圓心的運(yùn)動(dòng)坐標(biāo)
    var y = 0;
    var x0 = x0||500;       //球的起始位置
    var y0 = y0||300;  
    var yt = 0          //縱坐標(biāo)時(shí)間
    var xt = 0          //橫坐標(biāo)時(shí)間
    var flashT = flashT||0.1;   //踩點(diǎn)率 越低越精致
    var vx = vx||0;         //求的起始速度,注意方向.
    var vy = vy||0;
    var rate_x = vx;        //球的實(shí)際速度
    var rate_y = vy;
    var ax = ax||0;     //X方向加速度
    var ay = ay||10;        //y方向加速度
    var x_off = 10;     //x方向移動(dòng)速度
    var y_off = 10;     //y方向移動(dòng)速度
    var damping = damping||0;       //球的阻尼效果
    var damping_off = 0.5;
    var flagx = 1;      //標(biāo)志變量
    var flagy = 1;
    var flag = 1;
    var carshRight = SCREEN_WIDTH - radius;             //碰撞的實(shí)際寬度
    var carshButtom = SCREEN_HEIGHT - radius;           //碰撞的實(shí)際高度
    var carshLeft = 0 + radius;
    var carshTop = 0 +radius;
    stopBall = setInterval(
            function()
            {
                //第一幀
                x = x0 + (vx*xt + 0.5*ax*xt*xt);
                y = y0 + (vy*yt + 0.5*ay*yt*yt);
                //判斷
                if(y > carshButtom)              //到底了
                {
                    y = carshButtom;
                    y0 = carshButtom;
                    if(flag == 1)
                    {
                        vate_y = vy + ay*yt;
                        flag = -1;
                    }
                    vy = vate_y * -1;
                    vate_y = vate_y - damping;
                    damping = damping - damping_off;
                    if(damping < 0)damping = 0;
                    yt = 0;
                    if(vy > 0) clearInterval(stopBall);          //球停止了.
                    //alert(damping);
                    //if(damping <= 9)alert(1);//clearInterval(stopBall);
                }
                //畫圖
                canvas2D.beginPath();                               ////下面兩句是清除畫布的功能
                canvas2D.clearRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
                canvas2D.arc(x,y,radius,0,Math.PI*2,false);
                canvas2D.fillStyle = ballColor;
                canvas2D.fill();
                //改變
/*              x = x + flagx * x_off;
                y = y + flagy * y_off;
                if( (x+radius) > SCREEN_WIDTH || (x-radius) < 0)flagx *= -1;
                if( (y+radius) > SCREEN_HEIGHT || (y-radius) < 0)flagy *= -1;
                if( x > carshRight || x < carshLeft)flagx *= -1;
                if( y > carshButtom || y < carshTop)flagy *= -1;*/
                  
                xt = xt + flashT;
                yt = yt + flashT;
                //最后一幀
                if(isDown)
                {
                    clearInterval(stopBall);            //重新繪圖
                    canvas2D.beginPath();                               ////下面兩句是清除畫布的功能
                    canvas2D.clearRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
                    canvas2D.arc(evt.clientX,evt.clientY,radius,0,Math.PI*2,false);
                    canvas2D.fillStyle = ballColor;
                    canvas2D.fill();
                      
                }
/*              if(y > carshButtom)              //到底了
                {
                    if(flagx == 1)
                    {
                    vate_y = vy + 9.8*t;
                    vy = vate_y * -1;
                    t = 0;
                    flagx = -1;
                    }
                }
                if(t > 1)flagx = 1;*/
            }
            ,refreshRate);
            //alert(1);
              
}
</script>
<script type="text/javascript">
var x0 = 0;
var y0 = 0;
var ballX = 0;
var ballY = 0;
var x1 = 0;
var y1 = 0;
var upX = 0;
var upY = 0;
var evt,evt1,evt2;
var startTime = 0;
var stopTime = 0;
var getvx = 0;
var getvy = 0;
var isDown = false;
var radius = 30;
var canvas = document.getElementById("myCanvas");   //得到canvas
var canvas2D = canvas.getContext("2d");
var lineColor = canvas2D.createLinearGradient(0,0,1366,768);
lineColor.addColorStop(0,"rgba(0,0,0,1)");
lineColor.addColorStop(0.2,"rgba(120,0,0,1)");
lineColor.addColorStop(0.4,"rgba(0,120,0,1)");
lineColor.addColorStop(0.6,"rgba(0,0,255,1)");
lineColor.addColorStop(0.8,"rgba(125,45,0,1)");
lineColor.addColorStop(1,"rgba(45,86,111,1)");
var ballColor = lineColor;
canvas.width = SCREEN_WIDTH;
canvas.height = SCREEN_HEIGHT;
function getOldMouseXY()
{
        evt = event || window.event;
        x0 = evt.clientX;
        y0 = evt.clientY;
        isDown = true;
        //alert(ball.getBoundingClientRect().left);
        ballX = x0;
        ballY = y0;
        //畫圖
        //alert(1);
        canvas2D.beginPath();                               ////下面兩句是清除畫布的功能
        canvas2D.clearRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
        canvas2D.arc(x0,y0,radius,0,Math.PI*2,false);
        canvas2D.fillStyle = ballColor;
        canvas2D.fill();
        //alert(ballY);
        startTime = new Date();
          
}
function getNewMouseXY()
{
        evt1 = event || window.event;
        //alert(upX+","+upY+" "+x1+","+y1);
        //速度計(jì)算
        stopTime = new Date();
        var timeOff = stopTime.getTime() - startTime.getTime();
        getvx = ~~((x1 - x0)*100/timeOff);
        getvy = ~~((y1 - y0)*100/timeOff);
        //alert(getvx+","+getvy);
//      alert(timeOff);
        //畫圖
        ballMove("myCanvas",x1,y1,getvx,getvy,0,10,radius,10);
        isDown = false;
}
function dragBall()
{
    evt2 = event || window.event;
    if(isDown)      //是否按下了鼠標(biāo)左鍵
    {
        x1 = evt2.clientX;
        y1 = evt2.clientY;
        var  dragX = x1-x0+ballX;
        var  dragY = y1-y0+ballY;
        //畫圖
        canvas2D.beginPath();                               ////下面兩句是清除畫布的功能
        canvas2D.clearRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
        canvas2D.arc(dragX,dragY,radius,0,Math.PI*2,false);
        canvas2D.fillStyle = ballColor;
        canvas2D.fill();
    }              
}
</script>
<script type="text/javascript">
//var ball = document.getElementById("myCanvas");
 = getOldMouseXY;                    //注意給一個(gè)事件賦值的時(shí)候,不用加括號(hào).
 = dragBall;
 =   getNewMouseXY;
</script>
</body>
</html>

這樣就小球就能用鼠標(biāo)進(jìn)行初始度的開始了.可是現(xiàn)在我們沒有實(shí)現(xiàn)什么類啊,沒有用到JS的類.在接下來的學(xué)習(xí)中,我將自己來建立一個(gè)類,用這個(gè)類來實(shí)驗(yàn)這些效果.

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI