用Canvas打造高强度渲染SVG

前言

         早就想写这篇博客。一个原因是其中某些内容在某度的面试中遇到,比如第二部分;二是一些需求在实际工程中遇到了。

一、基本概念

         Canvas:html5新增的DOM,提供了像素级图形编程接口。支持path,不支持鼠标响应,不能绘制矢量图,依赖分辨率,文本渲染能力弱,刷新能力强。适用于图像密集型编程,如游戏。

         SVG:一种使用XML描述2D图像的语言。因此SVG中所有元素都是DOM。支持path,支持鼠标事件,能绘制矢量图,不依赖分辨率,文本渲染能力强,刷新能力弱。适用于大区域渲染程序,比如地图。

二、性能对比及应用场景

         详情见这篇文章:http://msdn.microsoft.com/zh-cn/library/gg193983,这里给出一些摘要。


         选择SVG:

         l  用于查看和打印的高保真文档,如建筑图、工程图、电子图、航空图、地理图、组织图、生物图等。

         l  静态图像,比如带有某些特效的图片,用SVG会节省图片的存储空间。

         选择Canvas:

         l  高性能图形,如光线跟踪器、3D引擎渲染器。

         l  复杂场景,实时动画等。

         l  图像处理,涉及到像素操作。

三、应用中的问题

        既然Canvas和SVG各有特点,我们只需要在特定场景选择特定技术就行了。但其中有一些问题。比如我想做一个CAD online,就是在Web上做一个工程制图工具,能编辑CAD图纸,用哪种技术好?首先想到的肯定是SVG,因为编辑器肯定要在工作区选择某一条线、某一个元素,这需要鼠标事件。并且,SVG适合高保真图纸的显示,又能保存成矢量图。

        但实际做起来,就不太容易了。因为SVG是DOM,如果一张图纸里有几万条线,恐怕打开图纸,成功渲染出来都要几分钟,更别说编辑、来回拖动图纸了。可用Canvas绘制图纸,先不说怎样高保真绘制,这些可以通过引入图形算法解决,单响应鼠标事件这一项就不好实现,似乎不可能从像素中识别出一条完整的线。

真的不行么?接下来我们就来解决这个问题,并做一个简单的DEMO,让Canvas看起来像极了SVG,能响应鼠标事件。

四、Canvas的鼠标接口

        Canvas其实提供了一个鼠标接口,仔细翻API文档,你就会发现isPointInPath()方法,这是我们唯一可以利用的。该方法的作用是判断Canvas中的某个点,在不在某个路径中。输入参数两个,x值和y值,笛卡尔坐标,返回值boolean:

<span style="font-size:14px;">    var ctx =document.getElementById(‘container’).getContext(‘2d’);
    var isin = ctx.isPointPath(0, 0);</span>

        需要强调的是,前面提到“在不在某个路径中”,指的是哪个路径?Canvas在绘制时,都是以路径为基本单位。路径以ctx.beginPath();开始,那么以什么结束呢?很多人说closePath()结束,这是大错特错的说法。closePath() 的意思是闭合路径,而不是结束路径,如果是endPath 就对了。其实,路径,在绘制时宣布结束,即ctx.strock()或ctx.fill()。只要碰到这两个方法的任何一个,都算一个路径绘制结束。接下来剩下的问题就是,什么时候使用isPointInPath(),就是在路径的开始后,绘制前。在这个阶段可以做很多事:设置线条样式、设置填充样式、在路径中绘画、判断某个点是否在路径中。</

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值