導航:首頁 > 源碼編譯 > canvas運動演算法

canvas運動演算法

發布時間:2022-08-14 23:54:59

❶ 怎麼製作canvas沿路徑運動

剛好我這有點代碼: 我的圖片 // 設置繪圖環境 var myMap = document.getElementById("Map"); var cxt = myMap.getContext('2d'); // 設置圖像位置初始位置的變數 var x = 20; var y = 20; // 創建繪圖對象,並且畫出來 var img = new Image(); i...

❷ 如何用HTML5的Canvas製作3D動畫效果

HTML5的誕生給web前端界帶來了不小轟動,像什麼動畫旋轉、圖片滑塊、圖片輪播等等這些3D特效,也引發了不少朋友想要學習HTML5的好奇心。最近我一直在做canvas動畫效果,發現canvas這個東西做動畫不是不可以。相對於flash,它太底層。如果有給力的編輯器或者給力的框架的話,它就能發揮出更大的威力。

於是決定自己寫一個簡單一點的動畫框架,以便能更方便地構建出一些動畫效果。
我將分幾個章節來講述我這個小動畫框架的實現:
1.通用類的提取:動畫對象與幀對象
2.靈與肉的結合:便於拆卸的運動方程
3.進度條的實現:canvas的圖片預載入
4.demo測試:通過一個demo測試框架
這一節我們先來說說通用類的提取。
其實上一篇文章我已經用到了這種從flash借鑒來的思路:一個動畫對象(類似flash中的元件),一個幀對象(類似flash中的幀)。動畫就是在不斷在當前幀上繪制每個動畫對象來實現的。有了這兩個對象,再加上一些運動方法,我們就可以構建出動畫來。
首先我們先來看看動畫對象Aniele:
/*
*Aniele動畫對象
*所有動畫對象的始祖
*/
varAniele=function(){
this.img=newImage();
//定義動畫對象位置
this.loca={
x:300,
y:300
}
//定義動畫對象的大小(可以實現縮放)
this.dw;
this.dh;
//動畫對象的速度屬性
this.speed={
x:0,
y:0
}
//設置對象的透明度
this.alpha=1;
//設置圖像翻轉,1為不翻轉,-1為翻轉
this.scale={
x:1,
y:1
}
//定動畫對象的運動方法庫
this.motionFncs=[];
}
Aniele.prototype={
//添加運動方法
addMotionFnc:function(name,fnc) {
this.motionFncs[name]=fnc;
},
//刪除運動方法
deleMotionFnc:function(name){
this.motionFncs[name]=null;
},
//遍歷運動方法庫里的所有運動方法
countMotionFncs:function() {
for(vari=0; i
if(this.motionFncs[i]==null)
continue;
this.motionFncs[i].call(this);
}
},
//把自己繪制出來的方法,包括功能:水平翻轉
draw:function(canvas,ctx){
//存儲canvas狀態ctx.save();
//實現透明度的改變
ctx.globalAlpha=this.alpha;
//實現水平豎直翻轉,定義drawImage的兩個位置參數dx,dy
vardx=this.loca.x;
vardy=this.loca.y;
if(this.scale.x!=1||this.scale.y!=1){
if(this.scale.x<0){
console.log(this.img.width)
dx=canvas.width-this.loca.x-this.img.width;
ctx.translate(canvas.width,1);
ctx.scale(this.scale.x,1);
}
if(this.scale.y<0){
dy=canvas.height-this.loca.y-this.img.height;
ctx.translate(1,canvas.height);
ctx.scale(1,this.scale.y);
}
}
if(this.dw==null)
this.dw=this.img.width;
if(this.dh==null)
this.dh=this.img.height;
//畫出對象
ctx.drawImage(this.img,dx,dy,this.dw,this.dh);
//恢復canvas狀態ctx.restore();
}
}
動畫對象的主要屬性:
this.img=newImage();我們引入一張圖片,依附在動畫對象上;
this.loca.x等等;圖片的大小位置透明度等等,便於繪圖時調用;
this.motionFncs=[];這個比較關鍵,我們給動畫對象定義一個運動方法庫,把動畫對象的運動規則都放在這個運動方法庫中統一管理(每個動畫對象都有自己的運動方法庫);
動畫對象的主要方法:
addMotionFnc: 為動畫對象的運動方法庫中添加一個運動方法;
deleMotionFnc:為動畫對象的運動方法庫中刪除一個運動方法;
countMotionFncs:為動畫對象遍歷運動方法庫中的所有運動方法;
draw:把動畫對象畫在畫布上,這里我們會把畫布作為參數傳到這個方法裡面去,便於繪圖;
在draw方法里,我封裝了一些對圖像的簡單操作,這些操作在動畫中會經常用到:透明,縮放和翻轉。
有了這個,我們就好似獲得了flash里的一個元件,我們可以通過修改它的屬性來隨意改變它。
那麼幀對象呢?
幀對象肩負著渲染的任務,並且管理所有動畫對象:
/*
*Render渲染對象
*管理所有動畫對象和渲染
*參數:畫布對象,畫布上下文*/varRender=function(canvas,ctx) {
//引入畫布
this.canvas=canvas;
this.ctx=ctx;
//創建一個緩沖畫布
this.backBuffer=document.('canvas');
this.backBuffer.width=this.canvas.width;
this.backBuffer.height=this.canvas.height;
this.backBufferctx=this.backBuffer.getContext('2d');
//所有動畫對象
this.aniEles=[];
}
Render.prototype={
//初始化畫布int
int:function() {
clearInterval(this.sint);
this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);
this.backBufferctx.clearRect(0,0,this.backBuffer.width,this.backBuffer.height);
},
//設置開始渲染
begin:function() {
this.lastFrame=(newDate()).getTime();
this.sint=setInterval((function(progra){
returnfunction(){progra.render();}
})(this),SECOND);
},
//主渲染方法
render:function() {
//在畫布和緩存畫布上清除歷史幀
this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);
this.backBufferctx.clearRect(0,0,this.backBuffer.width,this.backBuffer.height);
//保存當前的實時輸出幀率this.ftp
this.nowFrame=(newDate()).getTime();
this.ftp=1000/(this.nowFrame-this.lastFrame);
this.lastFrame=this.nowFrame;
//調用每個動畫對象的運動方法
for(vari=0; i
if(this.aniEles[i]==null)
continue;
this.aniEles[i].countMotionFncs();
//把對象繪制到後台緩沖畫布上
this.aniEles[i].draw(this.backBuffer,this.backBufferctx);
}
//把後台對象繪制到前台
this.ctx.drawImage(this.backBuffer,0,0);
},
//增加動畫對象
addAniEle:function(name,aniEle) {
this.aniEles[name]=aniEle;
},
//刪除動畫對象
deleAniEle:function(name) {
this.aniEles[name]=null;
}
}
幀對象的主要屬性:
this.aniEles=[];用來存儲當前畫布上所有動畫實例的數組;
大家用過canvas載入圖片的應該知道,由於圖片的非同步載入,動畫過程中圖片會出現閃爍的現象,為了避免這種現象,我採用了雙緩沖。
首先後台創建一個畫布:
this.backBuffer=document.('canvas');
this.backBuffer.width=this.canvas.width;
this.backBuffer.height=this.canvas.height;
this.backBufferctx=this.backBuffer.getContext('2d');
我們所有繪制命令都執行在這個後台畫布上,最後把後台畫布畫在前台畫布上:
this.ctx.drawImage(this.backBuffer,0,0);
這種先把圖繪在後台畫布,再把後台畫布復制到前台的方法就叫做雙緩沖技術。
幀屬性的主要方法:
int:用於初始化畫布;
begin:開始動畫渲染的方法;
render:主渲染的方法;
addAniEle:為當前幀添加動畫對象;
deleAniEle:為當前幀刪除動畫;
我們利用幀對象的流程是:先為當前幀添加動畫對象,然後讓當前幀開始渲染。

