H5中canvas的坐标系(画布初始)
2017-04-16 23:50

canvas画布的坐标系

canvas画布是通过HTML的标签<canvas>嵌入到web页面中的,它支持通过CSS结构来设置canvas的一些样式。比如通过style来设置canvas的width,height。这个设置的画布的表象,同时canvas标签还有两个属性width,height,这个用来设置canvas的坐标系的大小。

看了这个不明白?

好吧,我觉得用语言说也说不太明白,还得配合代码例子才能讲明白。

html,body{
    height:100%;
    overflow: hidden;
}
body{
    margin:0;
    padding:0;
}
.stage{
    width:100%;
    height:100%;
    box-sizing:border-box;
    border:1px solid #e74c3c;
}
<canvas class="stage" id="mystage" width="200" height="200">

</canvas>
<script>
    var cvs=document.getElementById("mystage");
    var ctx=cvs.getContext("2d");
    console.log(cvs.width);
    console.log(cvs.height);
    ctx.moveTo(0,0);
    ctx.lineTo(200,200);
    ctx.strokeStyle="#2A35A4";
    ctx.strokeWidth="5px";
    ctx.lineCap="round";
    ctx.stroke();
</script>

这段代码中canvas标签有一个class样式stage,stage结合body的css样式,目的是设置画布的大小和浏览器窗口一样大。通过这些设置,canvas听话的达到了和浏览器一样的大小。然后canvas标签的属性上width,height的大小是200,200。注意这里是没有单位的。当然你设置单位也一样,比如“px”,"em",但他们的效果跟没有单位的纯数值是一样的。这里的单位跟svg的坐标系一样,属于相对单位。看到这里你应该若有所思,那么canvas虽然看上去的大小是跟浏览器窗口一样大的,可他的坐标系的大小只有200*200的大小。那么我们moveTo(0,0) ,lineTo(200,200)所画的这条直线应该是从左上角到右下角。结果也是这样。

代码运行结果如下:

blob.png

写了个Demo:canvas坐标系示例。你应该在demo中通过改变浏览器的大小来观察,canvas画布的大小是跟随浏览器的宽度进行变化的一个矩形。但是canvas的坐标系的大小却始终是200*200。

这里我们就应该理解canvas的坐标系是的单位是相对单位,并且canvas的坐标系的刻度是通过类似scale缩放的方式映射到实际的我们通过style设置的大小。

canvas的width,height可以不设置,不设置的时候默认大小是宽300,高150的坐标系。

上面我们画的斜线不能反映画布坐标系和展现的缩放效果,我们在上面的代码中绘制一个圆形,来体现其坐标系和渲染的canvas舞台的缩放关系。

<script>
    var cvs=document.getElementById("mystage");
    var ctx=cvs.getContext("2d");
    console.log(cvs.width);
    console.log(cvs.height);
    ctx.moveTo(0,0);
    ctx.lineTo(200,200);
    ctx.strokeStyle="#2A35A4";
    ctx.strokeWidth="5px";
    ctx.lineCap="round";
    ctx.stroke();
    ctx.closePath();
    ctx.beginPath();
    ctx.strokeStyle="#D15815";
    ctx.arc(100,100,50,0,360);
    ctx.stroke();
</script>

我们在代码中添加了一个圆形的绘制。注意其中的closePath,beginPath的使用,是为了结束上一个斜线的stroke路径的结束,然后开始下一个圆形stroke的绘制。如果不加这两个路径的操作,圆形和斜线的颜色会变成一样,并且圆形会和斜线的结束或开始多出一条直线相连接。

因为我们设置的canvas的坐标系是200*200的大小,所以如果canvas的css设置的舞台的大小也是一个正方形,那么他它应该是一个正圆,而如果canvas的舞台大小是一个长方形,那么这个通过arc绘制的圆形会变成以一个椭圆。

正如我们所料,结果如下:

blob.png

我们把浏览器缩放成一个长方形,圆形变成了一个椭圆。这也说明了canvas的坐标系和舞台之间的scale缩放映射关系。

canvas的坐标系跟svg的坐标的原理是一样的,svg是通过svg 的preserveAspectRatio和viewBox来实现坐标系和舞台的缩放映射的。当然,我承认,svg的缩放貌似更高级点,因为它有选择是变形缩放还是保持宽高比的选项。canvas只有变形缩放这一个缩放方式。

说道这里,我们想起了微信小程序里面的canvas标签,微信小程序的canvas没有设置width,height属性的功能,JS的api也没有提供这个功能,它貌似把坐标系和舞台设置同一个坐标了,并且微信小程序里面无法操作“DOM”元素,通过类似“getBoundingClientRect”的方式获取元素宽高,所以在微信小程序里面绘图,只能设置canvas的大小为固定的宽高,比如“300*150”,并且这个宽高就是坐标系和舞台的大小。没有坐标系和舞台的缩放映射关系,我们没有办法让微信小程序里面的canvas的渲染大小自适应手机的大小。这个问题相比困扰着很多想要在微信小程序里面实现图表绘制功能的开发人员。不知道微信什么时候能够对这个问题作出处理或提供解决方案,且翘首以待。

原创文章,转载请注明来自:妹纸前端-www.webfront-js.com.
阅读(6465)
辛苦了,打赏喝个咖啡
微信
支付宝
妹纸前端
妹纸前端工作室 | 文章不断更新中
京ICP备16005385号-1