canvas图形绘制之星空,炫丽的倒计时效果

canvas图形绘制之星空、噪点与辐射雾效果

2016/06/07 · HTML5 · 1
评论 ·
Canvas

原文出处:
张鑫旭(@张鑫旭)   

变形

在打听变形往日,先通晓景况。

  • 状态

canvas
的图景就是当下画面应用的有所样式和变形的一个快照,用来操作那个状态有多个绘制复杂图形时不可或缺的措施:save()restore()canvas图形绘制之星空,炫丽的倒计时效果。
。save()用来保存当前气象,restore()用来还原刚才保存的状态。他们都可以频仍调用。

ctx.fillStyle = 'black';
ctx.fillRect(20, 20, 150, 150);
ctx.save();  //保存当前状态
ctx.fillStyle= '#fff';
ctx.fillRect(45, 45, 100, 100);
ctx.restore();    //恢复到刚才保存的状态
ctx.fillRect(70, 70, 50, 50);
  • 位移translate(x, y)

translate方式,它用来移动 canvas 和它的原点到一个不比的职分。

demo:

var ctx = document.getElementById('canvas').getContext('2d');
for(var i = 1; i< 4; i++) {
    ctx.save();   //使用save方法保存状态,让每次位移时都针对(0,0)移动。
  ctx.translate(100*i, 0);
  ctx.fillRect(0, 50, 50, 50);
  ctx.restore();
}
  • 旋转 rotate(angle)

    rotate 它用来以原点为中央旋转:
    旋转的角度(angle),它是顺时针方向的,以弧度为单位的值。

ctx.rotate(Math.PI * 2)     //参照原点顺时针旋转360度

demo:

ctx.translate(75,75);    //把原点移动到(75, 75);
for (var i=1; i<6; i++){       // 从里到外一共6圈
  ctx.save();
  ctx.fillStyle = 'rgb('+(50*i)+','+(255-50*i)+',255)';
  for (var j=0; j<i*6; j++){     // 每一圈有i*6个圆点
    ctx.rotate(Math.PI*2/(i*6));
    ctx.beginPath();
    ctx.arc(0,i*12.5,5,0,Math.PI*2,true);
    ctx.fill();
  }
  ctx.restore();
}
  • 缩放 scale

ctx.scale(x, y);     //基于原点缩放,x、y是两个轴的缩放倍数

demo:

var ctx = document.getElementById('canvas').getContext('2d');
ctx.fillStyle = 'red';
ctx.scale(0.8, 1.2);
ctx.beginPath();
ctx.arc(75, 75, 60, 0, Math.PI * 2);
ctx.fill();
  • 变形 transforms

transform(m11, m12, m21, m22, dx, dy)

m11:水平方向的缩放

m12:水平方向的撼动

m21:竖直方向的晃动

m22:竖直方向的缩放

dx:水平方向的移动

dy:竖直方向的运动

上边先河确实的支付一个小游戏

美高梅开户网址 1

一、三合一

多个职能合成一篇文章。

有三个小伙伴问我,为什么不开个公众号,现在都是运动时代,你博客小说写好后,公众号再复制一份,花不了多久,同时传播方便急忙,打赏方便火速,鲜明低花费高收益。

以前边来看,就像是的确那样。

可是,就自己个人而言,行为和安插准则总是听从内心的直觉和大方向的率领。说不上实际的道理,就是觉得,作品的输出源如若持续一个,久远来看,带来的不解损耗一定要高于长期的已知收益。

取巧的政工多慎思而克己,就好比本文内容,实际上,五个不等的canvas效果,直接分3篇来写,凑个小说数,扩大点浏览量其实也是无可厚非的。然,想了想,有点不像自己的style,内心真正的亲善并不愿意自己如此做,于是,就3个功效合体为一篇小说。

拒绝小部分的吸引,让投机过得更自在。

本文的3个功效都是源自我目前做的多少个真实的种类,是canvas领域基本入门的一些意义。代码我都专门重新梳理了下,须要注释也都助长去了,方便我们的就学。然后,假若您有不懂的地点,请不要来问我,没错,是不要,我并不欢迎您找我来交换,自己一点一点去弄领悟。因为,即使连那样基本的canvas效果都不亮堂,我的确也帮不了你哪些。倒不是说腾不出时间,而是腾不出精力,每日搜狐私信还有邮箱找我的人还挺多,实在应接不暇。

动画

一帧一帧的来渲染这几个因素,而且以此元素每一帧的地点都不一样,大家的眼睛看看的就是卡通片了。已毕起来也很方便,js提供了多少个主意:setTimeout 和setInterval都得以兑现,不过一个有逼格的程序员达成动画是不会用那三个格局的,而是用requestAnimationFrame以此点子。有何样界别吧?下边简单做个比较。

  • setInterval(myFun, 10);
    意思是隔一微秒执行一个myFun函数,不过这么就有一个标题了,比如我myFun函数里面绘制的东西相比较耗时,而10ms之内还不曾完全绘制出来,不过那段代码强制1ms从此又伊始绘制下一帧了,所以就会并发丢帧的难点;反之,如果时间设置太长,就会出现画面不流畅、视觉卡顿的问题。
  • requestAnimationFrame(myFun);
    借使大家如此写,又是怎么着看头啊?意思是根据早晚的时日距离,会活动执行myFun函数来拓展绘图。那个”一定的光阴距离”就是基于浏览器的习性如故网速快慢来支配了,总而言之,它会保险你绘制完这一帧,才会绘制下一帧,保险品质的还要,也有限援助动画的通畅

中央步驟:

  1. 清空 canvas

只有接下去要画的内容会完全充满 canvas
(例如背景图),否则你须要清空所有。最简便易行的做法就是用 clearRect 方法。

  1. 保存 canvas 状态

如若您要转移一些会转移 canvas
状态的设置(样式,变形之类的),又要在每画一帧之时都是本来状态以来,你须要先保存一下。

  1. 绘图动画图形(animated shapes)

这一步才是重绘动画帧。

  1. 恢复 canvas 状态

只要已经保存了 canvas 的情况,可以先过来它,然后重绘下一帧。

这边首先介绍canvas所有接口的运用。包含beginpath,closePath,linejoin,miterlimit,translate,rotate,scale,linecap。

canvas入门

二、canvas图形效果之旋转星空

美高梅开户网址 2

图是死的,效果是活的,IE9+浏览器下,您可以狠狠地方击那里:canvas已毕的旋转星空效果demo

会合到地球上方会有很多点滴在渐渐地绕着地球转啊转,星星在闪啊闪。

像那类密集型canvas效果,一般离不开下边那多少个至关重要字:实例,随机,变化与重绘,requestAnimationFrame。

规律就是:

  1. 先画一个岗位透明度随机的静态的有数实例对象;
  2. 有一个得以改变不难地方和透明度的draw方法;
  3. 定时器跑起来,画布不停地消除与绘图,动画效果落成!

规律很不难。

本例子完结的2个困难在于:

  1. 月明星稀
    区区垂直方向实际上是个伪随机,越接近地球,星星越密集,而越往上,越稀疏。其算法如下:
JavaScript

var getMinRandom = function() { var rand = Math.random(); //
step的大小决定了星星靠近地球的聚拢程度, // step = Math.ceil(2 /
(1 - rand))就聚拢很明显 var step = Math.ceil(1 / (1 - rand)); var
arr = \[\]; for (var i=0; i&lt;step; i++) { arr.push(Math.random());
} return Math.min.apply(null, arr); };

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-10">
10
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-11">
11
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-12">
12
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f4a6436b2b195965046-1" class="crayon-line">
var getMinRandom = function() {
</div>
<div id="crayon-5b8f4a6436b2b195965046-2" class="crayon-line crayon-striped-line">
    var rand = Math.random();
</div>
<div id="crayon-5b8f4a6436b2b195965046-3" class="crayon-line">
    // step的大小决定了星星靠近地球的聚拢程度,
</div>
<div id="crayon-5b8f4a6436b2b195965046-4" class="crayon-line crayon-striped-line">
    // step = Math.ceil(2 / (1 - rand))就聚拢很明显
</div>
<div id="crayon-5b8f4a6436b2b195965046-5" class="crayon-line">
    var step = Math.ceil(1 / (1 - rand));
</div>
<div id="crayon-5b8f4a6436b2b195965046-6" class="crayon-line crayon-striped-line">
    var arr = [];
</div>
<div id="crayon-5b8f4a6436b2b195965046-7" class="crayon-line">
    for (var i=0; i&lt;step; i++) {
</div>
<div id="crayon-5b8f4a6436b2b195965046-8" class="crayon-line crayon-striped-line">
        arr.push(Math.random());
</div>
<div id="crayon-5b8f4a6436b2b195965046-9" class="crayon-line">
    }
</div>
<div id="crayon-5b8f4a6436b2b195965046-10" class="crayon-line crayon-striped-line">
 
</div>
<div id="crayon-5b8f4a6436b2b195965046-11" class="crayon-line">
    return Math.min.apply(null, arr);       
</div>
<div id="crayon-5b8f4a6436b2b195965046-12" class="crayon-line crayon-striped-line">
};
</div>
</div></td>
</tr>
</tbody>
</table>

