12.11 HTML 画布阴影
所有人都喜欢好看的阴影效果,它们可能是Adobe Photoshop中使用最广泛的效果了,并且也经常在Web和图形设计中使用。如果操作正确,它们实际上确实能够增加图像真实感。然而,如果操作不当,它们也可能完全毁掉一个图像。
在画布中创建阴影效果是相对较简单的,它可以通过4个全局属性进行控制。这些属性是shadowBlur、shadowOffsetX、shadowOffsetY和shadowColor。我们马上开始逐一讲解这些属性。
默认情况下,2D渲染上下文是不会绘制阴影效果的,因为shadowBlur、shadowOffsetx和shadowOffsetY都设置为0,而shadowColor设置为透明黑色。
创建阴影效果的唯一方法是将shadowColor修改为不透明值,同时将shadowBlur、shadowOffsetX或shadowOffsetY都设置为非0值:
context.shadowBlur = 20; context.shadowColor = "rgb(0, 0, 0)"; context.fillRect(50, 50, 100, 100);
在这个例子中,给阴影设置了20像素的模糊值,并将它的颜色设置为完全不透明的黑色。阴影的偏移值在x轴和y轴方向仍然保持为默认值0。需要特别指出的是,即使使用了不透明的黑色,但由于采用了模糊效果,这个阴影在边界上仍然有些透明效果(参见图1)。
修改shadowBlur,shadowoffsetX或shadowOffsetY属性,就能够创建不同的阴影效果:
context.shadowBlur = 0; context.shadowOffsetX = 10; context.shadowOffsetY = 10; context.shadowColor = "rgba(100, 100, 100, 0.5)"; // Transparent grey context.fillRect(200, 50, 100, 100);
将模糊修改为0,创建清晰的阴影效果,而稍微向右下偏移,就得到一个不同的阴影效果。使用rgba颜色值将shadowColor设置为透明浅灰色,就能够实现更炫的效果(参见图2)。
画布的阴影支持所有图形,所以完全可以在所绘制的圆形或其他图形上创建阴影效果。甚至可以将颜色修改为任意奇特的值:
context.shadowColor = "rgb(255, 0, 0)"; // Red context.shadowBlur = 50; context.shadowOffsetX = 0; context.shadowOffsetY = 0; context.beginPath(); context.arc(400, 100, 50, 0, Math.PI*2, false); context.closePath(); context.fill();
这段代码会得到一个非常漂亮的圆形,它后面有一个鲜红色阴影效果(参见图3)。
通过组合使用各种模糊和颜色值,我们就能够实现一些与阴影完全无关的效果。例如,使用模糊黄色阴影在一个对象周围创建出光照效果,如太阳或发光体。
$(document).ready(function () { var canvas1 = $("#canvas1"); var context1 = canvas1.get(0).getContext("2d"); context1.shadowBlur = 20; context1.shadowColor = "rgb(0, 0, 0)"; context1.fillRect(50, 50, 100, 100); var canvas2 = $("#canvas2"); var context2 = canvas2.get(0).getContext("2d"); context2.shadowBlur = 0; context2.shadowOffsetX = 10; context2.shadowOffsetY = 10; context2.shadowColor = "rgba(100, 100, 100, 0.5)"; // Transparent grey context2.fillRect(200, 50, 100, 100); var canvas3 = $("#canvas3"); var context3 = canvas3.get(0).getContext("2d"); context3.shadowColor = "rgb(255, 0, 0)"; // Red context3.shadowBlur = 50; context3.shadowOffsetX = 0; context3.shadowOffsetY = 0; context3.beginPath(); context3.arc(400, 100, 50, 0, Math.PI*2, false); context3.closePath(); context3.fill(); });