河南新華電腦學院網路運營協會為您解答

❸ canvas相對於div+css3有什麼優勢一般的繪圖也可以用div+css3來實現,求解!

一般的繪圖當然是div+css3簡單一些。
canvas繪圖主要是做一些繁瑣的繪圖,可能裡面會有成千上萬個運動,但是電腦並不會卡頓。
canvas做游戲或者比較絢的動畫會有優勢,但是單獨的canvas交互方面可能沒有div+css3做的簡單。
所以做網頁的交互效果還是用css3,canvas只是做一些背景動圖和小游戲。

❹ 如何用Canvas繪制多種圖形

HTML5 的標准已經出來好久了,但是似乎其中的 Canvas 現在並沒有在太多的地方用到。一個很重要的原因是,Canvas 的標准還沒有完全確定,不適合大規模用在生產環境。但是,Canvas 的優點也是很明顯的,例如在繪制含有大量元素的圖表的時候,SVG 往往因為性能問題而無法勝任,例如我見過的一次技術分享會的抽獎環節,雖然效果比較炫,但因為每個頭像都是 DOM,利用 CSS3 控制的動畫,導致了性能非常低下。此外,隨著硬體性能的提高,視頻截圖、圖像處理等功能也逐漸可以在網頁上實現了,大多數網站用的是 Flash,但是 Flash 在 Mac 電腦上性能不高,還需要學一些額外的知識。Canvas 則是直接使用 JavaScript 來進行繪圖,對 Mac 友好,所以不失為 Flash 的一個繼承者。

