有趣小研究:如何用canvas绘制一个链接元素?

最近在研究canvas多些,那么突发奇想,如何用canvas绘制一个链接呢?感觉比较有意思,就实现了一个初步版本,有兴趣的可以看看哦。

有趣小研究:如何用canvas绘制一个链接元素?

如何画一个和指定文字一样长的直线?

比如我们要绘制一个和“我是个链接哦”几个字一样长的细线,即便是我们用了measureText,但绘制出来的直线依然比文字短了一截,这原因很奇怪,不管绘制一个字还是多个字,和直线的差都是8px,于是只能在measureText.width的基础上+8px暂时解决这个问题。

如何画一个1px粗的直线?

画一个1px粗的线,我们第一时间会想到lineWidth属性,是没错但默认画出来是比较粗的,是因为在Canvas中整数坐标值对应的位置恰巧是屏幕象素点中间的夹缝,那么当按这样的坐标进行线条渲染时所要用到的就是夹缝两边的象素点,这样即便设置了lineWidth为1也将看到两个象素效果的线条,解决方法原象素点+0.5进行偏移。(ctx.translate(0.5, 0.5);)

如何响应链接的点击事件?

首先监听canvas元素的click事件,然后通过点击位置和链接的位置做匹配,如果匹配上则认为点击了链接,然后做相应的事情。

如何实现鼠标经过为链接变换颜色?

我们需要监听canvas的mousemove事件,然后通过鼠标位置和链接的位置做匹配,然后来实现换颜色,其实就是原地重新绘制。延迟300ms很重要,可以模拟a标签的效果,也会大大降低重绘请求数目。

下面就直接上代码吧

<canvas id="my-canvas" width="200" height="120" style="margin-left:10px; border:1px solid #ccc;"></canvas> <script src='http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js'></script> <script type="text/javascript"> var canvas = document.getElementById("my-canvas"); var ctx = canvas.getContext("2d"); ctx.font = "14px Arial"; function drawLink(ctx, text, link, target) { var currentColor = ""; function pureDraw(color, needLine) { console.log(color); ctx.clearRect(startX, 1, textWidth, endY+1); ctx.fillStyle = color; ctx.fillText(text, startX, startY); if(needLine) { ctx.strokeStyle = color; ctx.beginPath(); ctx.lineWidth = 1; ctx.translate(0.5, 0.5); ctx.moveTo(startX, endY); ctx.lineTo(textWidth, endY); ctx.stroke(); ctx.closePath(); ctx.translate(-0.5, -0.5); } } var startX = 10; var startY = 20; var lineHeight = 5; var endY = startY + lineHeight; var textWidth = ctx.measureText(text).width+8; pureDraw("blue"); var canvasOffset = $(canvas).offset(); var textX1 = canvasOffset.left + startX; var textX2 = textX1 + textWidth; var textY1 = canvasOffset.top + startY - lineHeight; var textY2 = textY1 + lineHeight; $(canvas).click(function(e) { if(e.clientX >= textX1 && e.clientX <= textX2 && e.clientY >= textY1 && e.clientY <= textY2) { window.open(link, target); } }); var canRender = true; $(canvas).mousemove(function(e) { if(!canRender) { return; } if(e.clientX >= textX1 && e.clientX <= textX2 && e.clientY >= textY1 && e.clientY <= textY2) { if(currentColor == "red") { return; } $(canvas).css("cursor", "pointer"); canRender = false; currentColor = "red"; setTimeout(function() {pureDraw("red", true);canRender = true;}, 150); } else { if(currentColor == "blue") { return; } $(canvas).css("cursor", "default"); canRender = false; currentColor = "blue"; setTimeout(function() {pureDraw("blue");canRender = true;}, 150); } }); } drawLink(ctx, "聪明你的旅行", "http://www.qunar.com", "_blank"); </script>

相关阅读