親愛的朋友們大家好,鄙人自學前端,第一次寫博客,寫的不好的地方,煩請同學們諒解.
在進行教學之前,我想聰明的你已經掌握了基本的Canvas基本操作方法,如果對Canvas還不是很了解,那麼我建議你去http://www.w3school.com.cn/tags/html_ref_canvas.asp這裡先熟悉一下;
okey!下圖即是我們完成後的簡單效果,心動不如行動,那麼咱們就進行簡單繪製吧!
1、定義畫布首先我們現在html文件裡面插入<canvas>標籤,定義畫布的尺寸,我這裡定義畫布的尺寸為800*600像素。同時在內部樣式表裡面設置canvas的背景色(方便畫圖時觀看);
<!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圖形;
<script type=text/javascript> //獲取畫布的2d上下文var ctx = document.getElementById(canvas).getContext(2d);2、繪製風車底座
風車的底座的幾何圖形看似就像一個細長細長的梯形,我們可以畫出一個梯形出來,然後填充顏色,這里為了達到相對較好的效果,使用了顏色漸變填充的方法;okey!直接看代碼吧~~!
//定義一個函數,封裝風車的底部基座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(); //要調用函數,才能在瀏覽器顯示
我們來看一下頁面中的效果,是不是很簡單?
(我感覺我話有點多哦~!~!)
3、繪製葉子接下來的部分將是這個動畫中最關鍵的地方,首先我們分析一下葉子的結構,三片葉子夾角為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)、最後就是一些基本的外觀樣式調試的啦!比如顏色漸變啊,透明度啊,之類的!
繪製葉子畫這個葉子形狀的時候我是慢慢調試的,我的審美相當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(); }4、設置動畫
動畫這部分就比較簡單了,設置定時器,清除畫布,調用函數;大功告成,打完收工! ! !
setInterval(function(){ ctx.clearRect(0,0,800,600); //每次執行代碼前,都要將畫布清空,不然畫出的圖形會滯留在畫布上; buttom(); //調用函數yezi( ); },50);
源碼:https://github.com/224137748/Canvas/blob/master/windmill.html
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。