很大概率会返回一个数值偏小的值,于是,就可以有“月明星稀”的分布效果了。
  1. 圆弧轨迹
    实质上很简短,我们套用高中时候学的圆方程式就可以了,如下注释截图所述:
    美高梅开户网址 3那下标题就简单了,已知a,b,
    求y相对于x的函数表明式……

高等动画

卡通重假如requestAnimationFrame方法,现在我们来兑现一个在画布内滚动的实例

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var ball = {    //小球属性,原点位置,速度,半径等。
    x: 100,  
    y: 100,
    vx: 4,
    vy: 2,
    radius: 20,
    color: 'blue',
    draw: function() {
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true);
        ctx.closePath();
        ctx.fillStyle = this.color;
        ctx.fill();
    }
};
function draw() {
    ctx.clearRect(0,0, canvas.width, canvas.height);    //绘制之前清除整个画布
    ball.draw();   //在画布中绘制小球
    ball.x += ball.vx;   //改变小球位置坐标
    ball.y += ball.vy;   //改变小球位置坐标
    if (ball.y + ball.vy > canvas.height-15 || ball.y + ball.vy < 15) {   //边界判断
        ball.vy = -ball.vy;
    }
    if (ball.x + ball.vx > canvas.width-15 || ball.x + ball.vx < 15) {   //边界判断
        ball.vx = -ball.vx;
    }
    window.requestAnimationFrame(draw);   //循环执行
}
draw();

简单概括一下这个实例的实现思想:

制造一个小球对象,包蕴一个制图自己的法门。在整整画布中绘制这么些小球,然后在下三回绘制以前,先消除整个画布,改变小球的逐条属性(包括了逻辑,比如边界的论断),然后重新绘制三回,从而达成了动起来的功能。

若果你把下边代码中的ctx.clearRect(0,0, canvas.width, canvas.height);互换上面那样:

ctx.fillStyle = 'rgba(255,255,255,0.3)';
ctx.fillRect(0, 0, canvas.width, canvas.height);

就可以取得渐变尾巴的效果,几乎意思就是使用半透明的白色背景填充画布来代替直接清除这个画布,从而完毕了想要的效应。

本课起始前,要明了canvas的开创,怎么样绘制直线,多边形,弧线,圆。

正文头阵于自家的村办博客:http://cherryblog.site/
github项目地址:https://github.com/sunshine940326/canvasStar
品种示范地址:https://sunshine940326.github.io/canvasStar/

三、canvas图形效果之雪花噪点效果

美高梅开户网址 4

图是死的,效果这里也是死的,但并不妨碍我们零距离围观,您可以狠狠地方击那里:canvas完毕的噪点效果demo

由于此地是静态的,所以但从那一点来看,似乎比地点星空简单。可是,假若一味看绘制一帧,那那里的噪点要比地点的星空要忙绿些,最大的难点在于对品质的把控。

这样说吗,上面的星空,总共最多就400个点(白色的个别),不过,那里的噪点,例如,demo中画布大小(那我的电话机举例)是1920*500,其中,噪点大小是1像素*1像素,总共就有960000个绘制点,分明跟400个点完全不是一个数量级的,若是大家真正一个一个绘制下来,肯定,就连Chrome这么牛步的浏览器也会觉得到明确的卡顿,怎么样优化如何绘制呢?

这就是本例子达成的难关:

  1. 数据与特性
    本人那边是如此处理的,固然最终的噪点大小是1920*500,可是,大家实在是由N块300*150的小的像瓷砖同样的小方块拼起来的。话句话说,我实在只绘制了45000个点,比960000眼看要小了20倍还不止。这样,既满意了意义,又确保了品质。

切切实实贯彻原理为:

  1. 创建一个canvas,绘制一个300*150肆意噪点图形;
  2. 把那边拥有噪点的canvas以画布格局在绘制到页面上的大canvas上;

说得canvas绘图,不得不提一下不行常用的一个drawImage()主意,语法如下:

context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

1
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

梯次参数示意为(网上的描述都是直译,很别扭,我那里再度陈述了下):

参数 描述
img 用来被绘制的图像、画布或视频。
sx 可选。img被绘制区域的起始左上x坐标。
sy 可选。img被绘制区域的起始左上y坐标。
swidth 可选。img被绘制区域的宽度。
sheight 可选。img被绘制区域的高度。
x 画布上放置img的起始x坐标。
y 画布上放置img的起始y坐标。
width 可选。画布上放置img提供的宽度。(伸展或缩小图像)
height 可选。画布上放置img提供的高度。(伸展或缩小图像)

本例的小的噪点区块就是由此drawImage()艺术被平铺到大的canvas元素上的。

像素操作

假诺大家想对一个canvas画布进行如下操作:获取每一个点的音讯,对每一个坐标点进行操作。那我们就须求领悟一下ImageData对象了。

ImageData对象(由getImageData方法赢得的)中储存着canvas对象实际的像素数量,它包罗以下多少个只读属性:

  • width

图片宽度,单位是像素。

  • height

图形高度,单位是像素。

  • data

Uint8ClampedArray类型的一维数组,包蕴着RGBA格式的整型数据,范围在0至255里边(包蕴255)。简单讲,就是一个数组,每多个元素存储一个点的水彩音讯,那多少个因素分别对应为R、G、B、A的值(知道颜色取值的一眼就知晓了,不精通的也没涉及,前面有实例,一看就精通)。

更加复杂的动画片进程,还要等绘制学完之后,才能拿下。

[toc]

四、canvas图形效果之平流雾缭绕效果

美高梅开户网址 5

图是死的,效果是活的,IE9+浏览器下,您可以狠狠地方击那里:canvas达成的气团雾缭绕效果demo

本例子,效果看上去要更酷一些,实际上,从技术层面讲,跟上边的星空旋转效果大概如出一辙,可能还要比星空更简美素佳儿(Nutrilon)些,因为其运动轨迹直来直往,不必要转圈圈。

那为啥看起来更酷呢,首要在于感觉谷雾很难去模拟。

正确,混合雾确实很难用代码直接绘制出来,实际上,那里的云烟,是一个png图片,是选取画笔在PS里绘制导出来的。

旋转星空的例证,我们是使用canvas的fillRect主意绘制了不难,而本例子,则是选择方面提到的drawImage()情势把平流雾图片绘制进来了。

其余的运动啊,透明度变化什么的,原理都是相近。

本例子的困难紧要在于模拟是或不是丰裕真实:

  1. 高处不胜寒
    越往上,平流雾越淡,实际上就是越接近上方,透明度越低;
// 越靠近边缘,透明度越低 // 纵向透明度变化要比横向的明显 this.alpha
= (1 - Math.abs(canvasWidth\*0.5 - this.x) / canvasWidth) \* (0.7 -
Math.abs(canvasHeight\*0.5 - this.y) / canvasHeight);

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f4a6436b3d419634939-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b3d419634939-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b3d419634939-3">
3
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f4a6436b3d419634939-1" class="crayon-line">
// 越靠近边缘,透明度越低
</div>
<div id="crayon-5b8f4a6436b3d419634939-2" class="crayon-line crayon-striped-line">
// 纵向透明度变化要比横向的明显
</div>
<div id="crayon-5b8f4a6436b3d419634939-3" class="crayon-line">
this.alpha = (1 - Math.abs(canvasWidth*0.5 - this.x) / canvasWidth) * (0.7 - Math.abs(canvasHeight*0.5 - this.y) / canvasHeight);
</div>
</div></td>
</tr>
</tbody>
</table>
  1. 缭绕
    所谓“缭绕”,就是运动看似不抱有规律性。要了然,凡事有轨道有套路的运动都是有规律性地,你说那辐射雾上上下下,左左右右运动太过头规律,效果就会削减,可是,真的没有规律又倒霉通过代码控制移动轨迹。由此,为了搞到一个看似缭绕效果的运动函数,还真是烧了好多脑细胞。
创建ImageData对象

去成立一个新的,空白的ImageData对像,你应有会利用createImageData()方法:

var myImageData = ctx.createImageData(width, height);

上边代码成立了一个新的有血有肉特定尺寸的ImageData对像。所有像素被预设为透明黑。

各样接口一个小的示范性程序,启示怎样将那一个接口使用在实际的环境中。

