Canvas是HTML的API,我们可以用它在网页中实时的来生成图像。

文章导读

  1.必备技能

  2.用于画图的函数

    例子:

      -会话气泡-    -心形-    -钟表-      -星球里的星星-

      -调色板-      -鼠标绘图-      -旋转的小方块-

  3.图像的处理

    例子:

      -图像的灰度和翻转效果-     -拾色器-

      -放大镜-      -图像的高斯模糊-    

一.必备技能

<canvas id="Canvas" width="400" height="200">
不支持canvas的浏览器,你就会看到这句话!
</canvas>

控制它的宽高是要写在行内样式中的,像上面那样。这样我们就有了一个canvas元素,然后我们就可以去操作它了:

var canvas = document.getElementById('Canvas');

if (canvas.getContext) {
var content = canvas.getContext('2d');
}

获取元素的同时,还要获取canvas的2D绘图环境。要是用于3D绘图的话,就要用WebGL了。

二.用于画图的函数

然后,我们要开始在画布上绘图了。它的画布是这样的网格:

2.1矩形

canvas中只支持这一种形状的函数,别的形状就都要自己组合来实现了。

fillRect(x, y, width, height) //画一个填充的矩形
strokeRect(x, y, width, height) //画一个只有边框的矩形
clearRect(x, y, width, height) //清除指定的矩形区域

其中的(x,y)是指矩形左上角的坐标。

查看源码][运行结果

2.2路径

1.首先,创建一条路径--beginPath()
2.然后,通过一些绘图的方法做一些绘图操作
3.然后关闭路径--closePath()
4.我们已经把路径创建好了,然后就是填充或者绘制路径到我们的画布上--stroke()/fill()

比如说画一个三角形:

查看源码][运行结果

需要注意的是其中两个三角形,颜色不同,一不小心可能会出问题,所以我们有时可能需要save()和restore()函数的帮助来达到局部作用的效果。比如上面示例源码中所做的那样:

                content.save();//局部作用效果
content.fillStyle = 'red';
content.beginPath();//beginPath()不写的时候可能会出错,所以确保beginPath和closePath都相对应
content.moveTo(100,100);
content.lineTo(200,200);
content.lineTo(300,200);
content.closePath();
content.fill();
content.restore(); content.beginPath();
content.moveTo(100,200);
content.lineTo(200,300);
content.lineTo(300,300);
content.closePath();
content.fill();

canvas还提供了两个移动画笔的函数:

moveTo(x, y) //将画笔移动到指定的(x,y)的位置
lineTo(x, y) //在当前画笔的位置到指定的(x,y)位置画一条线

尝试一下moveTo()方法我们可以画个笑脸:

查看源码][运行结果

结合使用moveTo和lineTo方法,我们可以实现鼠标像画笔一样在画板上绘图的效果:

查看源码][运行结果

然后我们严格的按照上面说的规范步骤,1,2,3,4并结合画圆的函数,可以自己绘制一个钟表,稍加改进就是个嘀嗒嘀嗒走的时钟了:

查看源码][运行结果

 2.3文字

fillText('要显示的文本',x坐标,y坐标)此方法不支持文本断行,要显示多行文本只能多次调用

通过fillText()方法我们可以在canvas画布上写文字:

查看源码][运行结果

2.4圆形和扇形

ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);

(x,y)--圆心坐标
radius--半径
startAngle--扇形的起始角度(弧度)
endAngle--扇形的终止角度(弧度)
anticlockwise--做图时是顺时针画(true)还是逆时针(false)画