使用 Canvas
說了這么多,Canvas 究竟是個啥?
英文中 Canvas 的意思是「畫布」,不過這里說的 Canvas 是 HTML5 中新出的一個元素,開發者可以在上面繪制一系列圖形。Canvas 在 HTML 文件中的寫法很簡單:
<canvas id="canvas" width="寬度" height="高度"></canvas>

其中 id 屬性是所有 HTML 元素都可以用的,Canvas 自帶的屬性只有後面兩個(分別控制寬度、高度),沒有其它的了。至於兼容性,CanIUse 上面寫了,基礎的功能目前用戶使用的 90% 的瀏覽器都支持,所以大部分情況下還是可以放心使用的。

注意,一定要使用 Canvas 自帶的 width 和 height 屬性,不要使用 CSS 來控制,因為 CSS 控制會導致 Canvas 變形。可以試著與 PhptpShop 對比一下,後者是改變「圖像大小」,前者才是正確的改變「畫布大小」。例如下圖是三張圖片的橫向拼接:最左邊的黑框中是大小為 50px * 50px 的原圖;中間是改變了圖像大小為 100px * 100px 的效果,圖像變得模糊,但是對於圖像本身來說坐標范圍並沒有變大;最右邊才是正確的 100px * 100px 的 Canvas。

Canvas 絕大部分的繪圖方法都與 <canvas> 標簽無關,需要使用 JavaScript 對其進行操作,這就是所謂的 Canvas API。
我們首先獲取到這個元素:
var canvas = document.getElementById('canvas');

然後通過一個方法來獲取可以調用一切 Canvas API 的入口:
var ctx = canvas.getContext('2d');

看到 2d 是不是很激動地聯想到有沒有 3d 呢?沒有 3d 的寫法,不過如果想要開啟 3D 世界的大門,則可以寫 canvas.getContext('webgl')。然而 WebGL 是基於 OpenGL ES 2.0 的一套標准,與本文是徹徹底底的兩條路,因此這里就不討論了。
Canvas 中的基本概念
坐標
與數學上常見的笛卡爾坐標系不太相同,Canvas 的坐標系是計算機中常見的坐標系,它長這樣:

畫布的最左上角是 (0,0),往右 x 增大,往下 y 增大,而且 x 和 y 都是整數(就算在計算過程中不是整數,在繪制的時候也會當作整數處理),單位是像素。
繪圖
帶大家懷舊一下。不知道有多少同學小時候玩過 logo 語言,在裡面你可以控制一隻小海龜在一塊板子上行走、畫畫、提筆、落筆。Canvas 中也一樣,你需要控制一隻畫筆的移動和繪制。然而 Canvas 更高級一些,你可以直接利用一些函數來畫圖,不用去控制那隻畫筆的位置。
Canvas 中的基本圖形
通過上文定義的 ctx 變數可以干許多有意思的事情,我們先看看如何繪制一些基本圖形。
線條
我們指定畫筆移動到某一點,然後告訴畫筆需要從當前這一點畫到另一點。我們可以讓畫筆多次移動、繪制,最後統一輸出到屏幕上。例子如下:
ctx.moveTo(10, 10);
ctx.lineTo(150, 50);
ctx.lineTo(10, 50);
ctx.moveTo(10, 20);
ctx.lineTo(40, 70);
ctx.stroke();

上面的代碼中,lineTo 是產生線條用的函數,執行完之後畫筆就移到了線條的終點。需要注意的是,線條此時並沒有顯示在屏幕上,必須調用 stroke 才會顯示。這樣設計是有道理的,因為向屏幕上輸出內容需要耗費大量的資源,我們完全可以先攢夠一波 lineTo,最後用 stroke 放一個大的。
路徑
繪制路徑非常簡單,只需要先告訴 ctx 一聲「我要開始畫路徑了」,然後通過各種方法(例如 lineTo)繪制路徑。如果需要畫一個封閉路徑,那就最後告訴 ctx一聲:「我畫完了,你把它封閉起來吧。」當然,不要忘記利用 stroke 輸出到屏幕上。
一個簡單的例子:
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(150, 50);
ctx.lineTo(10, 50);
ctx.closePath();
ctx.stroke();

如果我不想只描繪路徑線條,而是想填充整個路徑呢?可以將最後一行的 stroke 改成 fill,這樣就跟使用了畫圖中的油漆桶一樣,封閉路徑裡面的內容就都被填充上顏色了:
ctx.fill();

弧 / 圓形
繪制弧的函數參數比較多:
ctx.arc(圓心 x 坐標, 圓心 y 坐標, 半徑, 起始角度, 終止角度, 是否為逆時針);

注意,在 Canvas 的坐標系中,角的一邊是以圓心為中心的水平向右的直線。角度單位均為弧度。例如下圖,確定了圓心、起始角度(圖中標明的銳角)和終止角度(圖中標明的鈍角),方向為逆時針,於是就有了這么一個弧。如果方向為順時針,那麼就會是一個跟它互補的、非常非常大的弧……

所以如果轉了 2π 圈之後,弧就成了圓形,因此也可以使用繪制弧的方式來繪制圓形:
ctx.beginPath();
ctx.arc(圓心 x 坐標, 圓心 y 坐標, 半徑, 0, Math.PI * 2, true);
ctx.closePath();

最後一個參數隨便填(當然也可以不填),因為不管是順時針還是逆時針,轉了 2π 圈之後都是一個圓。
矩形
如果只是想繪制一個橫平豎直的矩形,可以使用下面的兩個方法:
// 只描邊
ctx.strokeRect(左上角 x 坐標, 左上角 y 坐標, 寬度, 高度);
// 只填充
ctx.fillRect(左上角 x 坐標, 左上角 y 坐標, 寬度, 高度);

線條樣式 / 填充樣式
之前繪制的所有圖形都是黑色的,但是 Canvas 肯定不止這么一種顏色(不然標準的制定者會被噴的很慘)。事實上,Canvas 可以單獨設置線條樣式和填充樣式,分別使用的是 strokeStyle 和 fillStyle。可能的值有三種:純色、漸變、圖像。既然線條樣式與填充樣式的使用方法相同,那麼下面統一以填充樣式為例。如果想設置線條樣式,直接將所有的 fillStyle改成 strokeStyle 即可,裡面的參數都不變。
/* 純色填充 */
// 普通的顏色
ctx.fillStyle = '#0000ff';
// 帶有透明度的顏色
ctx.fillStyle = 'rgba(64, 0, 127, 0.5)';

