手把手地教你怎麼用canvas的rotate做出類似太陽系(包括月球的公轉)的嵌套運動

需要運用到的關於canvas的一些代碼

  • save()方法把當前狀態的一份拷貝壓入到一個保存圖像狀態的棧中。這就允許您臨時地改變圖像狀態,然後,通過調用 restore()
    來恢復以前的值。
    可是要注意,當前路徑和當前位置並非圖形狀態的一部分,並且不會由這個方法保存。以上均爲w3chool裏的介紹,但是這裏我個人感覺有點問題下面會講)

  • rotate() 方法根據原點旋轉當前的繪圖。

  • translate(x,y); 方法設定原點的指令之後我就就概括爲原點。

  • beginPath() 方法開始一條路徑,或重置當前的路徑。

  • stroke() 方法會實際地繪製出通過 moveTo() 和 lineTo()
    方法定義的路徑。默認顏色是黑色。(也可以當做結束當前畫的圖形的一個指令畫完一個圖形也就是在beginPath()
    之後一定要加要不然會出現奇怪的效果)

  • clearRect(x,y,width,height)方法清空給定矩形內的指定像素。

  • globalCompositeOperation
    屬性設置或返回如何將一個源(新的)圖像繪製到目標(已有)的圖像上。destination-over 在源圖像上方顯示目標圖像。

  • arc(x,y,r,sAngle,eAngle,counterclockwise);畫圓的方法

x 圓的中心的 x 座標。 y 圓的中心的 y 座標。 r 圓的半徑。 sAngle 起始角,以弧度計。(弧的圓形的三點鐘位置是 0 度)。
eAngle 結束角,以弧度計。 counterclockwise 可選。規定應該逆時針還是順時針繪圖。 False = 順時針,true逆時針。

fillStyle
strokeStyle
fill()等方法就此略過

接下來就開始操作!!

<body>
<canvas id="" width="500" height="500"></canvas>
<script type="text/javascript" charset="utf-8">


  var ctx = document.querySelector('canvas').getContext('2d');
 ctx.globalCompositeOperation = 'destination-over';
 //讓新的圖案覆蓋原來的團,按照從下網上的順序

  setInterval(function () {
    ctx.clearRect(0,0,500,500);
    //運用定時器來實現動畫效果,每次都先清空畫布
      //這裏開始寫代碼咯
  },60)

