开发者

<canvas> diamond/glass-like effect

I am working on a canvas animation, and one of the images is supposed to be a diamond.

Right now, I got as far as this:

ctx[0].beginPath();
ctx[0].moveTo(0,-80);
ctx[0].lineTo(-60,-130);
ctx[0].lineTo(-36,-160);
ctx[0].lineTo(36,-160);
ctx[0].lineTo(60,-130);
ctx[0].closePath();
ctx[0].fillStyle = "rgba(175,175,255,0.7)";
ctx[0].fill();

which draws a plain, light blue translucid diamond shape.

This is far too simple, but I'm having serious problems with the "color". I'm guessing something glass-like should do the trick, but I haven't found anything useful so far. I can add as many lines as needed, if it helps, but the color is my main problem.

This'll be pre-rendered, so long, complex code is not much of a problem. I'd rather not use images, 开发者_如何学Pythonthough.

To sum up: I need a glass-ish effect for canvas. Any ideas?


I think what you are looking for in glass (or, presumably, diamond) is that it is not entirely transparent or flat. Instead, it reflects its surroundings and very slightly distorts its background. You can give the appearance of a reflection by means of a radial gradient. The distortion, however, is trickier. You could move and scale every pixel behind the object, but that would be incredibly difficult to implement, not to mention grindingly slow. Alternatively, you could implement a very fine, rapidly shifting gradient, which would give the appearance of a distortion of the pixels underneath, even though none is actually taking place.

Here is an implementation of a pane of glass with reflection and distortion.

<html>
<canvas id="canvas" style="position:fixed;">
</canvas>
<script type="text/javascript">
    document.getElementById("canvas").height=window.innerHeight;
    document.getElementById("canvas").width=window.innerWidth;
    ctx=document.getElementById("canvas").getContext("2d");
    textWidth=ctx.measureText("Hello World! ");
    textWidth=Math.ceil(textWidth.width);
    ctx.lineWidth=3;
    targetWidth=Math.floor(window.innerWidth/textWidth)*textWidth;
    for(i=0;i<500;i++)
    {
        ctx.fillText("Hello World! ",((i*textWidth)%(targetWidth)),(16*Math.floor((i+1)*textWidth/window.innerWidth)+16));
    }
    var glass = ctx.createRadialGradient(80,110,0,100,140,100);
    for(i=0;i<=100;i++)
    {
        redComponent=Math.round(210-(i%11));
        greenComponent=Math.round(245-(i%7));
        blueComponent=Math.round(255-(i%5));
        opacity=Math.round(((i%3)+1)*Math.sin(i/200*Math.PI)*1000)/3000;
        glass.addColorStop(i/100,"rgba("+redComponent+","+greenComponent+","+blueComponent+","+opacity+")");
    }
    glass.addColorStop(1,"rgba(0,0,0,0)")
    ctx.fillStyle=glass;
    ctx.beginPath();
    ctx.translate(100,0);
    ctx.moveTo(100,100);
    ctx.lineTo(187,150);
    ctx.lineTo(137,237);
    ctx.lineTo(50,187);
    ctx.lineTo(100,100);
    ctx.closePath;
    ctx.fill();
    ctx.stroke();
</script>
</html>

And the result is:

<canvas> diamond/glass-like effect

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