前边看来了一个很为难的canvas效果,然后拿来做自我的博客背景,不少童鞋留言说求教程,并且影响说太耗内存,于是前一段我就重写了一回,并且应用离屏渲染举办优化,效果仍然挺鲜明的。不过因为毕竟是canvas,须求一直进行重绘,所以仍旧比较耗内存的,不过比优化往日曾经好广大了。并且最近备选自己写插件,于是就拿那些练手了,

五、canvas动效与结语

正文四个例证都是canvas 2D效果,是入门学习分外好的事例。

canvas卓殊适合完成密集型图形和动画,可以把质量优势给发挥出来,因为就是一块画布渲染;其它一些就是省流量,比方说第2个例子的噪点效果,如若是同样效果1920*500的png图片,科科,我越发保存了下,286K,1K的代码PK
286K的图样,显明是完爆啊!

canvas还支持3D效果,也就是webGL, 亦称3D Canvas graphics,
IE11+支持,目前Android
4.*随便版本都还不协助,业内盛名的相关库就是threejs了。

不过,我没探究过,也没兴趣,不是自己的可行性。

好了,就那么些,感谢阅读。

1 赞 7 收藏 1
评论

美高梅开户网址 6

赢得像素数据

为了拿走一个涵盖画布场景像素数据的ImageData对像,你可以用getImageData()方法

var myImageData = ctx.getImageData(left, top, width, height);

创设的myImageData对象就有width、height、data多个特性的值了。看上面这么些实例:

html:

<div id="color">hover处的颜色</div>
<canvas id="myCanvas" width="300" height="150"></canvas>

js:

var can = document.getElementById('myCanvas');
var ctx = can.getContext('2d');
var img = new Image();
    img.src = "***.jpg";
ctx.drawImage(img, 0, 0);
var color = document.getElementById('color');
function pick(event) {
    var x = event.layerX;
    var y = event.layerY;
    var area = ctx.getImageData(x, y, 1, 1);  //创建ImageData对象
    var data = area.data;   //获取data属性(一个存储颜色rgba值的数组)
    var rgba = 'rgba(' + data[0] + ',' + data[1] + ',' + data[2] + ',' + data[3] + ')';
    color.style.color =  rgba;
    color.textContent = rgba;
}
can.addEventListener('mousemove', pick);

Canvas基础回归:

github地址:https://github.com/sunshine940326/canvasStar

在气象中写入像素数据

您可以用putImageData()艺术去对现象举办像素数据的写入

ctx.putImageData(myImageData, x, y);  //在画布的(x, y)点开始绘制myImageData所存储的像素信息。

于是大家得以把获获得的像素新闻实行拍卖,然后再重新绘制,就得到了新的图片。看看上边这么些实例:

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = '***.jpg';
ctx.drawImage(img, 0, 0);
var imageData = ctx.getImageData(0,0,canvas.width, canvas.height);  //获取ImageData
var colors = imageData.data;  //获取像素信息
function invert() {
    for (var i = 0; i < colors.length; i += 4) {  //四个为一组
        colors[i]     = 225 - colors[i];     // red
        colors[i+1] = 225 - colors[i+1]; // green
        colors[i+2] = 225 - colors[i+2]; // blue
        colors[i+3] = 255;   //alpha
    }
    ctx.putImageData(imageData, 220, 0);  //从(220, 0)开始绘制改变过的颜色
}
function toGray() {
    for (var i = 0; i < colors.length; i += 4) {
        var avg = (colors[i] + colors[i+1] + colors[i+2]) / 3;  
        colors[i] = avg; // red
        colors[i+1] = avg; // green
        colors[i+2] = avg; // blue
        colors[i+3] = 255;   //alpha
    }
    ctx.putImageData(imageData, 440, 0); //从(440, 0)开始绘制改变过的颜色
}
invert();   //反转色
toGray();   //变灰色

制图一条直线

在HTML中 <canvas id=”canvas”> </canvas> 创建canvas标签。

在JavaScript中 

var canvas = document.getElementById(“canvas”) //得到canvas一个变量

var context = canvas.getContext(“2d”)
//得到canvas的一个2d的绘图上下文环境。

//使用context举行绘图。canvas绘图的有所接口都是拔取context的那些上下文环境提供。

当前只举办2d绘图,3D是一点一滴不相同的。

美高梅开户网址 7

context.moveTo(100,100)是笔尖放到这些地点,然后context.lineTo(700,700),将要画到那几个地方,不过此间注意,只是一个情况,而context.stroke()才是画出来。

美高梅开户网址 8

第一成立一个canvas标签,也像其余标签一样,可以安装相关的体制。然后在js中,获取这一个canvas,设置宽高,画线。

美高梅开户网址 9

美高梅开户网址 10

canvas是依据状态的绘图,所以都是先安装好状态,然后绘制。那么还有哪些情状吧?那里有线的宽窄,linewidth和strokeStyle。宽度和线条的样式。那里根本是颜色。也就是说,canvas是基于线条的动静绘制,不是按照对象。大家不是先创立一个canvas的靶子,然后设置它的依次属性。对完全安装景况,然后绘制。

美高梅开户网址 11

怎么样画折线?再来一个lineTo

美高梅开户网址 12

一致画一个三头形,一个moveTo,三个lineTo,画一个箭头。

美高梅开户网址 13

一个moveTo,三次起笔。

假定要绘制三条不一样颜色的折线怎么做呢?分析下边代码对不对?

美高梅开户网址 14

那是有标题标。因为canvas是场所加绘制。所以下边的情状会覆盖上边的情况。所以效果是底下:

美高梅开户网址 15

第一段绘制没难题,但是第二段绘制的时候,context.strokeStyle=“green”
覆盖了上边的水彩。同样第二回,会将方面装有的线又绘制了几回,将享有情状完成五次绘制。为灰色。

引出:context.beginPath(),阐明从现在开班要开展一段全新的绘图。当使用beginPath之后,再指定新的门径,再调用绘制的函数,比如stroke(),将绘制从context.beginPath()到context.stroke()之间的状态来展开具体的绘图。

美高梅开户网址 16

各类beginPath都是一个从新开始绘制。

美高梅开户网址 17

留神context.lineWidth=10,平素在最终边,在context.beginPath()之后,假设一个特性一直从未遮盖的话,将直接保持该情况。而strokeStyle一直被遮住,所以将用被遮盖的属性值。一定要区分哪些性质被掩盖,什么性质一直保持着。

首先个beginPath可以大约。

beginPath起初一个簇新的途径,moveTo从某点起头,lineTo画到那几个点。当使用beginPath之后,第四个moveTo能够换成lineTo,因为上一个坐标点被beginPath清空了。

美高梅开户网址 18

制图封闭的图像,只要首位相连就好了

美高梅开户网址 19

美高梅开户网址 20

而是有一个小缺点,就是缝合处。因为线段相比较宽,假使相比窄,一个像素,就不会有那么些难点。

更好的封闭的办法,就是beginPath喝closePath成对出现,那么画出来的造型就是封闭的。

美高梅开户网址 21

美高梅开户网址 22

美高梅开户网址 23

美高梅开户网址 24

美高梅开户网址 25

明日就到家封闭了。关于closePath还有一些,假如最后一个lineTo没有写,仍然是半自动用直线将最终一个点总是首个点。

美高梅开户网址 26

美高梅开户网址 27

一个填写的颜料,加一个进展填写。下边具体事例:

美高梅开户网址 28

美高梅开户网址 29

里面有了填充色,而且线条有10个像素,可是其中的5个像素被填充了,要化解那几个标题,肯定是先填充,后对线条描边。

美高梅开户网址 30

美高梅开户网址 31

没难点了呢

fillstyle和strokeStyle都是对情状的定义。context基于状态的绘图的,所以可以把所有的情景放在一起,再把具有的绘图放在一块儿,那样也是不影响结果的。如下

context.lineWidth = 10 

context.fillStyle = “yellow”

context.strokeStyle = “#058”

//以上都是意况

context.fill()

contex.stroke()

//举办绘图

美高梅开户网址 32

盛传参数,cxt上下文环境,就是传播的context,x,y绘制的序幕地点。矩形的宽和高,边框的宽和颜色,填充色。

美高梅开户网址 33

美高梅开户网址 34

绘制中矩形比较多,所以有特意的矩形绘制函数,rect(x,y,width,height),绘制的源点,宽和高。

美高梅开户网址 35

那五个结实是同一的。还有更有利的三个:

美高梅开户网址 36

fillRect使用当前的fillStyle,而strokeRect使用strokeStyle绘制当前的矩形边框。和rect()差异是,rect()状态,还亟需绘制一下,可是fillRect和strokeRect间接绘制出来了。

美高梅开户网址 37

看那多少个有分其余。

美高梅开户网址 38

后绘制的图片会遮掩前边绘制的图纸。