/* 漸變填充 */
// 設置漸變的尺寸(參數分別為起始點的 x 和 y、終止點的 x 和 y)
var gradient = ctx.createLinearGradient(0, 0, 170, 0);
// 設置過渡色,第一個參數是漸變的位置,第二個參數是顏色
gradient.addColorStop(0, 'magenta');
gradient.addColorStop(0.5, 'blue');
gradient.addColorStop(1.0, 'red');
// 設置填充樣式
ctx.fillStyle = gradient;

/* 圖片填充 */
// 創建圖片
var image = new Image;
image.src = '/path/to/image.png';
// 創建圖片筆觸,可以指定圖片的平鋪方式,這里是橫向平鋪
var pattern = ctx.createPattern(image, 'repeat-x');
// 設置筆觸填充
ctx.fillStyle = pattern;

關於漸變,除了代碼中提到的線性漸變以外,還有 createRadialGradient,也就是徑向漸變。
設置完填充樣式之後,就可以使用 fill 來填充啦!如果設置的是線條樣式,那麼就可以使用 stroke 來描邊。
當然,對於線條樣式,還有個額外的方法叫 lineWidth 可以用來控制線條的寬度。
文字
要想在畫布上畫文字,首先需要知道所使用的字體和字型大小:
ctx.font = '30px Verdana';

然後就可以通過 strokeText 或者 fillText 來對字體描邊或者填充字體。
ctx.strokeText("Hello Coding!", 23, 33);
ctx.fillText("Hello Coding!", 23, 66);

圖片
在 Canvas 中繪制圖片有三種方法:
// 指定繪制位置
ctx.drawImage(image, x, y);
// 指定繪制位置和圖像寬高
ctx.drawImage(image, x, y, width, height);
// 指定剪裁區域、繪制位置和圖像寬高
ctx.drawImage(image, sx, sy, swidth, sheight, x, y, width, height);

參數的含義依次如下:
image: 要使用的 Image、Canvas 或 Video
sx: 可選,開始剪切的 x 坐標
sy: 可選,開始剪切的 y 坐標
swidth: 可選,被剪切圖像的寬度
sheight: 可選,被剪切圖像的高度
x: 在畫布上放置圖像的 x 坐標
y: 在畫布上放置圖像的 y 坐標
width: 可選,要使用的圖像的寬度
height: 可選,要使用的圖像的高度

畫布設置
細心的同學可能會發現,剛才有些屬性是直接對 ctx 變數做設置,例如 ctx.lineWidth,只要設置了它,那麼後續畫出來的線條全都是這么個寬度。
其實,Canvas 的設置項還有許多,例如我們可以直接移動畫布、旋轉畫布、設置全局的繪制透明度等等。這些設置還可以隨時保存和恢復。
要注意的一點是,所有已經畫在畫布上的東西,是已經定死了的,不管之後再次進行任何設置都不會再改變。這個很像 Windows 下的畫圖程序。
廢話不多說,直接上代碼:
// 移動畫布,其實就是移動坐標系
ctx.translate(往右移動的量, 往下移動的量);
// 旋轉畫布,旋轉中心為坐標系原點
ctx.rotate(順時針旋轉的角度);
// 以坐標系原點為中心縮放畫布
ctx.scale(橫向放大倍數, 縱向放大倍數);
// 設置繪制透明度,如果 fillStyle 等屬性設置了透明度則會疊加
ctx.globalAlpha(零到一的小數);
// 設置全局組合操作
ctx.globalCompositeOperation = 'lighter';
// 保存當前設置
ctx.save();
// 恢復上次保存的設置
ctx.restore();

