原文链接:canvas总结:元素大小与绘图表面大小

前言

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

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

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

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

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

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

运行页面,展示如下

canvas大小为600px,高为300px,没有任何问题,符合预期。但是矩形...这显然不是40*40好吧,这是80*80

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

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

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

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

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

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

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

1
2
3
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元素600*300,绘图表面300*100,画矩形40*40

实际矩形80*120

宽度是预期的两倍,高度是预期3倍

2. Css中设置canvas元素600*300,绘图表面200*150,画矩形40*40

实际矩形120*80

宽度是预期的3倍,高度是预期的2倍

3. Css中设置canvas元素600*300,绘图表面1200*900,画矩形60*60

实际矩形30*20

宽度是预期的1/2,高度是预期的1/3

4. Css中设置canvas元素600*300,绘图表面1800*600,画矩形60*60

实际矩形20*30

宽度是预期的1/3,高度是预期的1/2

我们用element表示canvas元素,用canvas表示绘图表面,src表示绘制的内容,dest表示展示的内容,缩放规则为:dest.size = src.size * (element.size / canvas.size)

其它

其实不仅仅是大小缩放的问题,坐标也会偏移,在canvas中画圆,如果canvas元素与绘图表面的尺寸不一致,会发现实际展示的圆心位置并不是你指定的坐标,实际展示的坐标位置同样遵循上面所述的规则。

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

自适应

当我们在说自适应的时候,我们说的是 css layout dimensions 自适应,亦即元素的 display size。

而 canvas 的 width/height 属性对应的是画布内的 coordinate space,并不归 CSS 管。

于是,canvas 的显示大小可以由 CSS 规则指定,做到显示自适应,但其内部像素并不对应 CSS 像素或屏幕物理像素,也就是说缩放显示。

===========================================

如果你需要让 canvas 的 coordinate space 始终跟随窗口大小的话,可以用 js 设定 canvas 高宽为窗口高宽 x 设备像素密度,并且监听 window resize 事件,使 canvas 高宽随着窗口大小的变化而变化。

另外, canvas 的高宽改变时,画布内容会被清空,需要重新绘制。

canvas元素大小与绘图表面大小的更多相关文章

  1. canvas总结:元素大小与绘图表面大小

    前言 我们使用canvas的时候一般在canvas元素中直接设置它的width和height: <canvas id="myCanvas" width="300&q ...

  2. 使用html元素的getBoundingClientRect来获取dom元素的时时位置和大小

    使用: var section = $('.section'):这是jquery包装的dom元素,其他前端框架返回的可能也是一个包装元素, 我们需要获得的是里面的html的dom元素 然后:secti ...

  3. 【高级功能】使用canvas元素(第一部分)

    1. 开始使用 canvas 元素 canvas 元素非常简单,这是指它所有的功能都体现在一个JavaScript对象上,因此该元素本身只有两个属性:width 和 height. canvas 元素 ...

  4. HTML5 画布canvas元素

    HTML5的canvas元素以及随其而来的编程接口Canvas API应用前景极为广泛.简单地说,canvas元素能够在网页中创建一块矩形区域,这块矩形区域可以成为画布,这其中可以绘制各种图形.可别小 ...

  5. 【温故而知新-Javascript】使用canvas元素(第一部分)

    1. 开始使用 canvas 元素 canvas 元素非常简单,这是指它所有的功能都体现在一个JavaScript对象上,因此该元素本身只有两个属性:width 和 height. canvas 元素 ...

  6. Android应用程序窗口(Activity)的绘图表面(Surface)的创建过程分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8303098 在前文中,我们分析了应用程序窗口连 ...

  7. HTML5<canvas>标签:使用canvas元素在网页上绘制线条和圆(1)

    什么是 Canvas? HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像. 画布是一个矩形区域,您可以控制其每一像素. canvas 拥有多种绘制路径.矩形.圆形.字符以 ...

  8. 基于HTML5 Canvas和jQuery 的绘图工具的实现

    简单介绍 HTML5 提供了强大的Canvas元素.使用Canvas并结合Javascript 能够实现一些很强大的功能.本文就介绍一下基于HTML5 Canvas 的绘图工具的实现.废话少说,先看成 ...

  9. windows phone (24) Canvas元素A

    原文:windows phone (24) Canvas元素A Canvas元素表示定制一个区域,并可以通过相对坐标定义子元素位置,在一下情况下Canvas是不可见的 Height 属性等于 0. W ...

随机推荐

  1. Android再学习-便签开发小结-20141119

    这几天的便签开发,首先遇到的问题就是数据库操作问题.现在已经可以读写数据库了,并能将数据放在正确的位置显示. 专门建立了一个数据库操作的包,命名为"...database".新建一 ...

  2. C语言初学 if-else语句判断俩数的最大值

    #include<stdio.h> main() { float a,b; printf("输入俩个任意实数\n"); scanf("%f%f",& ...

  3. Android系统服务-简介

    http://blog.csdn.net/chenyafei617/article/details/6577907 Introduction 我们知道Android系统服务挺多的,做程序时经常会用到, ...

  4. 多线程操作UI界面的示例 - 更新进度条

    http://blog.csdn.net/liang19890820/article/details/52186626

  5. 关于IoAttachDeviceToDeviceStack

    IoAttachDeviceToDeviceStack将Source Device附加到Target Device上. 打开windbgkd> u IoAttachDeviceToDeviceS ...

  6. android 无法生成R文件的原因剖析

    android 无法生成R文件 是件痛苦的事情,即使有时候你xml文件没有错误,他都无法生成.针对此问题,我总结以下几个方面的原因. 一.xml本身有错误 R.java这个文件是会自动生成的,但是如果 ...

  7. python sqlite3使用

    python sqlite3文档地址:http://docs.python.org/2/library/sqlite3.html The sqlite3 module was written by G ...

  8. [转]一步步搭建Ubuntu环境——dpkg 被中断,您必须手工运行 sudo dpkg --configure -a 解决此问题——安装Flashplayer出错 ------不错

    原文网址:http://blog.csdn.net/xuezhimeng2010/article/details/8545261 解决方法如下: sudo rm /var/cache/apt/arch ...

  9. Android Tab控件简介

    在Android中,Tab控件是一种很常用的控件:Tab控件即标签页,可以在一页中切换显示N页内容: Tab控件具有两种实现过程,一是在同一个Activity中切换显示不同的标签页,这种主要是通过修改 ...

  10. bzoj 1191

    http://www.lydsy.com/JudgeOnline/problem.php?id=1191 二分+二分图匹配. 首先二分可以答对前mid道题,然后做二分图. 左边是题目,右边是锦囊. 做 ...