随着智能手机的普及和互联网前端的发展,对展现的内容样式的要求也趋于优雅过度。下面讲解一下使用canvas画一个简单的下图放大镜图标:
我们把canvas的绘图过程分为: 路径分析 -> 开发
路径分析
首先观察该放大镜图标是由(一个基本上完整的圆形 + 线条)组成,那么就可以由上图放大镜小腿左侧的缺口开始绘制,然后弧度不断变大,画到缺口右侧时开始绘制线性。
开发
canvas开发主要包含html和javascript,没有css。demo地址
html结构
在页面上定义canvas元素
<canvas id="canvas" width="19x" height="19px"></canvas>
javascript结构
要注意的是canvas本身并不能绘制图形,它只是图形的容器,实际需要调用javascript的API进行绘制图形。
canvas语法基础
getContext()
该方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性。
beginPath()
该方法开始一条路径,或重置当前的路径。
clearRect()
该方法清空给定矩形内的指定像素。
arc()
该方法创建弧/曲线。
注意弧度的计算。
lineTo()
该方法添加一个新点,然后创建从该点到画布中最后指定点的线条(该方法并不会创建线条)。
stroke()
该方法绘制已定义的路径。
完整javascript代码
var ctx = document.querySelector('#canvas').getContext('2d');
ctx.strokeStyle = '#f00';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.clearRect(0, 0, 19, 19);
ctx.arc(9, 9, 8, 0.37 * Math.PI, 2.27 * Math.PI, false);
ctx.lineTo(19, 19);
ctx.stroke();
动态绘制放大镜
如果你希望放大镜是线性画出来,需要计算绘制曲线的速度,变化arc的结束弧度和超过一定阈值时lineTo的结束坐标值。在这里,一定要注意控制目标值。
retina屏幕canvas绘制的图形模糊失真锯齿
关于devicePixelRatio,现有屏幕有1、1.5、2(iphone 5s)、2.5和3(iphone plus)。简单点讲就是css中的1px在dPR为2时,会被放大2倍,在dPR为3时,会被放大3倍。要知道canvas不是矢量的,放大会失真。
所以以上代码中绘制出的放大镜在retina屏幕中会失真,解决方案是把画布放大对应的dPR倍,把canvas的实际显示尺寸设置为实际尺寸。
上面的放大镜尺寸是57 * 57,开发移动端网页时,为了在devicePixelRatio = 3下显示不是真,图片显示尺寸是 (57 / 3)px。那么我们使用canvas绘制的时候,其实这个过程就类似于UE画设计稿的过程,FE开发过程类似于canvas的显示。
html结构
<canvas id="canvas2" width="19x" height="19px"></canvas>
javascript结构
var getPixelRatio = function(context) {
var backingStore = context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1;
return (window.devicePixelRatio || 1) / backingStore;
};
var retinaDraw = function () {
var canvasDomEle = document.querySelector('#canvas2');
var ctx2 = canvasDomEle.getContext('2d');
var ratio = getPixelRatio(ctx2);
console.log(ratio);
canvasDomEle.style.width = 19 + "px";
canvasDomEle.style.height = 19 + "px";
canvasDomEle.height = 19 * ratio;
canvasDomEle.width = 19 * ratio;
ctx2.strokeStyle = '#0f0';
ctx2.lineWidth = 1 * ratio;
ctx2.beginPath();
ctx2.clearRect(0, 0, 19 * ratio, 19 * ratio);
ctx2.arc(9 * ratio, 9 * ratio, 8 * ratio, 0.37 * Math.PI, 2.27 * Math.PI, false);
ctx2.lineTo(19 * ratio, 19 * ratio);
ctx2.stroke();
}
retinaDraw();
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。