原文  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绘制背景图的更多相关文章

  1. 用canvas绘制折线图

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. Android自己定义组件系列【9】——Canvas绘制折线图

    有时候我们在项目中会遇到使用折线图等图形,Android的开源项目中为我们提供了非常多插件,可是非常多时候我们须要依据详细项目自己定义这些图表,这一篇文章我们一起来看看怎样在Android中使用Can ...

  3. 使用canvas绘制扇形图

    <!doctype html><html lang="en"><head> <meta charset="UTF-8" ...

  4. canvas绘制折线图(仿echarts)

    遇到的问题:Retina屏上字体线条模糊问题 解决方案:放大canvas的大小,然后用css压缩回原大小,例如:想要900*400的画布,先将画布设置为 width="1800px" ...

  5. canvas 绘制星座图(好玩)--转载

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...

  6. canvas绘制经典折线图(一)

    最终效果图如下: 实现步骤如下:注-引用了jQuery HTML代码 <!doctype html> <html lang="en"> <head&g ...

  7. background 的一些 小的细节: 1, 背景色覆盖范围: border+ width+ padding ;背景图覆盖范围: width + padding ; 2设置多个背景图片 ; 3) background-position定位百分比的计算方式: 4)background-clip 和 background-origin 的区别

    1. background (background-color, background-image)  背景色覆盖范围: border+ width+ padding ;背景图覆盖范围: width ...

  8. canvas 绘制刮刮卡

    思路=> 用div来展示刮奖结果,用canvas绘制刮奖前展示的图片或者文字:将canvas叠在div上方,刮奖是只需要操作canvas配合touch事件即可简单完成. canvas刮奖可以用g ...

  9. 【带着canvas去流浪(6)】绘制雷达图

    目录 一. 任务说明 二. 重点提示 三. 示例代码 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文 ...

随机推荐

  1. 树莓派3B更新软件

    因为软件是要不断更新的,所以半个月或者一个月要升级一下软件 升级软件非常简单 在终端或者SSH里输入 sudo apt-get update && apt-get upgrade -y ...

  2. Git-仓库基本结构

    三 Git 仓库      1.1Git 基本概念    在Git中,我们将需要进行版本控制的文件目录叫做一个仓库(repository),每个仓库可以简单理解成一个目录,这个目录里面的所有文件都通过 ...

  3. [Tips] Useful link ... on going

    1. CSS Bootstrap http://getbootstrap.com/ Bootstrap 中文文档 http://getbootstrap.com/2.3.2/ 最全的 Twitter ...

  4. opencv笔记2:图像ROI

    time:2015年 10月 03日 星期六 12:03:45 CST # opencv笔记2:图像ROI ROI ROI意思是Region Of Interests,感兴趣区域,是一个图中的一个子区 ...

  5. 用xml添加动画

    在res文件夹下新建anim文件夹 在anim文件夹新建anim.xml anim.xml: <?xml version="1.0" encoding="utf-8 ...

  6. [视频转换] C#VideoConvert视频转换帮助类 (转载)

    点击下载 VideoConvert.zip 主要功能如下 .获取文件的名字 .获取文件扩展名 .获取文件类型 .视频格式转为Flv .生成Flv视频的缩略图 .转换文件并保存在指定文件夹下 .转换文件 ...

  7. java.lang.OutOfMemoryError: GC overhead limit exceeded 问题分析和解决(转)

    在项目历史数据导入过程中,出现了应用无法访问的情况.立刻对Weblogic进行分析,发现Weblogic的内存.线程等性能良好,Server也是Running的状态.随后查看了Weblogic日志,在 ...

  8. Word Break II 解答

    Question Given a string s and a dictionary of words dict, add spaces in s to construct a sentence wh ...

  9. Jrebel热部署配置完整教程(IntelliJ IDEA、Jrebel、spring boot、springboot、eclipse、Tomcat)

    标签:IntelliJ IDEA.Jrebel.spring boot.springboot.eclipse.Tomcat1.安装插件并激活插件安装参考:http://blog.csdn.net/u0 ...

  10. opencron

    opencron 是强大的管理linux crontab任务的系统,基于JAVA开发 http://github.com/wolfboys/opencron 一个功能完善真正通用的linux定时任务调 ...