移動、旋轉、縮放其實就是在控制繪圖的坐標系,如果你在調用這三個方法的時候,腦子里時刻有一個帶刻度的坐標系,效果會非常好。
事實上,Canvas 的坐標變換遵循計算機圖形學的知識:變換矩陣。簡單來說,一個坐標可以看成是一個矩陣,坐標所對應的矩陣乘上變換矩陣就可以實現對坐標的變換。為了提升計算的效率,可以先計算出幾種變換復合之後的變換矩陣,然後直接通過 transform 函數對當前坐標系進行變換,或者通過 setTransform 函數將坐標系重置為初始狀態後再進行變換。至於變換矩陣的內容,對於本文來說就有些超綱了。
全局組合操作有點像 PhotoShop 裡面的「混合選項」,具體的實現方式還沒有完全確定,目前常見瀏覽器都統一了的實現方式有:source-over、source-atop、destination-over、destination-out、lighter、xor。具體的行為可以看 Mozilla 官方文檔,但是由於標准還未完全確定,因此其它瀏覽器不保證所有的行為都跟 Mozilla 的標准一致。一般來說,比較常見的是 source-over 和 lighter 兩種,這兩種的標准在瀏覽器界也算是無可爭議的。
至於保存和恢復設置就有點好玩了,首先需要了解一個叫「棧」的東西。
棧是一個一維數組,規定只能從一個方向操作。棧一開始是空的,我們可以從這個方嚮往數組 push 元素,也只能從這個方向把最後一個元素(棧頂元素)pop 出來,除此以外沒有任何多餘的操作。當然,pop 的次數不能多於 push 的次數,因為 pop 到棧底的時候棧里就已經沒有元素了,此時再 pop 是沒有意義的。棧的用處有很多,例如括弧匹配、表達式求值、深度優先搜索,甚至絕大部分語言的函數調用都要用到棧。
每次我們調用 save 函數,實際上是將當前的全局設置 push 到了一個專門棧上,每次調用 restore 函數的時候將最後一次保存的內容 pop 出來並用它覆蓋當前的全局設置,這樣棧頂就是最近一次保存的內容了。保存和恢復在某些情況下很好用,例如我需要畫一個歪著的圖形,然後繼續畫正著的圖形,這樣就可以先調用 save,然後調用 rotate,畫完圖形之後再 restore 回來,繼續畫其它的圖形。
其實 Canvas 還有許多方法,例如 toDataURL 直接將當前畫布上的內容轉換為十六進制的 data-url,getImageData直接將圖像轉換為 RGBA 數組以供圖像處理演算法使用,putImageData 將 RGBA 數組轉換為圖片顯示在畫布上等等。如果配上 JavaScript 的定時更新(最好用 requestAnimationFrame 而不是 setInterval),則可以產生動畫效果。網上還有許多 Canvas 的庫,可以讓程序員更簡便地基於 Canvas 編寫屬於自己的特效或功能。在這兒我想說一句話:大家的腦洞有多大,Canvas 的能力就有多強~

python tkinter怎麼用canvas實現按順序畫圖

python簡述:

Python是一種解釋型、面向對象、動態數據類型的高級程序設計語言。自從20世紀90年代初Python語言誕生至今,它逐漸被廣泛應用於處理系統管理任務和Web編程。Python[1]已經成為最受歡迎的程序設計語言之一。2011年1月,它被TIOBE編程語言排行榜評為2010年度語言。自從2004年以後,python的使用率是呈線性增長。

tkinter模塊介紹

tkinter模塊(「Tk 介面」)是Python的標准Tk GUI工具包的介面.Tk和Tkinter可以在大多數的Unix平台下使用,同樣可以應用在Windows和Macintosh系統里.,Tk8.0的後續版本可以實現本地窗口風格,並良好地運行在絕大多數平台中。

由於Tkinter是內置到python的安裝包中、只要安裝好Python之後就能import Tkinter庫、而且IDLE也是用Tkinter編寫而成、對於簡單的圖形界面Tkinter還是能應付自如。

八、顯示文字

用create_text在畫布上寫字。這個函數只需要兩個坐標(文字x和y的位置),還有一個具名參數來接受要顯示的文字。例如:

>>> from tkinter import*>>> tk = Tk()>>> canvas = Canvas(tk,width=400,height=400)>>> canvas.pack()>>> canvas.create_text(150,100,text='Happy birthday to you')

