超多经典 canvas 实例,动态离子背景、移动炫彩小球、贪吃蛇、坦克大战、是男人就下100层、心形文字等等等

超多经典 canvas 实例

普及<canvas> 元素用于在网页上绘制图形。这是一个图形容器,您可以控制其每一像素,必须使用脚本来绘制图形。

注意:IE 8 以及更早的版本不支持 <canvas> 元素。

贴士:全部例子都分享在我的 GayHub - https://github.com/bxm0927/canvas-special

尤雨溪个人主页炫彩三角纽带效果,点击还可变换

GitHub源码Demo演示

知乎登录注册页动态离子背景效果

GitHub源码Demo演示

基于 canvas 的五子棋完整功能实现

GitHub源码Demo演示

基于 canvas 的《是男人就下100层》小游戏完美实现

GitHub源码Demo演示

毛笔字书写田字格,可以写字

GitHub源码Demo演示

随心而动,随刃而行。输入文字显示动画粒子特效

GitHub源码Demo演示

鼠标移动炫彩小球

GitHub源码Demo演示

2048

GitHub源码Demo演示

贪吃蛇

GitHub源码Demo演示

看你有多色

GitHub源码Demo演示

坦克大战

GitHub源码Demo演示

宇宙行星旋转特效

GitHub源码Demo演示

支付宝咻咻咻动画特效

GitHub源码Demo演示

程序员表白代码

GitHub源码Demo演示

心形文字

GitHub源码Demo演示

照片墙

GitHub源码Demo演示

License

The code is available under the MIT license.

<marquee>不断更新,欢迎补充!</marquee>

!

canvas 简介

<canvas> 元素用于在网页上绘制图形。这是一个图形容器,您可以控制其每一像素,必须使用脚本来绘制图形。

<canvas> 标记和 SVG 以及 VML 之间的一个重要的不同是,<canvas> 有一个基于 JavaScript 的绘图 API,而 SVG 和 VML 使用一个 XML 文档来描述绘图。

注意:IE 8 以及更早的版本不支持 <canvas> 元素。

!

canvas 初体验

<canvas id="myCanvas" width="450" height="450">
  Your browser does not support the Canvas API, Please upgrade your browser.
</canvas>

<script>
let myCanvas = document.getElementById('myCanvas');
let ctx = myCanvas.getContext('2d');

ctx.moveTo(100, 100);
ctx.lineTo(200, 200);
ctx.lineTo(200, 300);

ctx.stroke();
</script>

canvas 核心 API 讲解

建议大家看官方文档来系统的学习 canvas API,本文下面的例子只是对知识点的巩固。

颜色、样式和阴影

fillStylestrokeStyle

fillStyle 属性设置或返回用于填充绘画的颜色、渐变或模式。

strokeStyle 属性设置或返回用于笔触的颜色、渐变或模式。

// 用蓝色填充矩形
ctx.fillStyle="#0000ff";
ctx.fillRect(20,20,150,100);

// 渐变填充
var my_gradient=ctx.createLinearGradient(0,0,0,170);
my_gradient.addColorStop(0,"black");
my_gradient.addColorStop(1,"white");
ctx.fillStyle=my_gradient;
ctx.fillRect(20,20,150,100);

// 图像填充
var img=document.getElementById("lamp");
var pat=ctx.createPattern(img,"repeat");
ctx.rect(0,0,150,100);
ctx.fillStyle=pat;
ctx.fill();

!

!

shadowBlurshadowColor

shadowBlur 设置或返回用于阴影的模糊级别

shadowColor 设置或返回用于阴影的颜色

注释1:请将 shadowColor 属性与 shadowBlur 属性一起使用,来创建阴影。

注释2:请通过使用 shadowOffsetX 和 shadowOffsetY 属性来调节阴影效果。

ctx.shadowBlur=20;
ctx.shadowColor="black";
ctx.fillStyle="blue";
ctx.fillRect(20,20,100,80);

!

createLinearGradient()createRadialGradient()

context.createLinearGradient(x0,y0,x1,y1) 创建线性渐变

context.createRadialGradient(x0,y0,r0,x1,y1,r1) 创建放射状/环形的渐变

注释:addColorStop(stop,color) 方法与 createLinearGradient()createRadialGradient() 一起使用。

var my_gradient=ctx.createLinearGradient(0,0,0,170);
my_gradient.addColorStop(0,"black");
my_gradient.addColorStop(0.5,"red");
my_gradient.addColorStop(1,"white");
ctx.fillStyle=my_gradient;
ctx.fillRect(20,20,150,100);

!
var grd=ctx.createRadialGradient(75,50,5,90,60,100);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
ctx.fillStyle=grd;
ctx.fillRect(10,10,150,100);

