Canvas 旋轉風車繪製

 

寫在前面:javascript

     親愛的朋友們你們好,鄙人自學前端,第一次寫博客,寫的很差的地方,煩請同窗們諒解,若是本文對你有一丁點幫助,還請勞駕您給我點個贊,您的承認將是我堅持下去的強大動力!謝謝!css

 

   在進行教學以前,我想聰明的你已經掌握了基本的Canvas基本操做方法,若是對Canvas還不是很瞭解,那麼我建議你去http://www.w3school.com.cn/tags/html_ref_canvas.asp這裏先熟悉一下;
html

okey!下圖便是咱們完成後的簡單效果,心動不如行動,那麼我們就進行簡單繪製吧!    前端

一、定義畫布

  首先咱們如今html文件裏面插入<canvas>標籤,定義畫布的尺寸,我這裏定義畫布的尺寸爲800*600像素。同時在內部樣式表裏面設置canvas的背景色(方便畫圖時觀看);java

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">
        body{
            padding: 0;
            margin: 0;
        }
        #canvas {
            background:#5151a2;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="800" height="600"></canvas>
</body>
</html> 

  接下來的核心就是在原生JS環境下,繪製風車;經過JS DOM操做方法獲取到canvas元素對象,並經過getContex("2d")獲取2D繪圖上下文,經過這個方法就像是要告訴瀏覽器「咱們要在這個畫布上繪製2d圖形」;git

<script type="text/javascript">

    //獲取畫布的2d上下文
    var ctx = document.getElementById("canvas").getContext("2d");

二、繪製風車底座

  風車的底座的幾何圖形看似就像一個細長細長的梯形,咱們能夠畫出一個梯形出來,而後填充顏色,這裏爲了達到相對較好的效果,使用了顏色漸變填充的方法;okey!直接看代碼吧~~!github

    //定義一個函數 ,封裝風車的底部基座
    function buttom(){
        ctx.beginPath();                                        //開始一條新的繪製路徑
        var liner = ctx.createLinearGradient(390,600,410,600);    //設置變量(顏色漸變的方向-起點-終點)
        liner.addColorStop(0,"#ccc");                            //設置起點顏色
        liner.addColorStop(0.5,"#fff");                            //設置中點顏色
        liner.addColorStop(1,"#ccc");                            //設置終點顏色
        ctx.fillStyle = liner;                                    //梯形的填充方式設置爲 變量(漸變顏色)    
        ctx.moveTo(395,300);                                    //提起咱們的畫筆,起點設置爲(395,300)
        ctx.lineTo(405,300);                                    //鏈接起點畫線
        ctx.lineTo(410,600);
        ctx.lineTo(390,600);                                    
        ctx.closePath();                                        //閉合路徑
        ctx.fill();                                                //填充梯形
        
    }
  buttom();                              //要調用函數,才能在瀏覽器顯示

咱們來看一下頁面中的效果,是否是很簡單?canvas

(我感受我話有點多哦~!~!)瀏覽器

三、繪製葉子

  接下來的部分將是這個動畫中最關鍵的地方,首先咱們分析一下葉子的結構,三片葉子夾角爲120°,並且每片葉子的形狀是相同的;他們有一個圓心,你心中或許也有疑問,先畫圓心仍是先畫葉子?葉子的形狀應該怎麼畫呢?葉子可不可複製粘貼呢?答案固然是能夠的,Let's do it! 微信

思路分析:

    1)、因爲3片葉子的形狀是如出一轍,咱們只須要畫出一片葉子,第二第三片葉子直接copy就好了,聰明的咱們是否是應該給這個葉子的畫法封裝一個函數呀?就叫它bind(  )函數吧!!每次調用它就能夠了!哎!大家TM太機智了

  2)、三片葉子有一個圓心,繪製葉子的時候爲了方便取座標值,咱們將圓心從畫圖的左上角移動梯形頂部,這樣咱們繪製葉子會方便不少!這裏使用了translate()方法,移動座標系!

    3)、最難的一點就是理解這裏動畫是怎麼實現的,由於動畫原理會影響到咱們畫葉子的文檔結構:

    首先咱們先新建一個繪圖環境,咱們稱它爲環境1,咱們在環境1上畫完第一片葉子;而後在   第一個繪圖環境前提下  旋轉120°新建第一個繪圖環境2,再此基礎上調用畫葉子的函數bind(  ),繪製二片葉子;第三片葉子的繪製方法如法炮製,在環境2的基礎上旋轉120°,新建環境3,調用繪製葉子函數bind(  )畫第三片葉子;

    若是要實現動畫,咱們只須要旋轉第一片葉子的繪圖環境1,第二片葉子和第三片葉子都是參照環境1爲基準畫出來的,是否是也跟着動起來了呢??        彈幕:666666

  4)、最後就是一些基本的外觀樣式調試的啦!好比顏色漸變啊,透明度啊,之類的!

 