美高梅开户网址 39

支撑css协助的体制

美高梅开户网址 40

美高梅开户网址 41

美高梅开户网址 42

美高梅开户网址 43

美高梅开户网址 44

美高梅开户网址 45

代码还有好多的阙如,求大神 review (づ。◕‿‿◕。)づ~

属性优化

  • 坐标点尽量用整数

浏览器为了达到抗锯齿的效用会做额外的运算。为了防止这种状态,请确保使用canvas的绘图函数时,尽量用Math.floor()函数对拥有的坐标点取整。比如:

ctx.drawImage(myImage, 0.3, 0.5);  //不提倡这样写,应该像下面这样处理
ctx.drawImage(myImage, Math.floor(0.3), Math.floor(0.5));
  • 使用多个画布绘制复杂气象

例如做一个游戏,有多少个规模:背景层(简单变化)、游戏层(时刻变化)。这些时候,大家就足以创建多个画布,一个专门用来绘制不变的背景(少量绘制),另一个用来绘制游戏动态部分(多量制图),似乎那样:

<canvas id="background-can" width="480" height="320"></canvas>
<canvas id="game-can" width="480" height="320"></canvas>
  • 用CSS设置静态大图

尽管有一层是永远不变的,比如一张静态的背景图,最好使用div+css的方法去替代ctx.drawimage(),这么做可以幸免在每一帧在画布上制图大图。不难讲,dom渲染肯定比canvas的操作品质更高。

  • 尽量少操作canvas的缩放

万一要对一个画布进行缩放,假若得以的话,尽量使用CSS3的transform来落实。不问可知,记住一个准绳,能用html+div完结的玩命不要js对canvas举办操作。

  • more
  1. 将画布的函数调用集合到一起(例如,画一条折线,而不用画多条分开的直线)
  2. 动用差距的法门去排除画布(clearRect()、fillRect()、调整canvas大小)
  3. 尽可能防止 shadowBlur特性
  4. 有动画,请使用window.requestAnimationFrame()
    而非window.setInterval()

线条的属性

linewidth就是线条属性的一种

线条的帽子:lineCap

设置线条两端的意况,默许是butt,仍是可以是round和square,圆头和方头。

切实如下:

美高梅开户网址 46

美高梅开户网址 47

美高梅开户网址 48

round是一个圆形的头,square是方形的头。butt是没有的。注意lineCap只可以用来线段的启幕和结尾处,无法用于线段的连接处。

美高梅开户网址 49

在起先的地方,是圆头,都是在接连的地方,是尖角。

美高梅开户网址 50

上边没有beginPath和closePath时候,最终的连日是不缝合的。

美高梅开户网址 51

加上context.linCap = ”square”时候

美高梅开户网址 52

是因为square是方形的头,所以会活动补上。不过闭合的图样,仍然提议利用beginPath和closePath。

canvas 基本知识

画一个五角星

美高梅开户网址 53

美高梅开户网址 54

大圆上七个点,小圆上四个点,可以求出左边大圆上和小圆的点,下一个点离开72度,所以可以透过一个巡回,遍历八个点。

美高梅开户网址 55

cos和sin函数里先角度转弧度。400是将圆心给移动一下。

为了能复用这一个五角星,给它有些变量:r小圆半径,R大圆半径,x,y圆心偏移量。

美高梅开户网址 56

调用一下drawStar(context,150,300,400,400)就可以了。

再改进一下,增添一个rot,旋转的角度。

美高梅开户网址 57

转30度自此的楷模

美高梅开户网址 58

线条的链接:lineJoin和miterLimit

lineJoin线条和线条相交的时候,所显示的事态,默许miter尖角,bevel谢姐,round圆角方式。

尖角正如:

美高梅开户网址 59

context.lineJoin=bevel 斜接是下边那一个样子:

美高梅开户网址 60

线条顶端不会成一个角。round是上面样子

美高梅开户网址 61

美高梅开户网址 62

看一下miterLimit的意思,默认是10个像素。唯有lineJoin为miter的时候会有其一界定,假诺超miterLimit过10个像素,就会把lineJoin变成bevel方式。如下:

美高梅开户网址 63

lineJoin为miter的时候,应该是尖角,不过把内圆改小一些,让尖角更尖。实际如下,因为当先了10像素。

美高梅开户网址 64

不过把miterLimit改成20之后,就足以健康展现了

美高梅开户网址 65

美高梅开户网址 66

美高梅开户网址 67

美高梅开户网址 68

=

什么是 canvas

canvas 是 HTML5 新定义的价签,通过行使脚本(常常是
JavaScript)绘制图形。
<canvas> 标签只是图形容器,相当于一个画布,canvas
元素本身是从未绘图能力的。所有的绘图工作必须在 JavaScript
内部形成,相当于选择画笔在画布上描绘。

默许情况下,<canvas> 没有边框和情节。默许是一个 300150
的画布,所以我们创造了 <canvas> 之后要对其设置宽高。
**大家能够透过html属性‘width’,‘height’来设置canvas的宽高,不可以通过
css 属性来设置宽高。因为经过 css 属性设置的宽高会使 canvas 内的图像根据300
150 时的百分比放大或裁减**

图片变换

美高梅开户网址 69

改建画一个五角星的函数,设置填充色和边缘色。

自此在onload函数里面绘制一个黄色背景,

美高梅开户网址 70

填充矩形背景大小与canvas一样。填充色为灰色。

美高梅开户网址 71

写一个循环往复,画200个随机的星星

美高梅开户网址 72

random为随机生成0-1,然后半径为10-20,小圆半径为大圆的一半。x,y的岗位在canvas里面随机,旋转角度a为0-360里随机。每一次刷新效率不等同。四个优化:有些星星在外面,别的有些星星叠在一块儿。

美高梅开户网址 73

上边的drawStar在作用上已经能一心餍足功用了。可是承载功能太多。比如下次想画一个四角星,甚至小圆点,改起来就相比麻烦了。为了化解那个标题,

美高梅开户网址 74

那是一个制图五角星的函数,在0,0地方,半径为1,同时没有任何偏移,没有其余旋转的五角星。把这么的五角星称为标准五角星。

美高梅开户网址 75

在drawStar中,先绘制一个正规的五角星,然后再位移,改大小,旋转角度。比如之后要绘制4角星,八角形,只必要变更starPath就好了。同时那里的starPath也足以用作参数举办传递。图形学里,都是那种绘制,先绘制基本的图像,再举办旋转,改变大小等图形变换。

美高梅开户网址 76

最常用的三种图形变换。

美高梅开户网址 77

translate把基坐标的(0,0)点放到了(100,100),然后绘制。效果如图:

美高梅开户网址 78

然而有一个小陷阱:

美高梅开户网址 79

美高梅开户网址 80

一遍将来,第三个矩形的岗位,并不是300,300.而是400,400.因为基坐标的义务发生三回变动。图形变换函数是增大的。为了幸免那些陷阱,可以方向操作一下:

美高梅开户网址 81

美高梅开户网址 82

而是逆袭太费事,canvas使用save和restore,用来存储状态,再次回到状态。

美高梅开户网址 83

那四个成对出现,有限协理canvas图形绘制状态的不易。先固定一下starPath中点滴的轻重。

美高梅开户网址 84

第二位先保全和回复处境。对星星translate改变地点,然后旋转角度,绘制星星,填充色,边缘色,线宽,线交合处,填充,描边。完毕后如下:

美高梅开户网址 85

地点星星大小是一样的,下边看一下施用scale爆发怎么着难题,如下演示程序:

美高梅开户网址 86

上述画多个正方形,地点都是从50,50开头画,大小都是200,200,但是实际效果如下:

美高梅开户网址 87

美高梅开户网址 ,不光尺寸改变了,左上角的坐标也展开了操作,线条的增加率也改成了。scale是有副作用的,比如线条大小,左上角的坐标,这一个是要留意的。

美高梅开户网址 88

绘图大小随机的有限的时候,只可以是抛弃边框的绘图了,然后一个改动大小scale。

程序运行的功力如下:

美高梅开户网址 89

留意缩放的副效能。可能会扬弃一些事物的绘图,或者用大家和好的措施绘制。

美高梅开户网址 90

深远驾驭图形变换:

美高梅开户网址 91

美高梅开户网址 92

这么一个函数可以取代几个。

美高梅开户网址 93

美高梅开户网址 94

此间把水平方向缩放改成2,垂直方向改成1.5。

美高梅开户网址 95

美高梅开户网址 96

一如既往有此前的多少个负效果,地点和边框都改成了、

美高梅开户网址 97

美高梅开户网址 98

在档次和垂直方向倾斜0.2的效果。

美高梅开户网址 99

美高梅开户网址 100