!
context.createPattern()

context.createPattern(image,"repeat|repeat-x|repeat-y|no-repeat") 重复绘制元素,元素可以是图片、视频,或者其他 <canvas> 元素。

var img=document.getElementById("lamp");
var pat=ctx.createPattern(img,"repeat");
ctx.rect(0,0,150,100);
ctx.fillStyle=pat;
ctx.fill();

!

线条样式

lineCap

context.lineCap="butt|round|square"

设置或返回线条的结束端点样式 (平直的边缘(默认)、圆形线帽、正方形线帽)

lineJoin

context.lineJoin="miter|bevel|round"

设置或返回两条线相交时,所创建的拐角类型 (尖角(默认)、斜角、圆角)

ctx.beginPath();
ctx.lineJoin="round";
ctx.moveTo(20,20);
ctx.lineTo(100,50);
ctx.lineTo(20,100);
ctx.stroke();

!

lineWidth

ctx.lineWidth = 10

设置或返回当前的线条宽度,单位 px

矩形

rect()fillRect()strokeRect()

context.rect(x,y,width,height) 创建矩形

context.fillRect(x,y,width,height) 创建已填色的矩形,默认的填充颜色是黑色。

context.strokeRect(x,y,width,height) 创建不填色的矩形,默认的笔触颜色是黑色。

// 红色矩形
ctx.beginPath();
ctx.lineWidth="6";
ctx.strokeStyle="red";
ctx.rect(5,5,290,140);
ctx.stroke();

clearRect()

clearRect() 在给定的矩形内清除指定的像素

// 在给定矩形内清空一个矩形
ctx.fillStyle="red";
ctx.fillRect(0,0,300,150);
ctx.clearRect(20,20,100,50);

!

路径

提示:请使用这些方法来创建路径:moveTo()、lineTo()、quadricCurveTo()、bezierCurveTo()、arcTo() 以及 arc()。

fill()

填充当前的图像(路径)。默认颜色是黑色。

提示:请使用 fillStyle 属性来填充另一种颜色/渐变。

注释:如果路径未关闭,那么 fill() 方法会从路径结束点到开始点之间添加一条线,以关闭该路径,然后填充该路径。

// 绘制 150*100 像素的矩形,然后用绿色来给它填色:
ctx.rect(20,20,150,100);
ctx.fillStyle="green";
ctx.fill();

!

stroke()

stroke() 方法会绘制出通过 moveTo() 和 lineTo() 方法定义的路径。默认颜色是黑色。

提示:请使用 strokeStyle 属性来绘制另一种颜色/渐变。

beginPath()

beginPath() 起始一条路径,或重置当前路径

closePath()

closePath() 创建从当前点回到起始点的路径

moveTo()lineTo()

moveTo() 把路径移动到画布中的指定点,不创建线条

lineTo() 添加一个新点,然后在画布中创建从该点到最后指定点的线条

ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(300,150);
ctx.stroke();

quadraticCurveTo()bezierCurveTo()

context.quadraticCurveTo(cpx,cpy,x,y); 创建二次贝塞尔曲线

context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y); 创建三次方贝塞尔曲线

ctx.beginPath();
ctx.moveTo(20,20);
ctx.quadraticCurveTo(20,100,200,20);
ctx.stroke();
image
ctx.beginPath();
ctx.moveTo(20,20);
ctx.bezierCurveTo(20,100,200,100,200,20);
ctx.stroke();
image

arc()arcTo()

context.arc(x,y,r,sAngle,eAngle[,counterclockwise]); 创建弧/曲线(用于创建圆形或部分圆)

context.arcTo(x1,y1,x2,y2,r); 创建两切线之间的弧/曲线

ctx.beginPath();
arc(100, 75, 50, 0*Math.PI, 1.5*Math.PI)
ctx.stroke();
image
ctx.beginPath();
ctx.moveTo(20,20);           // 创建开始点
ctx.lineTo(100,20);          // 创建水平线
ctx.arcTo(150,20,150,70,50); // 创建弧
ctx.lineTo(150,120);         // 创建垂直线
ctx.stroke();                // 进行绘制

!

clip()

clip() 从原始画布剪切任意形状和尺寸的区域

// 剪切矩形区域
ctx.rect(50,20,200,120);
ctx.stroke();
ctx.clip();
// 在 clip() 之后绘制绿色矩形
ctx.fillStyle="green";
ctx.fillRect(0,0,150,100);

!

isPointInPath()

isPointInPath() 如果指定的点位于当前路径中,则返回 true,否则返回 false

ctx.rect(20,20,150,100);
if (ctx.isPointInPath(20,50)) {
  ctx.stroke()
}

转换

scale()

scale() 缩放当前绘图至更大或更小

