JavaScript如何使用插值實現(xiàn)圖像漸變
描述由一個圖形變化為另一個圖形過程中的各個中間圖形,稱為漸變圖形??梢岳貌逯邓惴ㄇ蟮酶鱾€漸變圖形。
設在源圖形和目標圖形上各取M個對應坐標點,并分別保存到數組中,源圖形用數組SX[M]和SY[M]保存M個坐標點(sx,sy),目標圖形用數組DX[M]和DY[M]保存M個坐標點(dx,dy)。若需生成源圖形變換到目標圖形中的N-1個漸變圖形,采用簡單的線性插值可以編寫如下的二重循環(huán):
for (k=1;k<N;k++) for (i=0;i<M;i++) { x=(dx[i]-sx[i])/N*k+sx[i]; y=(dy[i]-sy[i])/N*k+sy[i]; // 按求得的插值坐標點繪制漸變圖形 }
1.六瓣花朵漸變?yōu)閳A
六瓣花朵的笛卡爾坐標方程式設定為:
t=r1*(1+sin(18*θ)/5) *(0.5+Math.sin(6*θ)/2);
x=t*cos(θ);
y=t* sin(θ); (0≤θ≤2π)
圓的笛卡爾坐標方程式為:
x=r*cos(θ)
y=r*sin(θ) (0≤θ≤2π)
在六瓣花朵和圓上分別取128個點,然后利用簡單的線性插值繪制中間24個漸變圖形。編寫如下的HTML代碼。
<!DOCTYPE html> <head> <title>六瓣花朵漸變?yōu)閳A</title> <script type="text/javascript"> function draw(id) { var canvas = document.getElementById( id); if (canvas == null) return false; var context = canvas.getContext('2d'); context.fillStyle = "#EEEEFF"; context.fillRect(0, 0, 200, 200); context.strokeStyle = "red"; context.lineWidth = 1; var dig = Math.PI / 64; var x1 = new Array(129); var y1 = new Array(129); var x2 = new Array(129); var y2 = new Array(129); for (var i = 0; i <= 128; i++) { d = 50 * (1 + Math.sin(18 * i * dig) / 5); t = d * (0.5 + Math.sin(6 * i * dig) / 2); x1[i] = t * Math.cos(i * dig); y1[i] = t * Math.sin(i * dig); x2[i] = 80 * Math.cos(i * dig); y2[i] = 80 * Math.sin(i * dig); } context.beginPath(); for (n = 0; n <= 25; n++) for (i = 0; i <= 128; i++) { x = (x2[i] - x1[i]) / 25 * n + x1[i] + 100; y = (y2[i] - y1[i]) / 25 * n + y1[i] + 100; if (i == 0) { context.moveTo(x, y); bx = x; by = y; } else context.lineTo(x, y); } context.lineTo(bx, by); context.closePath(); context.stroke(); } </script> </head> <body onload="draw('myCanvas');"> <canvas id="myCanvas" width="200" height="200"></canvas> </body> </html>
將上述HTML代碼保存到一個html文本文件中,再在瀏覽器中打開包含這段HTML代碼的html文件,可以看到在畫布中繪制出從六瓣花朵漸變?yōu)閳A的圖案,如圖1所示。
圖1 六瓣花朵漸變?yōu)閳A
2.圓漸變?yōu)榛ǘ?/strong>
我們將圖1圖形中的圓漸變?yōu)榱昊ǘ涞倪^程動態(tài)展示出來。編寫的HTML文件內容如下。
<!DOCTYPE> <html> <head> <title>圓漸變?yōu)榛ǘ?lt;/title> </head> <body> <canvas id="myCanvas" width="200" height="200" style="border:3px double #996633;"> </canvas> <script type="text/javascript"> var canvas = document.getElementById( 'myCanvas'); var context = canvas.getContext('2d'); context.fillStyle = "#EEEEFF"; context.fillRect(0, 0, 200, 200); context.fillStyle = "red"; var dig = Math.PI / 64; var x1 = new Array(129); var y1 = new Array(129); var x2 = new Array(129); var y2 = new Array(129); var n = 0; for (var i = 0; i <= 128; i++) { d = 50 * (1 + Math.sin(18 * i * dig) / 5); t = d * (0.5 + Math.sin(6 * i * dig) / 2); x1[i] = t * Math.cos(i * dig); y1[i] = t * Math.sin(i * dig); x2[i] = 80 * Math.cos(i * dig); y2[i] = 80 * Math.sin(i * dig); } function draw() { context.clearRect(0, 0, 200, 200); context.beginPath(); for (i = 0; i <= 128; i++) { x = (x1[i] - x2[i]) / 25 * n + x2[i] + 100; y = (y1[i] - y2[i]) / 25 * n + y2[i] + 100; if (i == 0) { context.moveTo(x, y); bx = x; by = y; } else context.lineTo(x, y); } context.lineTo(bx, by); context.stroke(); n = n + 1; if (n > 25) n = 0; context.fill(); } window.setInterval('draw()', 300); </script> </body> </html>
將上述HTML代碼保存到一個html文本文件中,再在瀏覽器中打開包含這段HTML代碼的html文件,可以在畫布中看到從圓漸變?yōu)榱昊ǘ涞膭赢嬤^程,如圖2所示。
圖2 從圓漸變?yōu)榱昊ǘ?/p>
3.六瓣花朵漸變?yōu)檎叫?/strong>
仿照上面的思路,設計程序將六瓣花朵漸變?yōu)檎叫?,且漸變計算時采用對數函數。編寫如下的HTML代碼。
<!DOCTYPE html> <head> <title>六瓣花朵漸變?yōu)檎叫?lt;/title> <script type="text/javascript"> function draw(id) { var canvas = document.getElementById( id); if (canvas == null) return false; var context = canvas.getContext('2d'); context.fillStyle = "#EEEEDD"; context.fillRect(0, 0, 300, 300); context.strokeStyle = "red"; context.lineWidth = 1; var dig = Math.PI / 60; var x1 = new Array(120); var y1 = new Array(120); var x2 = new Array(120); var y2 = new Array(120); // 生成花瓣基本數據,坐標保存在(x1[i],y1[i])中 var petalNum = 6; // 花瓣數 for (var i = 0; i < 120; i++) { d = 50 * (1 + Math.sin(petalNum * ( i * dig + Math.PI / 4))); x1[i] = d * Math.cos(i * dig + Math .PI / 4); y1[i] = -d * Math.sin(i * dig + Math.PI / 4); } // 生成多邊形基本數據,坐標保存在(x2[i],y2[i])中 var r = 150; var sideNum = 4; // 正多邊形邊數 var k = 120 / sideNum; dig = Math.PI / sideNum; var dd = 2 * r * Math.sin(dig) / k; for (i = 0; i < sideNum; i++) { aa = 2 * i * dig + 3 * Math.PI / 4; x0 = r * Math.sin(aa); y0 = r * Math.cos(aa); for (j = 0; j < k; j++) { x2[i * k + j] = x0 + j * dd * Math .sin(aa + Math.PI / 2 + Math.PI / sideNum); y2[i * k + j] = y0 + j * dd * Math .cos(aa + Math.PI / 2 + Math.PI / sideNum); } } context.beginPath(); // 按對數規(guī)律進行圖案漸變 for (n = 0; n <= 25; n++) { for (i = 0; i < 120; i++) { x = (x2[i] - x1[i]) / Math.log(25) * Math.log(n) + x1[i] + 150; y = (y2[i] - y1[i]) / Math.log(25) * Math.log(n) + y1[i] + 150; if (i == 0) { context.moveTo(x, y); bx = x; by = y; } else context.lineTo(x, y); } context.lineTo(bx, by); } context.closePath(); context.stroke(); } </script> </head> <body onload="draw('myCanvas');"> <canvas id="myCanvas" width="320" height="320"></canvas> </body> </html>
將上述HTML代碼保存到一個html文本文件中,再在瀏覽器中打開包含這段HTML代碼的html文件,可以看到在畫布中繪制出從六瓣花朵漸變?yōu)檎叫蔚膱D案,如圖3所示。
圖3 從六瓣花朵漸變?yōu)檎叫?/p>
將繪制圖3的HTML程序中的花瓣數設置為5,正多邊形邊數也設置為5,即修改語句“var petalNum=6;”為“var petalNum=5;”,修改語句“var sideNum=4;”為“var sideNum=5;”,則在畫布中繪制出如圖4所示的從五瓣花朵漸變?yōu)檎暹呅蔚膱D案。
圖4 從五瓣花朵漸變?yōu)檎暹呅?/p>
4.正五邊形漸變?yōu)槲灏昊ǘ?/strong>
我們將圖4圖形中的正五邊形漸變?yōu)槲灏昊ǘ涞倪^程動態(tài)展示出來。編寫的HTML文件內容如下。
<!DOCTYPE> <html> <head> <title>正五邊形漸變?yōu)槲灏昊ǘ?lt;/title> </head> <body> <canvas id="myCanvas" width="300" height="300" style="border:3px double #996633;"></canvas> <script type="text/javascript"> var canvas = document.getElementById( 'myCanvas'); var context = canvas.getContext('2d'); context.fillStyle = "#EEEEFF"; context.fillRect(0, 0, 300, 300); context.fillStyle = "red"; var dig = Math.PI / 60; var x1 = new Array(120); var y1 = new Array(120); var x2 = new Array(120); var y2 = new Array(120); // 生成花瓣基本數據,坐標保存在(x1[i],y1[i])中 var petalNum = 5; for (var i = 0; i < 120; i++) { d = 50 * (1 + Math.sin(petalNum * (i * dig + Math.PI / 4))); x1[i] = d * Math.cos(i * dig + Math.PI / 4); y1[i] = -d * Math.sin(i * dig + Math .PI / 4); } // 生成多邊形基本數據,坐標保存在(x2[i],y2[i])中 var r = 150; var sideNum = 5; var k = 120 / sideNum; dig = Math.PI / sideNum; var dd = 2 * r * Math.sin(dig) / k; for (i = 0; i < sideNum; i++) { aa = 2 * i * dig + 3 * Math.PI / 4; x0 = r * Math.sin(aa); y0 = r * Math.cos(aa); for (j = 0; j < k; j++) { x2[i * k + j] = x0 + j * dd * Math.sin( aa + Math.PI / 2 + Math.PI / sideNum); y2[i * k + j] = y0 + j * dd * Math.cos( aa + Math.PI / 2 + Math.PI / sideNum); } } var n = 0; function draw() { context.clearRect(0, 0, 300, 300); context.beginPath(); for (i = 0; i < 120; i++) { x = (x1[i] - x2[i]) / Math.log(25) * Math.log(n) + x2[i] + 150; y = (y1[i] - y2[i]) / Math.log(25) * Math.log(n) + y2[i] + 150; if (i == 0) { context.moveTo(x, y); bx = x; by = y; } else context.lineTo(x, y); } context.lineTo(bx, by); context.closePath(); context.stroke(); n = n + 1; if (n > 25) n = 0; context.fill(); } window.setInterval('draw()', 400); </script> </body> </html>
將上述HTML代碼保存到一個html文本文件中,再在瀏覽器中打開包含這段HTML代碼的html文件,可以在畫布中看到從正五邊形漸變?yōu)槲灏昊ǘ涞膭赢嬤^程,如圖5所示。
圖5 正五邊形漸變?yōu)槲灏昊ǘ?/p>
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
escape、encodeURI 和 encodeURIComponent 的區(qū)別
escape(), encodeURI()和encodeURIComponent()是在Javascript中用于編碼字符串的三個常用的方法,而他們之間的異同卻困擾了很多的Javascript初學者,今天我就在這里對這三個方法詳細地分析與比較一下。2009-03-03基于Bootstrap漂亮簡潔的CSS3價格表(附源碼下載)
該價格表基于Bootstrap網格系統(tǒng)來進行布局,通過簡單的CSS3代碼來美化價格表,樣式非常的時尚漂亮,且能在不同屏幕下展示良好的效果,需要的朋友可以參考下2017-02-02