作者:webabcd
介紹
HTML 5: 畫布(canvas)之效果
- 填充色, 筆划色, 顏色值 | fillStyle, strokeStyle
- 剪裁 | clip()
- 漸變色 | createLinearGradient(), createRadialGradient(), CanvasGradient.addColorStop()
- 貼圖的平鋪模式 | createPattern()
- 陰影效果 | shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor
- 全局 Alpha | globalAlpha
- 新顏色與畫布當前已有顏色的合成方式 | globalCompositeOperation
- 保存畫布上下文,以及恢復畫布上下文 | save(), restore()
- 像素操作 | createImageData(), getImageData(), putImageData(), ImageData, CanvasPixelArray
示例
1、填充色, 筆划色, 顏色值 | fillStyle, strokeStyle
canvas/effect/color.html
<!DOCTYPE HTML>
<html>
<head>
<title>填充色, 筆划色, 顏色值</title>
</head>
<body>
<canvas id="canvas" width="260" height="140" style="background-color: rgb(222, 222, 222)">
您的瀏覽器不支持 canvas 標簽
</canvas>
<br />
<button type="button" onclick="drawIt();">Demo</button>
<button type="button" onclick="clearIt();">清除畫布</button>
<script type="text/javascript">
var ctx = document.getElementById('canvas').getContext('2d');
function drawIt() {
clearIt();
/*
* context.fillStyle - 指定填充色的顏色值
*
* context.strokeStyle - 指定筆划色的顏色值
*
* 顏色值示例如下:
* Color Name - "green"
* #rgb - "#0f0"
* #rrggbb = "#00ff00"
* rgb(0-255, 0-255, 0-255) - rgb(0, 255, 0)
* rgb(0.0%-100.0%, 0.0%-100.0%, 0.0%-100.0%) - rgb(0%, 100%, 0%)
* rgba(0-255, 0-255, 0-255, 0.0-1.0) - rgb(0, 255, 0, 1)
* rgba(0.0%-100.0%, 0.0%-100.0%, 0.0%-100.0%, 0.0-1.0) - rgb(0%, 100%, 0%, 1)
*/
ctx.fillStyle = 'Red';
ctx.strokeStyle = 'Green';
ctx.lineWidth = 10;
// 看看 fillStyle 顏色的示例和 strokeStyle 顏色的示例,以及先 stroke 再 fill 和先 fill 再 stroke 的區別
ctx.beginPath();
ctx.rect(20, 20, 100, 100);
ctx.stroke();
ctx.fill();
ctx.beginPath();
ctx.rect(140, 20, 100, 100);
ctx.fill();
ctx.stroke();
}
function clearIt() {
ctx.clearRect(0, 0, 260, 140);
}
</script>
</body>
</html>
2、剪裁 | clip()
canvas/effect/clip.html
<!DOCTYPE HTML>
<html>
<head>
<title>剪裁</title>
</head>
<body>
<canvas id="canvas" width="512" height="512" style="background-color: rgb(222, 222, 222)">
您的瀏覽器不支持 canvas 標簽
</canvas>
<br />
<button type="button" onclick="drawIt();">Demo</button>
<button type="button" onclick="clearIt();">清除畫布</button>
<script type="text/javascript">
var ctx = document.getElementById('canvas').getContext('2d');
function drawIt() {
clearIt();
var img = new Image();
img.onload = function () {
ctx.drawImage(img, 0, 0, 512, 512);
}
img.src = "http://www.w3.org/html/logo/downloads/HTML5_Logo_512.png";
// img.src = "http://www.cnblogs.com/assets/html5_logo.png";
/*
* context.clip() - 只顯示當前路徑所包圍的剪切區域
*/
ctx.beginPath();
ctx.arc(256, 256, 100, 0, Math.PI * 2, true);
ctx.clip();
}
function clearIt() {
ctx.clearRect(0, 0, 512, 512);
}
</script>
</body>
</html>
3、漸變色 | createLinearGradient(), createRadialGradient(), CanvasGradient.addColorStop()
canvas/effect/gradient.html
<!DOCTYPE HTML>
<html>
<head>
<title>漸變色</title>
</head>
<body>
<canvas id="canvas" width="200" height="100" style="background-color: rgb(222, 222, 222)">
您的瀏覽器不支持 canvas 標簽
</canvas>
<br />
<button type="button" onclick="drawIt();">Demo</button>
<button type="button" onclick="clearIt();">清除畫布</button>
<script type="text/javascript">
var ctx = document.getElementById('canvas').getContext('2d');
function drawIt() {
clearIt();
/*
* context.createLinearGradient(xStart, yStart, xEnd, yEnd) - 創建線性漸變對象,並返回 CanvasGradient 類型的對象
* xStart, yStart - 線性漸變對象的起始點坐標
* xEnd, yEnd - 線性漸變對象的結束點坐標
*
* CanvasGradient.addColorStop(offset, color) - 新增一個漸變參考點
* offset - 漸變參考點的位置,0.0 - 1.0 之間。起始點為 0,結束點為 1
* color - 漸變參考點的顏色值
*/
var linearGradient = ctx.createLinearGradient(50, 0, 50, 100);
linearGradient.addColorStop(0, "red");
linearGradient.addColorStop(0.5, "green");
linearGradient.addColorStop(1, "blue");
ctx.beginPath();
ctx.arc(50, 50, 50, 0, 2 * Math.PI, true);
ctx.fillStyle = linearGradient;
ctx.fill();
/*
* context.createRadialGradient(xStart, yStart, radiusStart, xEnd, yEnd, radiusEnd) - 創建放射性漸變對象,並返回 CanvasGradient
* xStart, yStart - 放射性漸變對象的開始圓的圓心坐標
* radiusStart - 開始圓的半徑
* xEnd, yEnd - 放射性漸變對象的結束圓的圓心坐標
* radiusEnd - 結束圓的半徑
*/
var radialGradient = ctx.createRadialGradient(150, 50, 0, 150, 50, 50);
radialGradient.addColorStop(0, "red");
radialGradient.addColorStop(0.5, "green");
radialGradient.addColorStop(1, "blue");
ctx.beginPath();
ctx.arc(150, 50, 50, 0, 2 * Math.PI, true);
ctx.fillStyle = radialGradient;
ctx.fill();
}
function clearIt() {
ctx.clearRect(0, 0, 200, 100);
}
</script>
</body>
</html>
4、貼圖的平鋪模式 | createPattern()
canvas/effect/pattern.html
<!DOCTYPE HTML>
<html>
<head>
<title>貼圖的平鋪模式</title>
</head>
<body>
<canvas id="canvas" width="620" height="620" style="background-color: rgb(222, 222, 222)">
您的瀏覽器不支持 canvas 標簽
</canvas>
<br />
<button type="button" onclick="drawIt();">Demo</button>
<button type="button" onclick="clearIt();">清除畫布</button>
<script type="text/javascript">
var ctx = document.getElementById('canvas').getContext('2d');
function drawIt() {
clearIt();
var img = new Image();
img.onload = function () {
/*
* context.createPattern(image, repetitionStyle) - 指定貼圖的平鋪模式
* image - 圖像對象。除了支持 HTMLImageElement 外,還支持 HTMLCanvasElement 和 HTMLVideoElement
* repetitionStyle - 平鋪模式(無論任何平鋪模式,首圖均在畫布的左上角)
* no-repeat - 不平鋪,只貼圖一次,當然也是在畫布的左上角
* repeat-x - x 軸方向上平鋪圖片
* repeat-y - y 軸方向上平鋪圖片
* repeat - x 軸和 y 軸方向均平鋪圖片
*/
var pattern = ctx.createPattern(img, "no-repeat");
ctx.fillStyle = pattern;
ctx.strokeStyle = "blue";
ctx.beginPath();
ctx.rect(0, 0, 300, 300);
ctx.fill();
ctx.stroke();
pattern = ctx.createPattern(img, "repeat-x");
ctx.fillStyle = pattern;
ctx.strokeStyle = "blue";
ctx.beginPath();
ctx.rect(320, 0, 300, 300);
ctx.fill();
ctx.stroke();
pattern = ctx.createPattern(img, "repeat-y");
ctx.fillStyle = pattern;
ctx.strokeStyle = "blue";
ctx.beginPath();
ctx.rect(0, 320, 300, 300);
ctx.fill();
ctx.stroke();
pattern = ctx.createPattern(img, "repeat");
ctx.fillStyle = pattern;
ctx.strokeStyle = "blue";
ctx.beginPath();
ctx.rect(320, 320, 300, 300);
ctx.fill();
ctx.stroke();
}
img.src = "http://res2.windows.microsoft.com/resbox/en/Windows%207/main/4300ae64-546c-4bbe-9026-6779b3684fb9_0.png";
// img.src = "http://www.cnblogs.com/assets/windows_logo.png";
}
function clearIt() {
ctx.clearRect(0, 0, 620, 620);
}
</script>
</body>
</html>
5、陰影效果 | shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor
canvas/effect/shadow.html
<!DOCTYPE HTML>
<html>
<head>
<title>陰影效果</title>
</head>
<body>
<canvas id="canvas" width="480" height="480" style="background-color: rgb(222, 222, 222)">
您的瀏覽器不支持 canvas 標簽
</canvas>
<br />
<button type="button" onclick="drawIt();">Demo</button>
<button type="button" onclick="clearIt();">清除畫布</button>
<script type="text/javascript">
var ctx = document.getElementById('canvas').getContext('2d');
function drawIt() {
clearIt();
/*
* context.shadowOffsetX - 陰影相對於實體的水平偏移值
* context.shadowOffsetY - 陰影相對於實體的垂直偏移值
* context.shadowBlur - 陰影模糊程度。默認值是 0 ,即不模糊
* context.shadowColor - 陰影的顏色
*/
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 10;
ctx.shadowBlur = 10;
ctx.shadowColor = "rgba(0, 0, 255, 0.5)";
ctx.beginPath();
ctx.arc(120, 120, 100, 0, Math.PI * 2, true);
ctx.stroke();
ctx.fillRect(300, 300, 100, 100);
}
function clearIt() {
ctx.clearRect(0, 0, 480, 480);
}
</script>
</body>
</html>
6、全局 Alpha | globalAlpha
canvas/effect/globalAlpha.html
<!DOCTYPE HTML>
<html>
<head>
<title>全局 Alpha</title>
</head>
<body>
<canvas id="canvas" width="140" height="140" style="background-color: rgb(222, 222, 222)">
您的瀏覽器不支持 canvas 標簽
</canvas>
<br />
<button type="button" onclick="drawIt();">Demo</button>
<button type="button" onclick="clearIt();">清除畫布</button>
<script type="text/javascript">
var ctx = document.getElementById('canvas').getContext('2d');
function drawIt() {
clearIt();
/*
* context.globalAlpha - 設置全局的 alpha 值
*/
ctx.globalAlpha = "0.5";
ctx.fillStyle = "red";
ctx.beginPath();
ctx.rect(20, 20, 100, 100);
ctx.fill();
}
function clearIt() {
ctx.clearRect(0, 0, 140, 140);
}
</script>
</body>
</html>
7、新顏色與畫布當前已有顏色的合成方式 | globalCompositeOperation
canvas/effect/globalCompositeOperation.html
<!DOCTYPE HTML>
<html>
<head>
<title>新顏色與畫布當前已有顏色的合成方式</title>
</head>
<body>
<div id="msg"></div>
<canvas id="canvas" width="200" height="200" style="background-color: rgb(222, 222, 222)">
您的瀏覽器不支持 canvas 標簽
</canvas>
<br />
<button type="button" onclick="drawIt();">改變 globalCompositeOperation</button>
<button type="button" onclick="clearIt();">清除畫布</button>
<script type="text/javascript">
var ctx = document.getElementById('canvas').getContext('2d');
var compositeOperationTypes = ['source-atop', 'source-in', 'source-out', 'source-over', 'destination-atop', 'destination-in', 'destination-out', 'destination-over', 'lighter', 'copy', 'xor'];
var index = 0;
function drawIt() {
clearIt();
ctx.fillStyle = "red";
ctx.beginPath();
ctx.rect(20, 20, 100, 100);
ctx.fill();
/*
* context.globalCompositeOperation - 設置新顏色與畫布當前已有顏色的合成方式
* source-atop - 保留已有顏色,然后繪制新顏色與已有顏色重合的部分
* source-in - 繪制新顏色與已有顏色重合的部分,其余全透明
* source-out - 繪制新顏色與已有顏色不重合的部分,其余全透明
* source-over - 在已有顏色的前面繪制新顏色。默認值
* destination-atop - 在已有顏色的后面繪制新顏色,然后保留已有顏色與新顏色重合的部分
* destination-in - 保留已有顏色與新顏色重合的部分,其余全透明
* destination-out - 保留已有顏色與新顏色不重合的部分,其余全透明
* destination-over - 在已有顏色的后面繪制新顏色
* lighter - 混合重疊部分的顏色
* copy - 刪除已有顏色,只繪制新顏色
* xor - 透明化重疊部分的顏色
*/
ctx.globalCompositeOperation = compositeOperationTypes[index];
document.getElementById("msg").innerHTML = ctx.globalCompositeOperation;
ctx.fillStyle = "blue";
ctx.beginPath();
ctx.rect(80, 80, 100, 100);
ctx.fill();
index++;
if (index >= compositeOperationTypes.length)
index = 0;
}
function clearIt() {
ctx.clearRect(0, 0, 200, 200);
// source-over 是 context.globalCompositeOperation 的默認值
ctx.globalCompositeOperation = "source-over";
}
</script>
</body>
</html>
8、保存畫布上下文,以及恢復畫布上下文 | save(), restore()
canvas/effect/save_restore.html
<!DOCTYPE HTML>
<html>
<head>
<title>保存畫布上下文,以及恢復畫布上下文</title>
</head>
<body>
<div>單擊“save and draw”一次,然后單擊“restore and draw”三次</div>
<canvas id="canvas" width="280" height="140" style="background-color: rgb(222, 222, 222)">
您的瀏覽器不支持 canvas 標簽
</canvas>
<br />
<button type="button" onclick="drawIt();">save and draw</button>
<button type="button" onclick="restoreIt();">restore and draw</button>
<script type="text/javascript">
var ctx = document.getElementById('canvas').getContext('2d');
/*
* save() - 將畫布的上下文壓入堆棧
* restore() - 從堆棧中取一個畫布的上下文,如果沒有則什么都不做
*/
function drawIt() {
clearIt();
ctx.strokeStyle = "red";
ctx.fillStyle = "green";
ctx.lineWidth = 5;
ctx.save(); // 將畫布的上下文壓入堆棧,此時堆棧中有一個畫布上下文
drawRect1();
ctx.strokeStyle = "blue";
ctx.fillStyle = "yellow";
ctx.lineWidth = 10;
ctx.save(); // 將畫布的上下文壓入堆棧,此時堆棧中有兩個畫布上下文
drawRect2();
}
function restoreIt() {
clearIt();
ctx.restore(); // 按后進先出的順序從堆棧里取畫布上下文,如果取不到則什么都不做
drawRect1();
drawRect2();
}
function drawRect1() {
ctx.beginPath();
ctx.rect(20, 20, 100, 100);
ctx.stroke();
ctx.fill();
}
function drawRect2() {
ctx.beginPath();
ctx.rect(140, 20, 100, 100);
ctx.stroke();
ctx.fill();
}
function clearIt() {
ctx.clearRect(0, 0, 280, 140);
ctx.strokeStyle = "black";
ctx.fillStyle = "black";
ctx.lineWidth = 1;
}
</script>
</body>
</html>
9、像素操作 | createImageData(), getImageData(), putImageData(), ImageData, CanvasPixelArray
canvas/effect/imageData.html
<!DOCTYPE HTML>
<html>
<head>
<title>像素操作</title>
</head>
<body>
<div id="msg"></div>
<canvas id="canvas" width="300" height="300" style="background-color: black">
您的瀏覽器不支持 canvas 標簽
</canvas>
<br />
<button type="button" onclick="drawIt();">Demo</button>
<button type="button" onclick="clearIt();">清除畫布</button>
<br /><br />
<canvas id="canvas2" width="300" height="300" style="background-color: black">
您的瀏覽器不支持 canvas 標簽
</canvas>
<br />
<button type="button" onclick="syncIt();">同步第一個Demo</button>
<button type="button" onclick="redIt();">變紅</button>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
var canvas2 = document.getElementById('canvas2');
var ctx = canvas.getContext('2d');
var ctx2 = canvas2.getContext('2d');
var timer = -1;
var width = parseInt(canvas.width, 10);
var height = parseInt(canvas.height, 10);
function drawIt() {
clearIt();
/*
* context.createImageData(width, height) - 按指定的寬和高創建並返回 ImageData 對象,其內所有像素的默認值為 rgba(0,0,0,0)
*
* context.createImageData(imageData) - 按指定的 ImageData 對象的寬和高創建一個新的 ImageData 對象並返回此對象,其內所有像素的默認值為 rgba(0,0,0,0)
* 相當於 context.createImageData(imageData.width, imageData.height)
*
* context.getImageData(x, y, width, height) - 獲取畫布的指定范圍內的 ImageData 對象,並返回此對象
* x - 需要獲取的 ImageData 對象矩形框相對於畫布的左上角的 x 坐標
* y - 需要獲取的 ImageData 對象矩形框相對於畫布的左上角的 y 坐標
* width - 需要獲取的 ImageData 對象矩形框的寬
* height - 需要獲取的 ImageData 對象矩形框的高
*
* putImageData(imagedata, x, y, [dirtyX, dirtyY, dirtyWidth, dirtyHeight]) - 在畫布上寫入指定的數據
* imagedata - 需要寫入的 ImageData 對象
* x, y - 指定需要寫入的 ImageData 對象矩形框相對於畫布左上角的坐標
* [dirtyX, dirtyY, dirtyWidth, dirtyHeight] - 顯示 ImageData 對象上指定范圍內像素
*/
/*
* ImageData - 像素對象
* width - 像素對象的寬
* height - 像素對象的高
* data - 像素數據,CanvasPixelArray 類型的對象
*
* CanvasPixelArray - 像素數據對象,可以數組方式進行操作
* 數組中每 4 個元素代表一個像素,每個元素為一個字節,4 個元素按照 rgba 的方式描述一個像素
* length - 元素總數,即像素總數 * 4
*/
var imageData = ctx.createImageData(width, height);
document.getElementById("msg").innerHTML = "CanvasPixelArray.length: " + imageData.data.length;
// 隨機生成顏色不一樣的像素,並寫入到畫布上
timer = setInterval(randomPixel, 1);
function randomPixel() {
var x = parseInt(Math.random() * width, 10);
var y = parseInt(Math.random() * height, 10);
var index = (y * width + x) * 4;
imageData.data[index + 0] = parseInt(Math.random() * 256);
imageData.data[index + 1] = parseInt(Math.random() * 256);
imageData.data[index + 2] = parseInt(Math.random() * 256);
imageData.data[index + 3] = parseInt(Math.random() * 256);
ctx.putImageData(imageData, 50, 50, 0, 0, 200, 200);
}
}
function clearIt() {
clearInterval(timer);
ctx.clearRect(0, 0, width, height);
}
// 將 canvas 上的像素數據復制到 canvas2 上
function syncIt() {
var imageData = ctx.getImageData(0, 0, width, height);
ctx2.putImageData(imageData, 0, 0);
}
// 將 canvas2 上的非 rgba(0,0,0,0) 的點都變成紅色
function redIt() {
var imageData = ctx2.getImageData(0, 0, width, height);
for (var i = 1; i < imageData.data.length / 4; i++) {
var index = i * 4;
if (imageData.data[index + 0] + imageData.data[index + 1] + imageData.data[index + 2] + imageData.data[index + 3] > 0) {
imageData.data[index + 0] = 255;
imageData.data[index + 1] = 0;
imageData.data[index + 2] = 0;
imageData.data[index + 3] = 255;
}
}
ctx2.putImageData(imageData, 0, 0);
}
</script>
</body>
</html>
OK
[源碼下載]