註:用tkinter只能裝入GIF圖片,也就是擴展名是.gif的圖片文件。

想要顯示其他類型的圖片,如PNG和JPG,需要用到其他的模塊,比如Python圖像庫。

十、創建基本的動畫

創建一個填了色的三角形,讓它在屏幕上橫向移動:

import timefrom tkinter import*tk = Tk()canvas = Canvas(tk,width=400,height=200)canvas.pack()canvas.create_polygon(10,10,10,60,50,35) ##創建三角形for x in range(0,60): canvas.move(1,5,0) ##把任意畫好的對象移動到把x和y坐標增加給定值的位置 tk.update() ##強制tkinter更新屏幕(重畫) time.sleep(0.05) ##讓程序休息二十分之一秒(0.05秒),然後再繼續

三角形橫向移動

延伸一下,如果想讓三角形沿對角線在屏幕上移動,我們可以第8行為:

import timefrom tkinter import*tk = Tk()canvas = Canvas(tk,width=400,height=400)canvas.pack()canvas.create_polygon(10,10,10,60,50,35) ##創建三角形for x in range(0,60): canvas.move(1,5,5) ##把任意畫好的對象移動到把x和y坐標增加給定值的位置 tk.update() ##強制tkinter更新屏幕(重畫) time.sleep(0.05) ##讓程序休息二十分之一秒(0.05秒),然後再繼續

三角形沿對角線移動

如果要讓三角形在屏幕上沿對角線回到開始的位置,要用-5,-5(在結尾處加上這段代碼)

import timefrom tkinter import*tk = Tk()canvas = Canvas(tk,width=400,height=400)canvas.pack()canvas.create_polygon(10,10,10,60,50,35) ##創建三角形for x in range(0,60): canvas.move(1,5,5) ##把任意畫好的對象移動到把x和y坐標增加給定值的位置 tk.update() ##強制tkinter更新屏幕(重畫) time.sleep(0.05) ##讓程序休息二十分之一秒(0.05秒),然後再繼續for x in range(0,60): canvas.move(1,-5,-5) tk.update() time.sleep(0.05)

對角線運動並回到初始位置

十一、讓對象對操作有反應

我們可以用「消息綁定」來讓三角形在有人按下某鍵時有反應。

要開始處理事件,我們首先要創建一個函數。當我們告訴tkinter將某個特定函數綁到(或關聯到)某個特定事件上時就完成了綁定。

換句話說,tkinter會自動調用這個函數來處理事件。

例如,要讓三角形在按下回車鍵時移動,我們可以定義這個函數:

def movetriangle(event): canvas.move(1,5,0)

這個函數只接受一個參數(event),tkinter用它來給函數傳遞關於事件的信息。現在我們用畫布canvas上的bind_all函數來告訴tkinter當特定事件發生時應該調用這個函數。代碼如下:

from tkinter import*tk = Tk()canvas = Canvas(tk,width=400,height=400)canvas.pack()canvas.create_polygon(10,10,10,60,50,35)def movetriangle(event): canvas.move(1,5,0)canvas.bind_all('<KeyPress-Return>',movetringle) ##讓tkinter監視KeyPress事件,當該事件發生時調用movetriangle函數

那麼我們如何根據按鍵的不同而改變三角形的方向呢?比如用方向鍵。

我們可以嘗試改下movetriangle函數:

def movetriangle(event): if event.keysym == 'up': canvas.move(1,0,-3) ##第一個參數使畫布上所畫的形狀的ID數字,第二個是對x(水平方向)坐標增加的值,第三個是對y(垂直方向)坐標增加的值 elif event.keysym == 'down': canvas.move(1,0,3) elif event.keysym == 'left': canvas.move(1,-3,0) else canvas.move(1,3,0)

最後代碼匯總在一起為:

from tkinter import*tk = Tk()canvas = Canvas(tk,width=400,height=400)canvas.pack()canvas.create_polygon(10,10,10,60,50,35)def movetriangle(event): if event.keysym == 'Up': canvas.move(1,0,-3) ##第一個參數使畫布上所畫的形狀的ID數字,第二個是對x(水平方向)坐標增加的值,第三個是對y(垂直方向)坐標增加的值 elif event.keysym == 'Down': canvas.move(1,0,3) elif event.keysym == 'Left': canvas.move(1,-3,0) else: canvas.move(1,3,0)canvas.bind_all('<KeyPress-Up>',movetriangle) ##讓tkinter監視KeyPress事件,當該事件發生時調用movetriangle函數canvas.bind_all('<KeyPress-Down>',movetriangle)canvas.bind_all('<KeyPress-Left>',movetriangle)canvas.bind_all('<KeyPress-Right>',movetriangle)

方向鍵控制三角形的移動

十二、更多使用ID的方法

只要用了畫布上面以create_開頭的函數,它總會返回一個ID。這個函數可以在其他的函數中使用。

如果我們修改代碼來把返回值作為一個變數保存,然後使用這個變數,那麼無論返回值是多少,這段代碼都能工作:

>>> mytriangle = canvas.create_polygon(10,10,10,60,50,35)>>> canvas.move(mytriangle,5,0)

我們可以用itemconfig來改變三角形的顏色,這需要把ID作為第一個參數:

>>> canvas.itemconfig(mytrigle,fill='bue') ##把ID為變數mytriangle中的值的對象的填充顏色改為藍色

也可以給三角形一條不同顏色的輪廓線,同樣適用ID作為第一個參數:

>>> canvas.itemconfig(mytrigle,outline='red')

總結做出了簡單的動畫。學會了如何用事件綁定來讓圖形響應按鍵,這在寫計算機游戲時很有用。在tkinter中以create開頭的函數是如何返回一個ID數字。

已經學習Python兩天,最開始是想著是通過覺得用它寫個動畫或者畫個圖形比較方便,而且界面美觀,比黑洞洞的dos窗口好多了,准備寫個程序送個一女孩作為生日禮物(去年答應好的)。經過這兩天的學習,我慢慢發覺了Python語言的優點,其最主要的就是易學,而且可以調用各種庫。

❻ HTML裡面怎樣用canvas將一個線性漸變正方形沿水平和垂直方向運動呀


❼ canvas前端動圖如何實現

Canvas是HTML5中的重要組成部分,用於繪制簡單的圖形,定義路徑,創建漸變及應用圖像變換,如何用Canvas製作動畫也是很多人都有的疑問。

01

什麼是動畫?我們在繪制動畫之前必須要弄清楚什麼是動畫,一個動畫最起碼需要哪些基本條件呢?我們可以用一個工具展示動畫是什麼。這是利用PPT繪制出的一個動畫效果

這樣我們就通過Canvas做出一個簡單的動態圖形了

如果你想要學習更多的新知識

如果你想要分享自己的心得

如果你熱愛前端渴望提升

閱讀全文

與canvas運動演算法相關的資料

熱點內容
UG編程如何多平面輪廓2D倒角 瀏覽:437
視頻壓縮漸變紋 瀏覽:851
什麼app能看財經新聞 瀏覽:39
數學奇跡神奇運演算法 瀏覽:359
大廠的程序員的水平如何 瀏覽:700
遺傳演算法入門經典書籍 瀏覽:878
源碼炮台腳本 瀏覽:620
在位編輯命令 瀏覽:347
曲式分析基礎教程pdf 瀏覽:15
php生成靜態html頁面 瀏覽:965
怎麼分割pdf 瀏覽:813
壓縮垃圾報警器 瀏覽:629
小公司一般都用什麼伺服器 瀏覽:968
java獲取時間gmt時間 瀏覽:821
為什麼csgo一直連接不到伺服器 瀏覽:504
安卓登ins需要什麼 瀏覽:836
機器人演算法的難點 瀏覽:226
全自動化編程 瀏覽:728
程序員高薪限制 瀏覽:693
壓縮圖片壓縮 瀏覽:76