以上思路聽明白的同窗請  扣1,不明白的扣2!    

    22222           222222            1                 垃圾,下去                   66666        2222        22

2222          22222        222       22   22        最帥不過盧本偉                    222          2222

2222  ··。。。。。  博主你講的什麼鬼              博主我要跟你生猴子                222                222

 

    okey,我們也很少扯,個人表達能力實在有限,不能理解的粉絲自行腦補!!那位要跟我生猴子的同窗,留下微信哈!

 

 

繪製葉子

    畫這個葉子形狀的時候我是慢慢調試的,個人審美至關low,原諒我只能畫出這樣的葉子,固然想象力豐富的同窗能夠根據本身喜愛來繪製,不過大致思路是一致的;

這裏我聲明瞭一個變量 var num = 0;,做爲環境1旋轉度數變化的一個參數:  那麼咱就直接看代碼吧!!!


var num =0;
function
yezi(){ ctx.save(); //保存默認狀況下的canvas變換狀態 ctx.beginPath(); ctx.translate(400,300); // ctx.globalAlpha = 0.9; // 設置第一次狀態下 座標系旋轉度數 ctx.rotate((Math.PI/180)*num); var liner1 = ctx.createLinearGradient(30,-12,30,12); //這裏設置顏色漸變填充的樣式 liner1.addColorStop(0,"#ccc"); liner1.addColorStop(0.5,"#fff"); liner1.addColorStop(1,"#ccc"); ctx.fillStyle = liner1; ctx.save(); //保存第一次狀態 平移座標系變換 ctx.beginPath(); bind(); //調用函數 //繪製第二片葉子 ctx.beginPath(); ctx.rotate((Math.PI/180)*120); //座標系旋轉120° ctx.save(); //保存旋轉座標系狀態,爲第三片葉子作鋪墊 bind(); //調用函數 //繪製第三片葉子 ctx.beginPath(); ctx.rotate((Math.PI/180)*120); //座標系旋轉120° ctx.save(); bind(); //調用函數 ctx.restore(); //回覆第3次狀態前(旋轉座標系) ctx.restore(); //回覆第2次狀態前(旋轉座標系) //繪製葉子中心圓圈 ctx.beginPath(); var arcgradient = ctx.createRadialGradient(0,0,0,0,0,16); arcgradient.addColorStop(0,"#ccc"); arcgradient.addColorStop(0.1,"#fff"); arcgradient.addColorStop(1,"#ccc"); ctx.arc(0,0,10,0,Math.PI*2); ctx.fillStyle = arcgradient; ctx.fill(); ctx.restore(); //回覆第1次狀態前(平移座標系) num+=5; //第一狀下 環境1 態座標系旋轉度數增長********************************這個num使得環境1的旋轉角度在不停的變化,********************************************** ctx.restore(); } //繪製每片葉子都重複的代碼,這裏作一個函數包裝 function bind(){ ctx.moveTo(0,0); ctx.quadraticCurveTo(10,-12,30,-12);    //比賽爾曲線 ctx.lineTo(190,-3); ctx.quadraticCurveTo(200,0,190,3);     ctx.lineTo(30,12); ctx.moveTo(0,0); ctx.quadraticCurveTo(10,12,30,12); ctx.fill(); }

 

 

四、設置動畫

  動畫這部分就比較簡單了,設置定時器,清除畫布,調用函數;大功告成,打完收工!!!

setInterval(function(){
        ctx.clearRect(0,0,800,600);    //每次執行代碼前,都要將畫布清空,否則畫出的圖形會滯留在畫布上;
        buttom();               //調用函數 
        yezi();
    },50);

 

 

 

  啊 !忘記給源碼了,sorry!

https://github.com/224137748/Canvas/blob/master/windmill.html

相關文章
相關標籤/搜索