</script>
</body>`

然後開始搭建背景內容

<body>
<canvas id="" width="500" height="500"></canvas>
<script type="text/javascript" charset="utf-8">


  var ctx = document.querySelector('canvas').getContext('2d');
ctx.globalCompositeOperation = 'destination-over';//讓新的圖案覆蓋原來的團,按照從上往下的覆蓋順序

  setInterval(function () {
    ctx.clearRect(0,0,500,500);//運用定時器來實現動畫效果,每次都先清空畫布
    ctx.beginPath();//開始新的繪製
    ctx.arc(250, 250, 200, 0, Math.PI * 2, true);//以250,250的中心爲原點畫一個半徑爲200的圓圈當做太陽系的軌道
    ctx.strokeStyle='red';//
    ctx.stroke();//結束這次一次繪製

    ctx.beginPath();//開始新的一次繪製
    ctx.arc(250, 250, 30, 0, Math.PI * 2, true);//在中心畫了個圓
    ctx.fillStyle='red';//中心填充的顏色是紅色
    ctx.strokeStyle='red';//邊框的顏色是紅色色
    ctx.fill();//開始填充紅色顏色
    ctx.stroke();//結束這一次繪製
  },60)

</script>
</body>

在這裏插入圖片描述
如圖所示,接下里開始添加上藍藍的地球

<body>
<canvas id="" width="500" height="500"></canvas>
<script type="text/javascript" charset="utf-8">


  var ctx = document.querySelector('canvas').getContext('2d');
  ctx.globalCompositeOperation = 'destination-over';
  setInterval(function () {
    ctx.clearRect(0,0,500,500);//運用定時器來實現動畫效果,每次都先清空畫布


    ctx.save();
    //爲了不影響背景,也是爲了更好地使用rotae
    //這裏要用save來保存設置也是開闢一個新的空間,獨立於背景
    ctx.beginPath();//開始繪製
    ctx.translate(250,250);//原來的原點座標默認爲0,0要將原點座標設置爲250,250才能讓rotate繞着中心旋轉
    ctx.rotate(0);

    ctx.translate(200,0);//這個translate在250,250的基礎
   // 上往右又移動了200停留在軌道上不會影響上面rotate
    //,隻影響下面畫出來的藍色地球
    ctx.fillStyle='blue';
    ctx.strokeStyle='blue';
    ctx.arc(0, 0, 30, 0, Math.PI * 2, true);//畫藍色的地球
    ctx.fill();
    ctx.stroke();


    ctx.restore();


    ctx.beginPath();//開始新的一次繪製
    ctx.arc(250, 250, 30, 0, Math.PI * 2, true);//在中心畫了個圓
    ctx.fillStyle='red';//中心填充的顏色是紅色
    ctx.strokeStyle='red';//邊框的顏色是紅色色
    ctx.fill();//開始填充紅色顏色
    ctx.stroke();//結束這一次繪製

    ctx.beginPath();//開始新的繪製
    ctx.arc(250, 250, 200, 0, Math.PI * 2, true);
    //以250,250的中心爲原點畫一個半徑爲200的圓圈當做太陽系的軌道
    ctx.strokeStyle='red';//
    ctx.stroke();//結束這次一次繪製


  },60)

</script>
</body>

在這裏插入圖片描述
這時候爲了更好理解原點的座標我先不加旋轉的動畫,下面代碼中我就加上月球

<body>
<canvas id="" width="600" height="600"></canvas>
<script type="text/javascript" charset="utf-8">


  var ctx = document.querySelector('canvas').getContext('2d');
  ctx.globalCompositeOperation = 'destination-over';
  setInterval(function () {
    ctx.clearRect(0,0,500,500);//運用定時器來實現動畫效果,每次都先清空畫布


    ctx.save();//爲了不影響背景,也是爲了更好地使用rotae
    //這裏要用save來保存設置也是開闢一個新的空間,獨立於背景
    ctx.beginPath();//開始繪製
    ctx.translate(250,250);//原來的原點座標默認爲0,0
    //要將原點座標設置爲250,250才能讓rotate繞着中心旋轉
    ctx.rotate(0);//0度

    ctx.translate(200,0);
    //這個translate在250,250的基礎上往右又移動了200停留在軌道上
    //不會影響上面rotate,
    // 隻影響下面畫出來的藍色地球
    ctx.fillStyle='blue';
    ctx.strokeStyle='blue';
    ctx.arc(0, 0, 30, 0, Math.PI * 2, true);
    //畫藍色的地球這裏的想x,y是按照translate的定位來設置的
    // 這裏的x,y就是450,250的位置
    ctx.fill();
    ctx.stroke();

    
    ctx.save();//再用save這個是實現公轉的關鍵
    ctx.beginPath();
    ctx.rotate(0);//0度

    ctx.translate(50,0);
    //這個translate是按照上一個translate的座標來定位的
    //所以現在的translate的定位爲550,250的位置
    ctx.fillStyle='green';
    ctx.strokeStyle='green';
    ctx.arc(0, 0, 10, 0, Math.PI * 2, true);
    //根據translate定位的原點什麼都不動的情況下月球的位置爲550,250
    ctx.fill();
    ctx.stroke();
    ctx.restore();//把月球代碼包起來形成嵌套


    ctx.restore();



    ctx.beginPath();//開始新的一次繪製
    ctx.arc(250, 250, 30, 0, Math.PI * 2, true);//在中心畫了個圓
    ctx.fillStyle='red';//中心填充的顏色是紅色
    ctx.strokeStyle='red';//邊框的顏色是紅色色
    ctx.fill();//開始填充紅色顏色
    ctx.stroke();//結束這一次繪製

    ctx.beginPath();//開始新的繪製
    ctx.arc(250, 250, 200, 0, Math.PI * 2, true);
    //以250,250的中心爲原點畫一個半徑爲200的圓圈當做太陽系的軌道
    ctx.strokeStyle='red';//
    ctx.stroke();//結束這次一次繪製


  },60)

</script>
</body>

在這裏插入圖片描述
再根據rotate的值都設爲了0,再參考一張圖
在這裏插入圖片描述

集合原點的位置我們可以很好地推出上面的情況是如何出來的接下來我改變地球球的旋轉角度試一試`

 ctx.save();//爲了不影響背景,也是爲了更好地使用rotae這裏要用save來保存設置也是開闢一個新的空間,獨立於背景
    ctx.beginPath();//開始繪製
    ctx.translate(250,250);//原來的原點座標默認爲0,0要將原點座標設置爲250,250才能讓rotate繞着中心旋轉
    ctx.rotate(90*Math.PI/180);//旋轉了90度

    ctx.translate(200,0);//這個translate在250,250的基礎上往右又移動了200停留在軌道上不會影響上面rotate,
    // 隻影響下面畫出來的藍色地球
    ctx.fillStyle='blue';
    ctx.strokeStyle='blue';
    ctx.arc(0, 0, 30, 0, Math.PI * 2, true);
    //畫藍色的地球這裏的想x,y是按照translate的定位來設置的
    // 這裏的x,y就是450,250的位置
    ctx.fill();
    ctx.stroke();


    ctx.save();//再用save這個是實現公轉的關鍵
    ctx.beginPath();
    ctx.rotate(0);//0度

    ctx.translate(50,0);//這個translate是按照上一個translate的座標來定位的
    //所以現在的translate的定位爲550,250的位置
    ctx.fillStyle='green';
    ctx.strokeStyle='green';
    ctx.arc(0, 0, 10, 0, Math.PI * 2, true);//根據translate定位的原點什麼都不動的情況下月球的位置爲550,250
    ctx.fill();
    ctx.stroke();
    ctx.restore();//把月球代碼包起來形成嵌套


    ctx.restore();

