canvas元素大小与绘图表面大小

本文转载:https://www.cnblogs.com/v-rockyli/p/3822327.html
注:在使用canvas绘图的时候,设置canvas的宽高的方式不同,会使得canvas图片显示不全或画出的线条粗细不正确。

前言

我们使用canvas的时候一般在canvas元素中直接设置它的width和height:

<canvas id="myCanvas" width="300" height="150">browser don't support canvas</canvas>

当然,也可以不在canvas中进行设置,直接在css样式中设置,因为canvas本身也是一个html节点。

canvas{width:600px;height:300px}

设置以后,打开页面,发现canvas画布展示大小也ok,这个时候,我们在上面画一个40*40矩形,看下效果。

var canvas = document.getElementById('canvas'),
    context = canvas.getContext('2d');
    
context.fillStyle = 'cornflowerblue';
context.fillRect(0, 0, 40, 40);

运行页面,展示如下:
在这里插入图片描述
canvas大小为600px,高为300px,没有任何问题,符合预期。但是矩形…这显然不是4040好吧,这是8080

为什么会发生这种情况呢?

canvas的元素大小与绘图表面的大小

canvas的大小分为两种,一个是canvas作为html元素本身的尺寸,另外一个canvas作为绘图容器的绘图表面大小。

在canvas元素中设置宽高,同时指定了canvas的元素尺寸以及绘图表面的尺寸,两者相等,绘图不会有任何问题

但如果使用css设置canvas高宽,其实只是指定了canvas的元素尺寸,而不会影响canvas的绘图表面的尺寸,如果两者尺寸是一致的,并不会产生什么问题,但如果不一致,就会出现各种奇怪的问题,这个时候浏览器会有自动缩放的机制,对绘图表面进行缩放,使之适应canvas元素的尺寸。

看我们前面的例子,canvas元素以及绘图表面的尺寸是300150,但css中设置了canvas元素尺寸是600300,实际矩形的绘制是在300*150的绘图表面中进行绘制的,绘制完成以后要显示在canvas元素中,需要进行缩放,故产生了图形变化的问题。

在前面的例子我们打印一下日志:

var box = canvas.getBoundingClientRect(); //canvas元素的边界框
console.log(canvas.width + "---" + canvas.height) //300-150
console.log(box.width + "---" + box.height); //600-300

其中canvas对象获取的其实是绘图表面大小,box获取的是canvas元素的大小。
那缩放的规则是什么?
我们用几个例子来看一下

  1. css中设置canvas元素600300,绘图表面300100,画矩形4040。
    在这里插入图片描述
    实际矩形80
    120。
    宽度是预期的两倍,高度是预期3倍。

  2. Css中设置canvas元素600300,绘图表面200150,画矩形4040。
    在这里插入图片描述
    实际矩形120
    80
    宽度是预期的3倍,高度是预期的2倍

  3. Css中设置canvas元素600300,绘图表面1200900,画矩形6060。
    在这里插入图片描述
    实际矩形30
    20
    宽度是预期的1/2,高度是预期的1/3

  4. Css中设置canvas元素600300,绘图表面1800600,画矩形6060。
    在这里插入图片描述
    实际矩形20
    30
    宽度是预期的1/3,高度是预期的1/2
    我们用element表示canvas元素,用canvas表示绘图表面,src表示绘制的内容,dest表示展示的内容,缩放规则为:dest.size = src.size * (element.size / canvas.size)。
    其他
    其实不仅仅是大小缩放的问题,坐标也会偏移,在canvas中画圆,如果canvas元素与绘图表面的尺寸不一致,会发现实际展示的圆心位置并不是你指定的坐标,实际展示的坐标位置同样遵循上面所述的规则。

当然,解决这些问题非常简单,就是不要使用css来指定canvas元素大小,保持canvas元素尺寸与绘图表面尺寸的一致性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值