// 绘制矩形,放大到 200%,然后再次绘制矩形:
ctx.strokeRect(5,5,25,15);
ctx.scale(2,2);
ctx.strokeRect(5,5,25,15);

!

rotate()

rotate() 旋转当前绘图

// 将矩形旋转 20 度:
ctx.rotate(20 * Math.PI / 180);
ctx.fillRect(50,20,100,50);

!

translate()

translate() 重新定义画布上的 (0,0) 位置

ctx.fillRect(10,10,100,50);
ctx.translate(70,70);
ctx.fillRect(10,10,100,50);

!

transform()setTransform()

context.transform(a,b,c,d,e,f); 替换绘图的当前转换矩阵

context.setTransform(a,b,c,d,e,f); 将当前转换重置为单位矩阵。然后运行 transform()

文本

fonttextAligntextBaseline

font 设置或返回文本内容的当前字体属性

textAlign 设置或返回文本内容的当前对齐方式

textBaseline 设置或返回在绘制文本时使用的当前文本基线

fillText()strokeText()measureText()

context.fillText(text, x, y, maxWidth); 在画布上绘制被填充的文本

context.strokeText(text,x,y,maxWidth); 在画布上绘制文本(无填充)

context.measureText(text).width; 返回包含指定文本宽度的对象

ctx.font="30px Arial";
ctx.fillText("Hello World", 10, 50);
ctx.font="40px Arial";
// 创建渐变
var gradient=ctx.createLinearGradient(0, 0, myCanvas.width, 0);
gradient.addColorStop("0", "magenta");
gradient.addColorStop("0.5", "blue");
gradient.addColorStop("1.0", "red");
// 用渐变填色
ctx.strokeStyle=gradient;
ctx.strokeText("Hello World", 10, 90);

图像绘制

drawImage()

context.drawImage(img,x,y,width,height); 向画布上绘制图像、画布或视频

var img=document.getElementById("tulip");
ctx.drawImage(img, 10, 10);

像素操作

widthheightdata

width 返回 ImageData 对象的宽度

height 返回 ImageData 对象的高度

data 返回一个对象,其包含指定的 ImageData 对象的图像数据

createImageData()getImageData()putImageData()

createImageData() 创建新的、空白的 ImageData 对象

getImageData() 返回 ImageData 对象,该对象为画布上指定的矩形复制像素数据

putImageData() 把图像数据(从指定的 ImageData 对象)放回画布上

合成

context.globalAlpha = number; 设置或返回绘图的当前 alpha 或透明值
context.globalCompositeOperation="source-in"; 设置或返回新图像如何绘制到已有的图像上

其他

save()restore()

save() 保存当前环境的状态
restore() 返回之前保存过的路径状态和属性

getContext

let cxt = Canvas.getContext('2d')

为不同的绘制类型 (2d、3d) 提供不同的环境,当前唯一支持的是 2d 环境

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 144,481评论 1 305
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 61,908评论 1 258
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 95,710评论 0 214
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 41,372评论 0 183
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 49,216评论 1 262
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 38,949评论 1 178
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 30,558评论 2 275
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,308评论 0 168
  • 想象着我的养父在大火中拼命挣扎,窒息,最后皮肤化为焦炭。我心中就已经是抑制不住地欢快,这就叫做以其人之道,还治其人...
    爱写小说的胖达阅读 29,183评论 7 237
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 32,675评论 0 214
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,416评论 2 217
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 30,757评论 1 232
  • 白月光回国,霸总把我这个替身辞退。还一脸阴沉的警告我。[不要出现在思思面前, 不然我有一百种方法让你生不如死。]我...
    爱写小说的胖达阅读 24,314评论 1 33
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,215评论 2 213
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 31,682评论 3 214
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,665评论 0 9
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,091评论 0 170
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 33,687评论 2 233
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 33,830评论 2 237

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,400评论 25 707
  • 一:canvas简介 1.1什么是canvas? ①:canvas是HTML5提供的一种新标签 ②:HTML5 ...
    GreenHand1阅读 4,588评论 2 32
  • Part7收集 那堵白墙大约是城外挺远的山上,李帝努细细地规划去往的路径,估计得花上几天,在这之前,最好能拿上几天...
    几几几分钟阅读 319评论 0 0
  • 一 滴答,滴答,滴答,滴答。。。。。。。 随着耳边响起时钟摆动的声响,我缓缓睁开双眼。 襁褓中的我想要拼命呼喊,却...
    梁思成阅读 335评论 0 4
  • 走过的路我会一直负责到底 雨来时我会为你撑伞陪着你 烈日当头我会给你一片阴凉 乱石封路我会背你越过山岗 烈酒灼喉时...
    旧时雨m阅读 97评论 2 1