爲了減少冗餘我就單獨地把save裏的東西拿了出來
可以看到我只將角度改成了90度按理說只有地球會移動到下面去可事實是如下
在這裏插入圖片描述

可以看到月球也改變了方位也就是說原點的位置也發生了改變可以說說明幾點問題

- rotae會改變原點位置

- save嵌套,裏邊的save旋轉的中心就是外邊的原點位置

- 角度也是相對的在地球0度的情況下,月球的0度在地球的右邊也就是外邊,地球90度的情況下,月球的0度在地球的下邊邊也是外邊。

- save會保存上一層的原點座標與w3chool定義出了衝突。

基於以上的結論就可以給地球添加上動畫月球就會跟着地球旋轉了。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<canvas id="" width="600" height="600"></canvas>
<script type="text/javascript" charset="utf-8">


  var ctx = document.querySelector('canvas').getContext('2d');
  ctx.globalCompositeOperation = 'destination-over';
  setInterval(function () {
    ctx.clearRect(0,0,600,600);//運用定時器來實現動畫效果,每次都先清空畫布


    ctx.save();//爲了不影響背景,也是爲了更好地使用rotae這裏要用save來保存設置也是開闢一個新的空間,獨立於背景
    ctx.beginPath();//開始繪製
    ctx.translate(250,250);//原來的原點座標默認爲0,0要將原點座標設置爲250,250才能讓rotate繞着中心旋轉
    var time = new Date(); //新建一個日期類用來控制旋轉

    //rotate是按照上一個translate的定位來旋轉的
    //所以這個rotate的旋轉定位就是250,250也就是圖像中心
    ctx.rotate(((2 * Math.PI) / 60) * time.getSeconds()
      //獲取秒來控制大致的移動速度可以減小分母或者增大分母來控制速度的快慢
      + ((2 * Math.PI) / 60000) * time.getMilliseconds());
      + //獲取毫秒讓動畫更加圓潤,不卡頓

    ctx.translate(200,0);//這個translate在250,250的基礎上往右又移動了200停留在軌道上不會影響上面rotate,
    // 隻影響下面畫出來的藍色地球
    ctx.fillStyle='blue';
    ctx.strokeStyle='blue';
    ctx.arc(0, 0, 30, 0, Math.PI * 2, true);
    //畫藍色的地球這裏的想x,y是按照translate的定位來設置的
    // 這裏的x,y就是450,250的位置
    ctx.fill();
    ctx.stroke();


    ctx.save();//再用save這個是實現公轉的關鍵
    ctx.beginPath();
    ctx.rotate(0);//0度

    ctx.translate(50,0);//這個translate是按照上一個translate的座標來定位的
    //所以現在的translate的定位爲550,250的位置
    ctx.fillStyle='green';
    ctx.strokeStyle='green';
    ctx.arc(0, 0, 10, 0, Math.PI * 2, true);//根據translate定位的原點
    //什麼都不動的情況下月球的位置爲550,250
    ctx.fill();
    ctx.stroke();
    ctx.restore();//把月球代碼包起來形成嵌套


    ctx.restore();



    ctx.beginPath();//開始新的一次繪製
    ctx.arc(250, 250, 30, 0, Math.PI * 2, true);//在中心畫了個圓
    ctx.fillStyle='red';//中心填充的顏色是紅色
    ctx.strokeStyle='red';//邊框的顏色是紅色色
    ctx.fill();//開始填充紅色顏色
    ctx.stroke();//結束這一次繪製

    ctx.beginPath();//開始新的繪製
    ctx.arc(250, 250, 200, 0, Math.PI * 2, true);//以250,250的中心爲原點畫一個半徑爲200的圓圈當做太陽系的軌道
    ctx.strokeStyle='red';//
    ctx.stroke();//結束這次一次繪製


  },60)