历次更换的效益是在上三遍的效益之上的。级联的。然而setTransform能够无视之前的transform的法力。

美高梅开户网址 101

事先的倾斜都没用了。

美高梅开户网址 102

美高梅开户网址 103

美高梅开户网址 104

getContext()

context 是一个打包了诸多绘制成效的对象,大家在页面中开创一个 canvas
标签之后,首先要使用 getContext() 获取 canvas 的上下文环境,近年来
getContext() 的参数唯有 2d,暂时还不协理 3d

getContext("2d") 对象是内建的 HTML5
对象,拥有各类制图路径、矩形、圆形、字符以及丰盛图像的法子。

填充样式

fillStyle 除了颜色,还足以其它的。线性渐变色和镜像渐变色。

美高梅开户网址 105

多个变量,四个坐标,构成一个线条。渐变线,构成渐变方向和规则。

美高梅开户网址 106

先是个stop关键色的职位,第三个color关键色是何许颜色。上边例子:

美高梅开户网址 107

首先个addColorStop 中0.0就是早先地点,为白色,首个addColorStop
中1.0就是甘休的岗位,为青色。那样就是从左上角0,0到右下角800,800由白至黑的一个渐变色。

美高梅开户网址 108

多少个注意点

1、创设linearGrad之后,addColorStop可以增加无数个的。自己喜欢的相继添加颜色就好。

美高梅开户网址 109

渐变线还足以水平和垂直的。

美高梅开户网址 110

还足以只指定一部分,不是一体画布的。

美高梅开户网址 111

创制一个渐变到400,400,渐变利落后,其余部分显得的是潜移默化的利落时候的颜料。

仍能超越画布的最大值。外侧的黑白色不会显得了。

美高梅开户网址 112

美高梅开户网址 113

基于上面的渐变色能够更改星空的体制。创制一个渐变色,从0,0到0,canvas.height,也就是贯通整个屏幕的垂直方向。扩张三个颜色,初始点是红色,终点是湛蓝。然后把个别变小部分,别的星星的排布在上0.65的区域。如下显示:

美高梅开户网址 114

放射性的渐变:Radial Gradient

美高梅开户网址 115

多少个同心圆的底子上,6个参数:第三个圆圆点半径,第四个圆圆点半径,整个径向渐变就暴发在那多个圆环中间。

美高梅开户网址 116

第一个增进颜色。

美高梅开户网址 117

圆心400,400,半径0,就是一个点,外面圆圆心一样,半径500。添加5种颜色,

美高梅开户网址 118

内圆半径若是非0,如下:

美高梅开户网址 119

这几个圆白色,外面当先500个像素的半径为粉黄色。

美高梅开户网址 120

星空中,径向渐变开头于底层中点,如下所示:

美高梅开户网址 121

createPattern

美高梅开户网址 122

美高梅开户网址 123

上面分别是no-repeat,repeat-x和repeat-y的样式

美高梅开户网址 124

美高梅开户网址 125

美高梅开户网址 126

美高梅开户网址 127

无异于canvas画布也可以看做填充情势。

美高梅开户网址 128

始建了一个backCanvas画布,然后作为填充。

美高梅开户网址 129

开创画布,设置高宽,画星星。创制好的画布重返。

作用如下:

美高梅开户网址 130

美高梅开户网址 131

video也可以用作背景填充。

美高梅开户网址 132

美高梅开户网址 133

美高梅开户网址 134

美高梅开户网址 135

美高梅开户网址 136

相同,fillstyle也足以使用与strokestyle上面。

=

canvas 元素绘制图像

canvas 成立图形有两种方法

曲线的绘图

美高梅开户网址 137

美高梅开户网址 138

6个参数,圆心坐标,半径,开首和终结的角度,顺时针仍旧逆时针。

看这多少个绘制:第四个画10个弧,第三个弧是虚掩的,

美高梅开户网址 139

其多个个逆时针,

美高梅开户网址 140

美高梅开户网址 141

美高梅开户网址 142

圆角矩形

美高梅开户网址 143

绘图圆角矩形就能够分成上边8个部分。确认圆心就足以了。

美高梅开户网址 144

美高梅开户网址 145

调用drawRoundRect就足以了。

美高梅开户网址 146

美高梅开户网址 147

已知的有(x0,y0),根据(x1,y1),(x2,y2)绘制两条直线,然后圆弧与那三个直线相切,半径为radius。上面具体运用:

美高梅开户网址 148

绘图了一条圆弧和一个条扶助线。

美高梅开户网址 149

留意,开头点不肯定是圆弧的开头点,其余圆弧的停止点也不自然是终止点,而是切线终止点。起源不自然是切点,为止于切点,不是终点。

美高梅开户网址 150

一个制图圆弧的函数,多个点,一个半径。

一旦半径过大,会从起源早先延伸到切点,然后开头画,画到的也不是极限,而是延长线上的切点。

美高梅开户网址 151

美高梅开户网址 152

美高梅开户网址 153

美高梅开户网址 154

美高梅开户网址 155

context.fill()

fill() 方法填充当前的图像(路径)。默许颜色是青色。在填充前要先使用
fillStyle 设置填充的颜色依旧渐变,并且只要路径未关门,那么 fill()
方法会从路径停止点到初阶点时期添加一条线,以关闭该路线(正如
closePath() 一样),然后填充该路线。

贝塞尔曲线 Bezier

美高梅开户网址 156

以下二次贝塞尔曲线:

美高梅开户网址 157

网站可以查阅贝塞尔曲线绘制效果。

首先个点是控制点,第一个点是终止点。二次曲线无法绘制波浪线。

以下四次贝塞尔曲线:

美高梅开户网址 158

美高梅开户网址 159

有七个控制点,前四个是控制点,最终一个是截止点。

其余二次曲线无法像那样表面伸张

美高梅开户网址 160

美高梅开户网址 161

美高梅开户网址 162

美高梅开户网址 163

美高梅开户网址 164

美高梅开户网址 165

美高梅开户网址 166

context.font 字体的体制,fillStyle填充的水彩,fillText
填充的书体,前边参数是填充字体的职位。

美高梅开户网址 167

美高梅开户网址 168

第七个参数是最大的长度,如若设为400,效果如下

美高梅开户网址 169

美高梅开户网址 170

美高梅开户网址 171

美高梅开户网址 172

美高梅开户网址 173

美高梅开户网址 174

美高梅开户网址 175

默认是大小和字体,可以安装七个属性。font-style默许normal
,italic斜体字,oblique倾斜字体。

美高梅开户网址 176

web中或者看不出来italic和oblique的分别。

美高梅开户网址 177

自己导入的书体,可能斜体和倾斜有分别。

美高梅开户网址 178

美高梅开户网址 179

美高梅开户网址 180

小型大写字母

美高梅开户网址 181

normal通常指400,同理bold

美高梅开户网址 182

美高梅开户网址 183

美高梅开户网址 184

美高梅开户网址 185

美高梅开户网址 186

context.stroke()

stroke() 方法会实际地绘制出通过 moveTo()lineTo()
方法定义的路子。默许颜色是绿色。在进展图纸绘制前,要安装好绘图的体制

fillStyle()//填充的样式
strokeStyle()//边框样式
context.lineWidth()//图形边框宽度

文件对齐

美高梅开户网址 187

美高梅开户网址 188

美高梅开户网址 189

美高梅开户网址 190

美高梅开户网址 191

绘制矩形

用 canvas 绘制一个矩形很简短

fillRect(x,y,width,height)  // 实心矩形 
strokeRect(x,y,width,height)        // 空心矩形
  • x :初阶点的 x 坐标
  • y :开始点的 y 坐标
  • width : 矩形的宽
  • height : 矩形的高

//html代码
<canvas id="canvas"></canvas>
//script代码
   var canvas = document.getElementById('canvas');
    var context = canvas.getContext('2d');
    context.fillRect(0, 0, 100, 100);
    context.strokeRect(120, 0, 100, 100);

展现如下:

美高梅开户网址 192

canvas绘制矩形有填充颜色

大家得以看出,在一直不设置颜色的动静下,默认是青色的。

我们仍能够通过安装 fillStyle 或者 fillStyle 改变其填写颜色。

context.fillStyle = "pink";
context.strokeStyle = "darkred";
context.fillRect(0, 0, 100, 100);
context.strokeRect(120, 0, 100, 100);

作用如下

美高梅开户网址 193

canvas绘制矩形有填充颜色

排除矩形区域

clearRect(x,y,width,height)

 - x :清除矩形起始点的 x 坐标
 - y :清除矩形起始点的 y 坐标
 - width : 清除矩形矩形的宽
 - height : 清除矩形矩形的高

