当前位置: 代码迷 >> 综合 >> 千呼万唤 HTML 5 (11) - 画布(canvas)之效果
  详细解决方案

千呼万唤 HTML 5 (11) - 画布(canvas)之效果

热度:70   发布时间:2024-01-10 14:52:07.0

原文地址:http://www.cnblogs.com/webabcd/archive/2012/02/27/2369452.html

作者: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
[源码下载]


  相关解决方案