</script>
</body>
</html>

在這裏插入圖片描述

那我們再給月球添加上動畫效果就完成了!!!!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<canvas id="" width="600" height="600"></canvas>
<script type="text/javascript" charset="utf-8">


  var ctx = document.querySelector('canvas').getContext('2d');
  ctx.globalCompositeOperation = 'destination-over';
  setInterval(function () {
    ctx.clearRect(0,0,600,600);//運用定時器來實現動畫效果,每次都先清空畫布


    ctx.save();//爲了不影響背景,也是爲了更好地使用rotae這裏要用save來保存設置也是開闢一個新的空間,獨立於背景
    ctx.beginPath();//開始繪製
    ctx.translate(250,250);//原來的原點座標默認爲0,0要將原點座標設置爲250,250才能讓rotate繞着中心旋轉
    var time = new Date(); //新建一個日期類用來控制旋轉

    //rotate是按照上一個translate的定位來旋轉的所以這個rotate的旋轉定位就是250,250也就是圖像中心
    ctx.rotate(((2 * Math.PI) / 60) * time.getSeconds()
      //獲取秒來控制大致的移動速度可以減小分母或者增大分母來控制速度的快慢
      + ((2 * Math.PI) / 60000) * time.getMilliseconds());//獲取毫秒讓動畫更加圓潤,不卡頓

    ctx.translate(200,0);//這個translate在250,250的基礎上往右又移動了200停留在軌道上不會影響上面rotate,
    // 隻影響下面畫出來的藍色地球
    ctx.fillStyle='blue';
    ctx.strokeStyle='blue';
    ctx.arc(0, 0, 30, 0, Math.PI * 2, true);
    //畫藍色的地球這裏的想x,y是按照translate的定位來設置的
    // 這裏的x,y就是450,250的位置
    ctx.fill();
    ctx.stroke();


    ctx.save();//再用save這個是實現公轉的關鍵
    ctx.beginPath();
    var time = new Date(); //新建一個日期類用來控制旋轉

    //這裏的rotate旋轉的中心是按照上一層save的原點,
    //上一層的原點在改變所以月球的旋轉的中心也會改變
    ctx.rotate(((2 * Math.PI) / 6) * time.getSeconds()
      //獲取秒來控制大致的移動速度可以減小分母或者增大分母來控制速度的快慢
      + ((2 * Math.PI) / 6000) * time.getMilliseconds());//獲取毫秒讓動畫更加圓潤,不卡頓

    ctx.translate(50,0);//這個translate是按照上一個translate的座標來定位的
    //所以現在的translate的定位爲550,250的位置
    ctx.fillStyle='green';
    ctx.strokeStyle='green';
    ctx.arc(0, 0, 10, 0, Math.PI * 2, true);
    //根據translate定位的原點什麼都不動的情況下月球的位置爲550,250
    ctx.fill();
    ctx.stroke();
    ctx.restore();//把月球代碼包起來形成嵌套


    ctx.restore();



    ctx.beginPath();//開始新的一次繪製
    ctx.arc(250, 250, 30, 0, Math.PI * 2, true);//在中心畫了個太陽
    ctx.fillStyle='red';//中心填充的顏色是紅色
    ctx.strokeStyle='red';//邊框的顏色是紅色色
    ctx.fill();//開始填充紅色顏色
    ctx.stroke();//結束這一次繪製

    ctx.beginPath();//開始新的繪製
    ctx.arc(250, 250, 200, 0, Math.PI * 2, true);
    //以250,250的中心爲原點畫一個半徑爲200的圓圈當做太陽系的軌道
    ctx.strokeStyle='red';//
    ctx.stroke();//結束這次一次繪製


  },60)

</script>
</body>
</html>

在這裏插入圖片描述
也可以做些騷操作,比如再給月球來一個旋轉的衛星形成三個save的嵌套,這裏我就不做過多演示了。

如果這邊博客能幫上一點忙得那就請點個贊把^ - ^

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章