var canvas = document.getElementById(‘canvas’);
var context = canvas.getContext(“2d”);
context.fillRect(0, 0, 100, 100);
context.strokeRect(120, 0, 100, 100);
context.fillStyle = “pink”;
context.strokeStyle = “darkred”;
context.fillRect(0, 120, 100, 100);
context.strokeRect(120, 120, 100, 100);
context.clearRect( 50,50,120,120)

意义如下:

美高梅开户网址 194

消除矩形

实心圆

context.arc(x, y, radius, starAngle,endAngle, anticlockwise)

  • x : 圆心的 x 坐标
  • y:圆心的 y 坐标
  • radius : 半径
  • starAngle :初步角度
  • endAngle:甘休角度
  • anticlockwise :是不是逆时针(true)为逆时针,(false)为顺时针

context.beginPath();
context.arc(300, 350, 100, 0, Math.PI * 2, true);
//不关闭路径路径会一直保留下去
context.closePath();
context.fillStyle = 'rgba(0,255,0,0.25)';
context.fill();

功效如下:

美高梅开户网址 195

canvas绘制圆弧

圆弧

设若不填充颜色,实心圆就是圆弧

    context.beginPath();
    context.arc(600, 350, 100, 0, Math.PI , true);
    context.strokeStyle = 'pink';
    context.closePath();
    context.stroke();

    context.beginPath();
    context.arc(300, 350, 100, 0, Math.PI , true);
    context.strokeStyle = 'red';
    //没有closePath
    context.stroke();

功用如图:

美高梅开户网址 196

canvas绘制圆弧

  • 系统默许在绘制第二个途径的上马点为beginPath
  • 比方画完前边的不二法门没有重新指定beginPath,那么画第其她路径的时候会将前方近年来点名的beginPath后的方方面面路径重新绘制
  • 老是调用context.fill()的时候会自行把当次绘制的途径的起来点和截至点相连,接着填充封闭的有些

之所以说,即使首个圆弧没有 closePath() 并且第三个圆弧没有
beginPath() 的话就是那般的效劳:

美高梅开户网址 197

canvas绘制矩形

绘图线段

  • moveTo(x,y):把路子移动到画布中的指定点,不创设线条
  • lineTo(x,y):添加一个新点,然后在画布中成立从该点到终极指定点的线条
  • 老是画线都从 moveTo 的点到 lineTo 的点,

    context.strokeStyle = 'pink';
    context.moveTo(0, 0);
    context.lineTo(100, 100);
    context.stroke();*/

职能如下:

美高梅开户网址 198

canvas绘制片段

若是没有 moveTo 那么首先次 lineTo 的功力和 moveTo 一样,
例如:

    context.strokeStyle = 'pink';
    context.lineTo(100, 100);
    context.lineTo(200, 200);
    context.stroke();*/

意义如下:

美高梅开户网址 199

canvas绘制线段

历次lineTo后假设没有moveTo,那么下次lineTo的先河点为前一次lineTo的为止点
例如:

// 绘制片段
    context.strokeStyle = 'pink';
    context.lineTo(200, 200);
    context.lineTo(200, 100);
    context.lineTo(100,50);
    context.stroke();

作用如下:

美高梅开户网址 200

canvas绘制线段

俺们得以选择 canvas 的线条绘制各样种种的图形,比如绘制一个六边形

var n = 0;
    var dx = 150;
    var dy = 150;
    var s = 100;
    context.beginPath();
    context.fillStyle = 'pink';
    context.strokeStyle = 'rgb(0,0,100)';
    var x = Math.sin(0);
    var y = Math.cos(0);
    var dig = Math.PI / 15 * 5;
    for (var i = 0; i < 6; i++) {
        var x = Math.sin(i * dig);
        var y = Math.cos(i * dig);
        context.lineTo(dx + x * s, dy + y * s);
        console.log( x ,y )
    }
    context.closePath();
    context.fill();
    context.stroke();

美高梅开户网址 201

动用canvas绘制六边形

绘制 30 角形:

var n = 0;
    var dx = 150;
    var dy = 150;
    var s = 100;
    context.beginPath();
    context.fillStyle = 'pink';
    context.strokeStyle = 'rgb(0,0,100)';
    var x = Math.sin(0);
    var y = Math.cos(0);
    var dig = Math.PI / 15 * 7;
    for (var i = 0; i < 30; i++) {
        var x = Math.sin(i * dig);
        var y = Math.cos(i * dig);
        context.lineTo(dx + x * s, dy + y * s);
        console.log( x ,y )
    }
    context.closePath();
    context.fill();
    context.stroke();

职能如下:

![canvas绘制 30
脚形](http://img.blog.csdn
.net/20170804152344651?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3Vuc2hpbmU5NDAzMjY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

线性渐变

var lg= context.createLinearGradient(xStart,yStart,xEnd,yEnd)
lg.addColorStop(offset,color)

  • xstart:渐变开头点x坐标
  • ystart:渐变开头点y坐标
  • xEnd:渐变截至点x坐标
  • yEnd:渐变截至点y坐标
  • offset:设定的颜色离渐变甘休点的偏移量(0~1)
  • color:绘制时要运用的颜料

例如:

    var g1 = context.createLinearGradient(0, 0, 0, 300);
    g1.addColorStop(0, '#E55D87'); 
    g1.addColorStop(1, '#5FC3E4');
    context.fillStyle = g1;
    context.fillRect(0, 0, 400, 300);

效果如下:

美高梅开户网址 202

canvas绘制渐变

通向渐变

var rg=context.createRadialGradient(xStart,yStart,radiusStart,xEnd,yEnd,radiusEnd)
rg.addColorStop(offset,color)

  • xStart:发散初始圆心x坐标
  • yStart:发散初始圆心y坐标
  • radiusStart:发散早先圆的半径
  • xEnd:发散截至圆心的x坐标
  • yEnd:发散停止圆心的y坐标
  • radiusEnd:发散停止圆的半径
  • offset:设定的颜色离渐变为止点的偏移量(0~1)
  • color:绘制时要运用的颜料

美高梅开户网址 203

通向渐变原理

例如:

// 同心圆径向渐变
    var g1 = context.createRadialGradient(200, 150, 0, 200, 150, 200);
    g1.addColorStop(0.1, '#F09819');
    g1.addColorStop(1, '#EDDE5D');
    context.fillStyle = g1;
    context.beginPath();
    context.arc(200, 150, 100, 0, Math.PI * 2, true);
    context.closePath();
    context.fill();

美高梅开户网址 204

canvas绘制同心圆径向渐变

//不同圆心的径向渐变模型
    var g1 = context.createRadialGradient(100, 150, 10, 300, 150, 80);
    g1.addColorStop(0.1, '#F09819');
    g1.addColorStop(0.8, 'red');
    g1.addColorStop(1, '#EDDE5D');

    context.fillStyle = g1;
    context.fillRect(0, 0, 300, 500);

效果图:

美高梅开户网址 205

不等圆心径向渐变

图形变形

缩放

scale(x,y)

  • x :x坐标轴按 x 比例缩放
  • y :x坐标轴按 y 比例缩放

旋转

rotate(angle)

  • angle :坐标轴转动x角度(角度变化模型和画圆的模子一样)

平移

translate(x,y)

  • x :坐标原点向x轴方向平移x
  • y :坐标原点向y轴方向平移y

挪动,缩放,旋转先后顺序差别,坐标轴的变化图,图片来源互连网:

美高梅开户网址 206

平移缩放旋转先后顺序不一致坐标轴的变化图

图片组成

globalCompositeOperation=type
设置或回到新图像怎样绘制到已有些图像上。最后的机能取决于 type 的值
type:

  • source-over(默许值):在原来图形上绘制新图片
  • destination-over:在原始图形下绘制新图片
  • source-in:突显原有图形和新图片的搅和,新图片在上,所以颜色为新图片的颜料
  • destination-in:显示原有图形和新图片的混杂,原有图形在上,所以颜色为原本图形的颜色
  • source-out:只体现新图片非交集部分
  • destination-out:只突显原有图形非交集部分
  • source-atop:呈现原有图形和交集部分,新图片在上,所以交集部分的颜色为新图片的水彩
  • destination-atop:突显新图片和混合部分,新图片在下,所以交集部分的颜料为原本图形的颜色
  • lighter:原有图形和新图片都呈现,交集部分做颜色叠加
  • xor:重叠飞部分不现实
  • copy:只浮现新图片
    功效图如下,图片来自网络

美高梅开户网址 207

效果图

阴影

shadowOffsetX:设置或返回阴影距形状的水平距离(默认值为 0)
shadowOffsetY:设置或返回阴影距形状的垂直距离(默认值为 0)
shadowColor:设置或返回用于阴影的颜色
shadowBlur:设置或返回用于阴影的模糊级别(值越大越模糊)

例如:

    context.fillStyle = 'white';
    context.beginPath();
    context.arc(100,100,10,0,2 * Math.PI);
    context.shadowColor = 'white';
    context.shadowBlur = 10;
    context.fill();
    context.closePath();

大家看来的效果就是我们在初阶提起的事例中的 star
粒子的效率,因为其有白色阴影的效应,所以看起来像是发光一样,效果如下图:

美高梅开户网址 208

带阴影效果的圈子

图像绘制

drawImage()
向画布上绘制图像、画布或录像

  • 在画布上一定图像:context.drawImage(img,x,y);
  • 在画布上一直图像,并确定图像的大幅度和可观:context.drawImage(img,x,y,width,height);
  • 分开图像,并在画布上稳定被细分的有的:context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
  • img:规定要使用的图像、画布或摄像。
  • sx:可选。初叶剪切的 x 坐标位置。
  • sy:可选。开端剪切的 y 坐标地点。
  • swidth:可选。被分割图像的增进率。
  • sheight:可选。被分开图像的冲天。
  • x:在画布上放置图像的 x 坐标地点。
  • y:在画布上放置图像的 y 坐标地方。
  • width:可选。要使用的图像的增进率。(伸展或裁减图像)
  • height:可选。要运用的图像的可观。(伸展或裁减图像)

美高梅开户网址 209

canvas绘制图形例子

图像平铺

createPattern(image,type)
type:

  • no-repeat:不平铺
  • repeat-x:横方向平铺
  • repeat-y:纵方向平铺
  • repeat:全方向平铺

图像裁剪

clip()从原始画布剪切任意形状和尺寸的区域,须要先创立裁剪区域,再绘制图像;一旦剪切了某个区域,则具有之后的绘图都会被限定在被细分的区域内(不可以访问画布上的别样区域)。您也可以在运用
clip() 方法前经过运用 save()
方法对现阶段画布区域开展封存,并在后头的轻易时间对其开展回复(通过
restore() 方法)。
例如:

    // 设置剪切区域(粉色矩形)
    context.rect(0,0,500,400);
    context.fillStyle = "pink";
    context.fill();
    context.clip();

    // 在剪切区域中绘制图形(白色矩形)
    context.fillStyle = "white";
    context.fillRect(10,10,100,100);

    // 之后绘制的图形只能显示在剪切区域之内(红色矩形)
    context.fillStyle = "red";
    context.fillRect(100,100,600,600)

效果如下:可以看来大家设置的新民主主义革命矩形是一个 600600
的矩形,不过明显是没有突显完的,一旦剪切了某个区域,则具有之后的绘图都会被限制在被剪切的区域内(不能访问画布上的其余区域)。
*

美高梅开户网址 210

canvas进行图像剪切

因此说大家得以在应用 clip() 方法前透过利用 save()
方法对当下画布区域拓展封存,并在之后的轻易时间对其举行还原(通过
restore() 方法)。
代码如下:

context.save();
    // 设置剪切区域
    context.rect(0,0,500,400);
    context.fillStyle = "pink";
    context.fill();
    context.clip();

    // 在剪切区域中绘制图形
    context.fillStyle = "white";
    context.fillRect(10,10,100,100);

    context.restore();
    // 之后绘制的图形只能显示在剪切区域之内
    context.fillStyle = "red";
    context.fillRect(100,100,600,600)

如此那般就足以健康显示了:

美高梅开户网址 211

canvas进行图像裁剪

制图文字

fillText(text,x,y):绘制实心文字
strokeText():绘制文字描边(空心)
textAlign:设置或返回文本内容的当前对齐方式
textBaseline:设置或返回在绘制文本时使用的当前文本基线
font:设置或返回文本内容的当前字体属性

例如:

    context.font="40px Arial";
    context.fillText("Hello world",200,200);
    context.strokeText("Hello world",200,300)

职能如下:

美高梅开户网址 212

canvas绘制文字

准备干活

好的开首是打响的一半

简言之介绍了下 canvas 的常用
api,大家发现是或不是也从没那么难啊( ̄▽ ̄)*,那么让我们回到标题,一起来看一下这么些姑娘心满满的例子是何许贯彻的~

canvas 其实写一个炫酷的特效在技术上并不难,难的是您的创意,因为 canvas
完毕粒子的效劳仍旧比较惊艳的,但实则代码都是相比简单的,无非就是随便的创办图形或者路径,当然图形也是虚掩的门路。在添加一定的运动就可以了。然而你要规划出一个好的特效是那多少个不简单的。

为此我们就先来分析一下这几个功效由那几有的构成,将其拆分开来。

特效pc端演示地址:https://sunshine940326.github.io/canvasStar/
(当然,可以平素查看自己的博客,背景暂时就是那个,不精通哪一天会变,捂脸ing:http://cherryblog.site/)

解析 star 的显现和表现

我们得以将其一向位移向上的粒子称为 star,大家观看 star 的特性:

  • 先河创办时地方随机(坐标随机)
  • 透明度随机
  • 创立时的高低在必然限制内(半径在自然范围内)
  • 匀速上涨
  • 总数不变

因此大家就足以统计出 star
的特征就是总数固定,成立时坐标和半径还有透明度随机,匀速上升。是还是不是很不难了吧\[\]( ̄▽ ̄)~*

分析 dot 的表现和行为

再让我们来看一下乘机鼠标移入发生的粒子,大家称为 dot,同理,大家着眼得到dot 的特色

  • 列表内容
  • 鼠标移动时发出
  • 新暴发的 dot 和事先的 3 个 dot 发生连线
  • 向周围移动
  • 落成自然原则没有

诸如此类,大家就已毕了一半了吗~将事件屡清楚之后大家就足以先河开始撸代码了!

背景的 HTML 和 CSS

事实上需求的 HTML 代码和 CSS 代码很简答的,HTML
只需求一行就足以了呢,设置一个渐变的背景蒙层和一个 canvas 标签。

HTML 和 CSS 如下:

<div class="filter"></div>
<canvas id="canvas"></canvas>

html, body {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            overflow: hidden;
            background: black;
            background: linear-gradient(to bottom, #dcdcdc 0%, palevioletred 100%);
        }

        #main-canvas {
            width: 100%;
            height: 100%;
        }

        .filter {
            width: 100%;
            height: 100%;
            position: absolute;
            top: 0;
            left: 0;
            background: #fe5757;
            animation: colorChange 30s ease-in-out infinite;
            animation-fill-mode: both;
            mix-blend-mode: overlay;

        }

        @keyframes colorChange {
            0%, 100% {
                opacity: 0;
            }
            50% {
                opacity: .7;
            }
        }

没错,我动用的是一个渐变的背景,不仅是从上到下的渐变,并且颜色也是会潜移默化的,效果如下:

美高梅开户网址 213

渐变背景

安装参数以及获得 dom 对象

    /*
     * @var star_r:star半径系数,系数越大,半径越大
     * @var star_alpha:生成star的透明度,star_alpha越大,透明度越低
     * @var initStarsPopulation:初始化stars的个数
     * @var move_distance:star位移的距离,数值越大,位移越大
     * @var dot_r : dot半径系数,系数越大,半径越大
     * @var dot_speeds : dots运动的速度
     * @var dot_alpha : dots的透明度
     * @var aReduction:dot消失条件,透明度小于aReduction时消失
     * @var dotsMinDist:dot最小距离
     * @var maxDistFromCursor:dot最大距离
     * */
    var config = {
        star_r : 3,
        star_alpha : 5,
        initStarsPopulation : 150,
        move_distance : 0.25,
        dot_r : 5,
        dot_speeds : 0.5,
        dot_alpha : 0.5,
        dot_aReduction : 0.01,
        dotsMinDist : 5,
        maxDistFromCursor : 50,
    };
    var stars = [],
        dots = [],
        canvas = document.getElementById('canvas'),
        ctx = canvas.getContext('2d'),
        WIDTH,
        HEIGHT,
        mouseMoving = false,
        mouseMoveChecker,
        mouseX,
        mouseY;

绘图单个 star

    /* 设置单个 star
     * @param id:id
     * @param x:x坐标
     * @param y:y坐标
     * @param useCache:是否使用缓存
     * */
    function Star(id, x, y) {
        this.id = id;
        this.x = x;
        this.y = y;
        this.cacheCanvas = document.createElement("canvas");
        this.cacheCtx = this.cacheCanvas.getContext("2d");
        this.r = Math.floor(Math.random() * star_r) + 1;
        this.cacheCtx.width = 6 * this.r;
        this.cacheCtx.height = 6 * this.r;
        var alpha = ( Math.floor(Math.random() * 10) + 1) / star_alpha;
        this.color = "rgba(255,255,255," + alpha + ")";
        if (useCache) {
            this.cache()
        }
    }

让每一个 star 动起来

此地自己利用的是原型的点子,将 drawcachemovedie
方法都安装在 Star 的原型上,那样在行使 new 创建对象的时候,每一个
star 都可以继续那么些措施。

Star.prototype = {
        draw : function () {
            if (!this.useCacha) {
                ctx.save();
                ctx.fillStyle = this.color;
                ctx.shadowBlur = this.r * 2;
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
                ctx.closePath();
                ctx.fill();
                ctx.restore();
            } else {
                ctx.drawImage(this.cacheCanvas, this.x - this.r, this.y - this.r);
            }
        },

        cache : function () {
            this.cacheCtx.save();
            this.cacheCtx.fillStyle = this.color;
            this.cacheCtx.shadowColor = "white";
            this.cacheCtx.shadowBlur = this.r * 2;
            this.cacheCtx.beginPath();
            this.cacheCtx.arc(this.r * 3, this.r * 3, this.r, 0, 2 * Math.PI);
            this.cacheCtx.closePath();
            this.cacheCtx.fill();
            this.cacheCtx.restore();
        },

        move : function () {
            this.y -= move_distance;
            if (this.y <= -10) {
                this.y += HEIGHT + 10;
            }
            this.draw();
        },

        die : function () {
            stars[this.id] = null;
            delete stars[this.id]
        }
    };

绘制 dot

function Dot(id, x, y, useCache) {
        this.id = id;
        this.x = x;
        this.y = y;
        this.r = Math.floor(Math.random() * dot_r)+1;
        this.speed = dot_speeds;
        this.a = dot_alpha;
        this.aReduction = dot_aReduction;
        this.useCache = useCache;
        this.dotCanvas = document.createElement("canvas");
        this.dotCtx = this.dotCanvas.getContext("2d");
        this.dotCtx.width = 6 * this.r;
        this.dotCtx.height = 6 * this.r;
        this.dotCtx.a = 0.5;
        this.color = "rgba(255,255,255," + this.a +")";
        this.dotCtx.color = "rgba(255,255,255," + this.dotCtx.a + ")";
        this.linkColor = "rgba(255,255,255," + this.a/4 + ")";
        this.dir = Math.floor(Math.random()*140)+200;

        if( useCache){
            this.cache()
        }
    }

让每一个 dot 动起来

Dot.prototype = {
        draw : function () {
            if( !this.useCache){
                ctx.save();
                ctx.fillStyle = this.color;
                ctx.shadowColor = "white";
                ctx.shadowBlur = this.r * 2;
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
                ctx.closePath();
                ctx.fill();
                ctx.restore();
            }else{
                ctx.drawImage(this.dotCanvas, this.x - this.r * 3, this.y - this.r *3);

            }
        },

        cache : function () {
            this.dotCtx.save();
            this.dotCtx.a  -= this.aReduction;
            this.dotCtx.color = "rgba(255,255,255," + this.dotCtx.a + ")";
            this.dotCtx.fillStyle = this.dotCtx.color;
            this.dotCtx.shadowColor = "white";
            this.dotCtx.shadowBlur = this.r * 2;
            this.dotCtx.beginPath();
            this.dotCtx.arc(this.r * 3, this.r * 3, this.r, 0, 2 * Math.PI, false);
            this.dotCtx.closePath();
            this.dotCtx.fill();
            this.dotCtx.restore();
        },
        link : function () {
            if (this.id == 0) return;
            var previousDot1 = getPreviousDot(this.id, 1);
            var previousDot2 = getPreviousDot(this.id, 2);
            var previousDot3 = getPreviousDot(this.id, 3);
            var previousDot4 = getPreviousDot(this.id, 4);


            if (!previousDot1) return;
            ctx.strokeStyle = this.linkColor;
            ctx.moveTo(previousDot1.x, previousDot1.y);
            ctx.beginPath();
            ctx.lineTo(this.x, this.y);
            if (previousDot2 != false) ctx.lineTo(previousDot2.x, previousDot2.y);
            if (previousDot3 != false) ctx.lineTo(previousDot3.x, previousDot3.y);
            if (previousDot4 != false) ctx.lineTo(previousDot4.x, previousDot4.y);

            ctx.stroke();
            ctx.closePath();
        },

        move : function () {


            this.a -= this.aReduction;
            if(this.a <= 0 ){
                this.die();
                return
            }
            this.dotCtx.a  -= this.aReduction;
            this.dotCtx.color = "rgba(255,255,255," + this.dotCtx.a + ")";
            this.color = "rgba(255,255,255," + this.a + ")";
            this.linkColor = "rgba(255,255,255," + this.a/4 + ")";
            this.x = this.x + Math.cos(degToRad(this.dir)) * this.speed;
            this.y = this.y + Math.sin(degToRad(this.dir)) * this.speed;

            this.draw();
            this.link();

        },

        die : function () {
            dots[this.id] = null;
            delete dots[this.id];
        }
    };

鼠标移入事件监听

另外,大家还亟需安装有些其余的函数和对鼠标移入事件的监听,那里就不再赘述了,感兴趣的同班能够直接到
github 下载源码。

canvas 离屏渲染优化

自我所运用的离屏优化是基于此文,原文写的很好,大家感兴趣的话能够去看一下:http://www.cnblogs.com/axes/p/3567364.html?utm\_source=tuicool&utm\_medium=referral。
因为这么些效应以前自己也在博客用当做背景过,不少同室都影响很卡,所以自己就找了下优化的课程做了下优化,我发觉对品质影响最大的或是就是
canvas 的离屏渲染优化了,那也是 canvas 的最常见优化之一。

名字听起来很复杂,什么离屏渲染,其实就是设置缓存,绘制图像的时候在显示屏之外的地点绘制好,然后再一直拿过来用,那不就是缓存的概念吗?!︿( ̄︶ ̄)︿.

树立五个 canvas
标签,大小一样,一个正常化呈现,一个潜伏(缓存用的,不插入dom中),先将结果draw缓存用的canvas上下文中,因为游离canvas不会导致ui的渲染,所以它不会显现出来,再把缓存的始末全方位裁剪再
draw 到正常呈现用的 canvas 上,那样能优化不少。

骨子里早就反映在上述的代码中的,比如,创立 star 的代码中:

 /* 设置单个star
     * @param id:id
     * @param x:x坐标
     * @param y:y坐标
     * @param useCache:是否使用缓存
     * */
    function Star(id, x, y, useCache) {
        this.id = id;
        this.x = x;
        this.y = y;
        this.useCacha = useCache;
        this.cacheCanvas = document.createElement("canvas");
        this.cacheCtx = this.cacheCanvas.getContext("2d");
        this.r = Math.floor(Math.random() * star_r) + 1;
        this.cacheCtx.width = 6 * this.r;
        this.cacheCtx.height = 6 * this.r;
        var alpha = ( Math.floor(Math.random() * 10) + 1) / star_alpha;
        this.color = "rgba(255,255,255," + alpha + ")";
        if (useCache) {
            this.cache()
        }
    }

细心的同桌可能就会意识

        this.cacheCanvas = document.createElement("canvas");
        this.cacheCtx = this.cacheCanvas.getContext("2d");

那段代码就是又创办了一个 canvas 标签,然后再 star 的原型中有一个 cache
方法,这些 cache 方法就是在刚刚创造的 canvas 中绘制
star,而不是一向在原本的 canvas 画布中绘制的。

        cache : function () {
            this.cacheCtx.save();
            this.cacheCtx.fillStyle = this.color;
            this.cacheCtx.shadowColor = "white";
            this.cacheCtx.shadowBlur = this.r * 2;
            this.cacheCtx.beginPath();
            this.cacheCtx.arc(this.r * 3, this.r * 3, this.r, 0, 2 * Math.PI);
            this.cacheCtx.closePath();
            this.cacheCtx.fill();
            this.cacheCtx.restore();
        },

自此大家要求将我们绘制的离屏 canvas 使用 drawImage
方法插入到我们先河起始创建的 canvas 画布中。

那里要留意的是,创设的离屏 canvas
的高低,因为太大的话一样会浪费品质,所以大家得以创建和大家每一个 star
粒子相同的 canvas ,可是那么些例子中不适用,要将离屏的 canvas
设置的略微大一部分,因为大家还亟需设置发光的功能(也就是安装阴影)。

发福利

发福利的时光到了~╰( ̄▽ ̄)╭,很多伙伴对 canvas
不是很感兴趣,可是想平素运用这么些功能,于是自己就将其包装起来,你只要求引入这个JS,在 HTML 中添加一个 id 为 canvas 的标签,然后设置相应的 CSS 就足以~

github
下载地址:https://github.com/sunshine940326/canvasStar

在 README
中有使用方法因为是第一次自己封装函数,自己一个人在不停的摸索中前进,所以还有很多的不足,希望有大神可以指点一二

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图