canvas元素大小与绘图表面大小
原文链接: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元素大小与绘图表面大小的更多相关文章
- canvas总结:元素大小与绘图表面大小
前言 我们使用canvas的时候一般在canvas元素中直接设置它的width和height: <canvas id="myCanvas" width="300&q ...
- 使用html元素的getBoundingClientRect来获取dom元素的时时位置和大小
使用: var section = $('.section'):这是jquery包装的dom元素,其他前端框架返回的可能也是一个包装元素, 我们需要获得的是里面的html的dom元素 然后:secti ...
- 【高级功能】使用canvas元素(第一部分)
1. 开始使用 canvas 元素 canvas 元素非常简单,这是指它所有的功能都体现在一个JavaScript对象上,因此该元素本身只有两个属性:width 和 height. canvas 元素 ...
- HTML5 画布canvas元素
HTML5的canvas元素以及随其而来的编程接口Canvas API应用前景极为广泛.简单地说,canvas元素能够在网页中创建一块矩形区域,这块矩形区域可以成为画布,这其中可以绘制各种图形.可别小 ...
- 【温故而知新-Javascript】使用canvas元素(第一部分)
1. 开始使用 canvas 元素 canvas 元素非常简单,这是指它所有的功能都体现在一个JavaScript对象上,因此该元素本身只有两个属性:width 和 height. canvas 元素 ...
- Android应用程序窗口(Activity)的绘图表面(Surface)的创建过程分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8303098 在前文中,我们分析了应用程序窗口连 ...
- HTML5<canvas>标签:使用canvas元素在网页上绘制线条和圆(1)
什么是 Canvas? HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像. 画布是一个矩形区域,您可以控制其每一像素. canvas 拥有多种绘制路径.矩形.圆形.字符以 ...
- 基于HTML5 Canvas和jQuery 的绘图工具的实现
简单介绍 HTML5 提供了强大的Canvas元素.使用Canvas并结合Javascript 能够实现一些很强大的功能.本文就介绍一下基于HTML5 Canvas 的绘图工具的实现.废话少说,先看成 ...
- windows phone (24) Canvas元素A
原文:windows phone (24) Canvas元素A Canvas元素表示定制一个区域,并可以通过相对坐标定义子元素位置,在一下情况下Canvas是不可见的 Height 属性等于 0. W ...
随机推荐
- win7 删除服务
以管理员身份运行命令行工具. 输入 sc delete "服务名" 如若服务名有特殊字符需要加引号. sc dekete apache_pn
- Python subprocess执行持续输出shell命令的控制
研究了大半天,为了获取持续输出的shell指令结果,并对结果进行分析,一直因为无法控制subprocess开启的子进程头疼,研究了半天,参考众多大神的博客后,终于实现,目前已时间为控制点,在实际业务中 ...
- LinkButton中添加删除确认框
LinkButton1.Attributes.Add("onclick", "javascript:return confirml('确认删除?');");
- 手把手教你发布代码到CocoaPods(Trunk方式)-备用
概述 关于CocoaPods的介绍不在本文的主题范围内,如果你是iOS开发者却不知道CocoaPods,那可能要面壁30秒了.直奔主题,这篇文章主要介绍如果把你的代码发布到CocoaPods代码库中, ...
- 关于popupwindow的两种实现方式
http://104zz.iteye.com/blog/1685389 android PopupWindow实现从底部弹出或滑出选择菜单或窗口 本实例弹出窗口主要是继承PopupWindow类来实现 ...
- cf B. Dima and To-do List
http://codeforces.com/contest/366/problem/B 从0到k枚举起点,然后i+k判断是不是i+k>=n如果是i=(i+k)%n;否则i=i+k; #inclu ...
- WPF学习拾遗(二)TextBlock换行
原文:WPF学习拾遗(二)TextBlock换行 下午在帮组里的同事解决一个小问题,为了以后方便,把就把它收集一下吧. 新建一个TextBlock作为最基础的一个控件,他所携带的功能相对于其他的控件要 ...
- Linux 让进程在后台可靠运行的几种方法
我们经常会碰到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,运行了一些耗时较长的任务, 结果却由于网络的不稳定导致任务中途失败.如何让命令提交后不受本地关闭终端窗口/网络断开 ...
- 只允许指定的ip访问本机的指定端口22:
只允许指定的ip访问本机的指定端口22: 允许的的ip:192.168.1.123, 192.168.1.124, 192.168.1.100,其他ip都禁止访问. 切换到root用户 1.在tcp协 ...
- linux 下的对拍
搞了一上午终于弄好了一个对拍,估计以后调试会方便很多. #!/bin/bash while true; do ./makedate>tmp.in ./XXXXX<tmp.in>tmp ...