使用Canvas绘制背景图
原文 http://www.imququ.com/post/use-canvas-as-background-image.html
最近iCloud Web的Beta版换了UI,整体风格变得和iOS7一致了。首页图标下方漂浮着若干大小不一的泡泡,十分梦幻。大家可以访问 beta.icloud.com 体验下,如果觉得泡泡不够多,还可以加上 crazyAwesome 参数让泡泡变得更加疯狂。
上面提到的泡泡效果,有许多种实现方案。本文要讨论的是iCloud使用的Canvas绘制背景图方案。这样做的好处是,用代码绘制背景图,相比图片更灵活,也更省流量。另外,不知道大家有没留意到iCloud Web中的日历图标是根据当前日期和星期几动态生成的,下面Demo中有这个图标的实现。
canvas.toDataURL
大家知道,一般我们可以用图片、SVG和颜色渐变来做为元素的背景图(background-image属性)。在Canvas中,可以通过 toDataURL() 方法,把图像导出为 data类型的URL ,这个URL可以直接用做背景图。下面有个简单的例子:
<div style="width:200px;height:200px;" id="cloud">红心是我的背景图!</div>
<canvas style="display:none;" id="can" width="200" height="200"></canvas>
<script>
(function() {
var canvas = document.getElementById('can'), context; if(!canvas.getContext) {
alert('你的浏览器不支持canvas!');
return;
} context = canvas.getContext('2d');
context.fillStyle = 'red';
context.beginPath();
context.moveTo(75,40);
context.bezierCurveTo(75,37,70,25,50,25);
context.bezierCurveTo(20,25,20,62.5,20,62.5);
context.bezierCurveTo(20,80,40,102,75,120);
context.bezierCurveTo(110,102,130,80,130,62.5);
context.bezierCurveTo(130,62.5,130,25,100,25);
context.bezierCurveTo(85,25,75,37,75,40);
context.fill(); document.getElementById('cloud').style.backgroundImage = 'url("' + context.canvas.toDataURL() + '")';
})();
</script>
这是使用本方案实现的 iCloud日历图标 ,支持Canvas的浏览器都可以正常显示。
用Canvas绘制背景图,将Canvas强大的绘图能力与灵活的CSS背景图很好的结合起来,强大但不完美。例如多个元素使用同一个Canvas背景时,无论是分开设置背景图,还是创建临时Style,都很麻烦。如果想把一个Canvas动画作为元素背景,需要不断获取DataURL再赋给元素,更加不方便。
有没有更好的办法可以把一个或多个html元素与Canvas绑定起来,在Canvas内容改变时自动更新html元素呢?答案是肯定的。
-webkit-canvas
对于上面的问题,Webkit提出了一个自己的实现方案:-webkit-canvas。Safari4+、Chrome4+的background-image都支持这个属性值( caniuse ),可以方便的使用CSS Canvas作为元素的背景图,类似这样:
#icon1 {
background-image: -webkit-canvas(identifier);
}
区别于在Canvas元素上绘图,-webkit-canvas方案需要用下面的方法获取绘图的Context:
var context = document.getCSSCanvasContext("2d", "identifier", width, height);
创建CSS Canvas时需要指定一个标识,用它的html元素在CSS中指定这个标识就可以了。浏览器会自动将CSS Canvas的改变同步到所有指定了这个标识的元素上,这样就成功解决了上面提出的问题。
具体效果可以继续 看我写的Demo ,Webkit Only。这里还有一个使用-webkit-canvas将Canvas动画作为背景图的例子, 请自备梯子查看 。
-moz-element
Mozilla有个类似的方案,叫 -moz-element 。可以指定任何元素作为另外元素的背景图(实际上,一个元素不能指定父元素作为自己的背景,为什么自己想),Firefox4+开始支持它作为background-image的属性值。下面是它的用法:
<button id='elementID'>this is a element.</button>
<div style='background-image:-moz-element(#elementID);width:300px;height:200px;'></div>
于是,上面的Demo在Firefox下可以改由-moz-element来实现了, 点击查看 。由于本方案支持任何元素作为背景,所以 也可以这么玩 ,纯CSS的有趣效果,Firefox Only。
最后
个人感觉Mozilla的方案略微夸张了点,相比之下Webkit的CSS Canvas更有可能成为标准。另外,iCloud对于不支持-webkit-canvas的浏览器使用的是DataURL方案,并没有使用firefox的-moz-element,具体什么原因就不得而知了。
使用Canvas绘制背景图的更多相关文章
- 用canvas绘制折线图
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Android自己定义组件系列【9】——Canvas绘制折线图
有时候我们在项目中会遇到使用折线图等图形,Android的开源项目中为我们提供了非常多插件,可是非常多时候我们须要依据详细项目自己定义这些图表,这一篇文章我们一起来看看怎样在Android中使用Can ...
- Android自定义控件 -Canvas绘制折线图(实现动态报表效果)
有时候我们在项目中会遇到使用折线图等图形,Android的开源项目中为我们提供了很多插件,但是很多时候我们需要根据具体项目自定义这些图表,这一篇文章我们一起来看看如何在Android中使用Canvas ...
- Android自定义组件系列【9】——Canvas绘制折线图
有时候我们在项目中会遇到使用折线图等图形,Android的开源项目中为我们提供了很多插件,但是很多时候我们需要根据具体项目自定义这些图表,这一篇文章我们一起来看看如何在Android中使用Canvas ...
- canvas 绘制八卦图
绘制要点: 1.getContext('2d'); -->绘图环境,2维空间 2.fillRect(x,y,w,h); -->矩形:实心(黑色背景) 3.strokeRect(x,y,w, ...
- 使用canvas绘制扇形图
<!doctype html><html lang="en"><head> <meta charset="UTF-8" ...
- canvas绘制折线图(仿echarts)
遇到的问题:Retina屏上字体线条模糊问题 解决方案:放大canvas的大小,然后用css压缩回原大小,例如:想要900*400的画布,先将画布设置为 width="1800px" ...
- canvas 绘制星座图(好玩)--转载
<!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...
- canvas绘制折线图
效果图: 重难点: 1.画布左上角的顶点的坐标为(0 ,0),右下角的坐标最大,与平常思维相反 2.数据的处理 html代码: <!DOCTYPE html><html lang=& ...
随机推荐
- Build2016上值得一看的大数据相关Session
(此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:Build2016开完很久了,现在才来回顾下,就说说那些和大数据相关的Session, ...
- 最小化安装centos7不能执行ifconfig命令的解决方法
操作环境 虚拟机:VirtualBox 5.0.4 for Windows 操作系统:CentOS-7-x86_64-Minimal-1503-01.iso 问题描述 登录系统之后,输入ifconfi ...
- 开发常用之在webstorm中使用cmd
而今前端开发经常与cmd打交道,如使用个npm什么的,如果老是在ide和cmd之间切换显得比较繁琐,众多前端利器中我最喜欢的就是webstorm,而webstorm中就可以直接使用cmd,如图1, ...
- Appirater -- app中提示用户为app评价的提示框
Appirater是一段你可以嵌入自己工程中的代码,在用户使用应用一段时间后会自动弹出提示用户进行评分. 使用Appirater方面,你可以简单把源代码嵌入你的app工程中,并把以下代码添加至它的委托 ...
- 在wex5平台grid里面的gridselect下拉不能显示汉字问题
当grid里面有gridSelect组件的时候,gridSelect里面的bind-ref是对应的数据库存入字段(int类型),bind-labelRef是对应的计算字段(视图里面的),而option ...
- oj Rapid Typing
import bs4 import requests import urllib2 import time import base64 session=requests.Session() respo ...
- 转:WCF、WebAPI、WCFREST、WebService之间的区别
WCF.WebAPI.WCFREST.WebService之间的区别 注明:转载 在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API ...
- iOS中类别的使用
类别的三大作用1.给现有的类增加方法,可以增加 对象方法,也可以增加静态方法. 如果增加的方法是此类本来就有的方法,那么,此方法有可能会把原方法覆盖,也有可能不会覆盖. 类别只能增加现有类的方法,不能 ...
- jenkins和hudson---打酱油的日子
自动化构建:Jenkins起源于Hudson.Hudson在商业软件的路上继续前行,而Jenkins则作为开源软件,从hudson分支出来. 因此现在的jenkins和hudson非常类似,但是随着二 ...
- 【Oracle】ora-28001 ora-28002提示用户密码即将过期的解决办法
-- 1.首先查看用户的配置文件中的用户密码生命周期,一般情况下默认是180天.登录时系统提示ora-28002该用户即将过期 -- 可以先查看一下各用户的状态 SELECT username,PRO ...