查看源码][运行结果

结合对rgb颜色的相关操作,我们可以做出类似调色板的效果:

         

查看源码][运行结果

2.5不规则图形

我们可以通过画曲线来得到不规则的图形,canvas为我们提供了两个高大上的函数:

-------------------------------
#quadraticCurveTo(cp1x, cp1y, x, y)
(cp1x,cp1y)--控制点
此函数表示从当前的画笔位置到(x,y)画一条二次曲线
-------------------------------
#bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
(cp1x,cp1y)--控制点1 (cp2x,cp2y)--控制点2
此函数表示从当前的画笔位置到(x,y)画一条bezier曲线
-------------------------------

这两个曲线具体含义我也不太清楚,但大概是这个样子:

试一下quadraticCurveTo函数:

查看源码][运行结果

试一下bezierCurveTo函数:

查看源码][运行结果

2.6渐变和阴影

#渐变:
var myGradient = ctx.createLinearGradient(x1, y1, x2, y2);
(x1,y1)--起点坐标 (x2,y2)--终点坐标
myGradient.addColorStop(0, "#BABABA");
--添加起始颜色
myGradient.addColorStop(1, "#636363");
--添加终止的颜色 ----------------------------- #阴影
ctx.shadowOffsetX = 10; // 设置水平位移
ctx.shadowOffsetY = 10; // 设置垂直位移
ctx.shadowBlur = 5; // 设置模糊度
ctx.shadowColor = "rgba(0,0,0,0.5)"; // 设置阴影颜色

一个也不太搭边儿的例子,不管怎么说,也用到了渐变呢:

查看源码][运行结果

这里面用到了clip()方法来实现星星,这跟某css属性clip-path比较神似,我以前尝试过:

请戳[源码][示例

2.7变换

canvas中有我们熟悉的几个变换函数:

translate(x, y) --平移
rotate(angle) --旋转
scale(x, y) --缩放
transform(a, b, c, d, e, f) --变换
上面的变换函数是根据变换矩阵进行的:
a c e
[ b d f ]
0 0 1

简单的小例子:

查看源码][运行结果

三.图像处理

var myImageData = ctx.createImageData(width, height);
ctx.getImageData(left, top, width, height);//读取canvas的内容,返回一个对象且该对象有一个data属性,可以供我们操作页面的像素。
ctx.putImageData(myImageData, dx, dy);//将操作好的对象重新绘制在画布中
ctx.drawImage(img, 0, 0); // 我们常用的drawImage方法,设置对应的图像对象,以及它在画布上的位置

通过getImageData()方法获取到图像对象,访问它的data属性就可以得到一个像素数组,我们对像素进行处理,使我们可以用canvas处理图像。

3.1 灰度效果

灰度图(grayscale)就是取红、绿、蓝三个像素值的算术平均值,这实际上将图像转成了黑白形式。假定d[i]是像素数组中一个象素的红色值,则d[i+1]为绿色值,d[i+2]为蓝色值,d[i+3]就是alpha通道值。转成灰度的算法,就是将红、绿、蓝三个值相加后除以3,再将结果写回数组。

               for(var i=0;i<data.length;i+=4){
var avg = (data[i]+data[i+1]+data[i+2]) / 3;
data[i] = avg; //r
data[i+1] = avg; //g
data[i+2] = avg; //b
}

3.2 复古效果

复古效果(sepia)则是将红、绿、蓝三个像素,分别取这三个值的某种加权平均值,使得图像有一种古旧的效果。

  for (var i = 0; i < d.length; i += 4) {
var r = d[i];
var g = d[i + 1];
var b = d[i + 2];
d[i] = (r * 0.393)+(g * 0.769)+(b * 0.189); // red
d[i + 1] = (r * 0.349)+(g * 0.686)+(b * 0.168); // green
d[i + 2] = (r * 0.272)+(g * 0.534)+(b * 0.131); // blue
}

3.3 反转效果

反转效果(invert)是指图片呈现一种色彩颠倒的效果。算法为红、绿、蓝通道都取各自的相反值(255-原值)。

 for (var i = 0; i < d.length; i += 4) {
d[i] = 255 - d[i];
d[i+1] = 255 - d[i + 1];
d[i+2] = 255 - d[i + 2];
}

我尝试了一下灰度图的效果和反转图的效果:

查看源码

注意,在我们自己本地写demo准备运行查看结果的时候,getImageData()方法可能会有问题,比如说报这个错:Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data

我们知道这是域和本地运行等相关的问题,这时我们自己本地启用服务器,localhost访问就可以了。

 3.4 拾色器

实现思路:通过getImageData(x,y,1,1)获得当前鼠标所在位置的一像素的图像对象,通过其data属性操作拿到它的像素值,也就是我们想得到的rgb值。

查看源码

3.5 放大镜

实际上drawImage方法可以有多个参数,提供更加丰富的功能:

  ctx.drawImage(image, dx, dy);
ctx.drawImage(image, dx, dy, dWidth, dHeight);
ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

各个参数就像下面的示意图这样:

然后我们就可以使用drawImage方法在原图像变换到绘制的图像中做一个等比放大的操作,就可以实现放大镜的效果啦。

查看源码

3.6图像的高斯模糊

其实,css中有一个兼容性不那么好的filter属性,可以简单的实现图像模糊的效果:

 -webkit-filter: blur(20px); /* Chrome, Opera */
-moz-filter: blur(20px);
-ms-filter: blur(20px);
filter: blur(20px);

查看源码

但是使用canvas可以实现真正意义上的高斯模糊(就是算法那种balabala的)。

这里有一个实现的很好的高斯模糊的js:「StackBlur

使用它我们就可以轻松的实现图像的高斯模糊了:「查看源码

文章中的源码Demo都放在了github上,打开可能会有些慢,如果第一次打不开,刷新一下也会好了。

四.资源

canvas中绘图环境所有的属性和方法都可以在这里找到:「CanvasRenderingContext2D interface

使用CSS将图片转换成模糊(毛玻璃)效果」

Canvas API

javascript标准参考教程Canvas

相识HTML5 canvas的更多相关文章

  1. HTML5 程序设计 - 使用HTML5 Canvas API

    请你跟着本篇示例代码实现每个示例,30分钟后,你会高喊:“HTML5 Canvas?!在哥面前,那都不是事儿!” 呵呵.不要被滚动条吓到,很多都是代码和图片.我没有分开写,不过上面给大家提供了目录,方 ...

  2. 赠书:HTML5 Canvas 2d 编程必读的两本经典

    赠书:HTML5 Canvas 2d 编程必读的两本经典 这两年多一直在和HTML5 Canvas 打交道,也带领团队开发了世界首款基于HTML5 Canvas 的演示文档工具---AxeSlide( ...

  3. 如何开发一个简单的HTML5 Canvas 小游戏

    原文:How to make a simple HTML5 Canvas game 想要快速上手HTML5 Canvas小游戏开发?下面通过一个例子来进行手把手教学.(如果你怀疑我的资历, A Wiz ...

  4. html5 canvas常用api总结(一)

    1.监听浏览器加载事件. window.addEventListener("load",eventWindowLoaded,false); load事件在html页面加载结束时发生 ...

  5. HTML5 Canvas绘制转盘抽奖

    新项目:完整的Canvas转盘抽奖代码 https://github.com/givebest/GB-canvas-turntable 演示 http://blog.givebest.cn/GB-ca ...

  6. html5 canvas首屏自适应背景动画循环效果代码

    模板描述:html5 canvas首屏自适应背景动画循环效果代码 由于动态图太大,怕以后服务器受不了,所以现在都改为静态图了,大家点击演示地址一样的,希望大家喜欢,你们的支持就是小海的动力!! 欢迎大 ...

  7. 自己写的HTML5 Canvas + Javascript五子棋

    看到一些曾经只会灌水的网友,在学习了前端之后,已经能写出下载量几千几万的脚本.样式,帮助大众,成为受欢迎的人,感觉满羡慕的.我也想学会前端技术,变得受欢迎呀.于是心血来潮,开始学习前端知识,并写下了这 ...

  8. HTML5 Canvas彩色小球碰撞运动特效

    脚本简介 HTML5 Canvas彩色小球碰撞运动特效是一款基于canvas加面向对象制作的运动小球动画特效.   效果展示 http://hovertree.com/texiao/html5/39/ ...

  9. 学习笔记:HTML5 Canvas绘制简单图形

    HTML5 Canvas绘制简单图形 1.添加Canvas标签,添加id供js操作. <canvas id="mycanvas" height="700" ...

随机推荐

  1. CSS3 Loading(加载)动画效果

    1.html 部分 <div class="spinner"> <div class="rect1"></div> < ...

  2. Eclipse中使用Maven创建web项目

    一.创建一个Maven项目 1.Eclipse中用Maven创建项目 上图中点击next 2.继续next 3.选maven-archetype-webapp后,next 4.填写相应的信息,Pack ...

  3. UWP 判断windows mobile是使用的实体键还是虚拟按键

    最近在写启动屏幕,发现虚拟按钮会挡住,启动屏幕的最下面的元素,大概有50 px.可是有什么办法知道手机是用的实体键还是虚拟按键吗? 如下图.可以看到红色的部分显示了一点点.代码里设置的是60px. 在 ...

  4. for循环每次取出一个字符(不是字节)

    python3.5 for循环每次取出一个字符(不是字节) #!/usr/bin/env python # -*- coding:utf-8 -*- my_str = "我是哈哈" ...

  5. 从外部浏览开启app

    先描述一下需求:从浏览器中点击某个按钮,如果手机上装有相应的app,则直接开启app,并且到相对的页面.如果没有装该app,则会到相应的下载app的界面. 我这里主要用的是第三方的东西,就是魔窗中的m ...

  6. python调用c\c++

    前言 python 这门语言,凭借着其极高的易学易用易读性和丰富的扩展带来的学习友好性和项目友好性,近年来迅速成为了越来越多的人们的首选.然而一旦拿python与传统的编程语言(C/C++)如来比较的 ...

  7. python 爬虫(三)

    爬遍整个域名    六度空间理论:任何两个陌生人之间所间隔的人不会超过六个,也就是说最多通过五个人你可以认识任何一个陌生人.通过维基百科我们能够通过连接从一个人连接到任何一个他想连接到的人. 1. 获 ...

  8. Xcode playground markdown常用语法

    //: **Bold** *Italic* /*: # h1 ## h2 ### h3 #### h4 h5 h6 same as h3 --- --- --- * blank seperate li ...

  9. [翻译svg教程]svg学习系列 开篇

    目录 [翻译svg教程]svg学习系列 开篇 [翻译svg教程 ]svg 的坐标系统 [翻译svg教程]svg 中的g元素 [翻译svg教程]svg中矩形元素 rect [翻译svg教程]svg中的c ...

  10. Linux下Electron的Helloworld

    什么是Electron Electron 框架的前身是 Atom Shell,可以让你写使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序.它是基于io.js 和 Chromi ...