要创建一个canvas,其实只要在HTML中添加标签:<canvas></canvas> 就行了。
若是考虑浏览器的兼容问题,只需在标签中加上一行文字:

<canvas>您的浏览器不支持canvas
</canvas>

即可达到「 友好提示用户 」的效果。

如果要“画东西”,也就是所谓的“操纵canvas元素”,则必要借助于DOM事件:

//获取canvas
var canvas=document.querySelector('canvas标签中的id/class名');
//获取“上下文对象“
var ctx=canvas.getContext("2d");

其中“上下文对象”你可以理解为是“绘图的环境(参数)”,而“2d”代表“要绘制2d(平面)图形” —— 同样的,“3d”表示“绘制3d(立体)图形”。

canvas坑一:
若要改变canvas“画布”的大小,最好在canvas标签的style属性中或在JS中动态进行。若通过class/id-style中修改(执行),会造成“整体缩放”——包括后面说到的lineTo线条也是这样。

//style
.canvas{border: 1px solid red;width: 200px;height: 200px;
}
//html
<canvas class="canvas">您的浏览器不支持canvas
</canvas>
//JS
var canvas=document.querySelector('.canvas');
var ctx=canvas.getContext("2d");
console.log(canvas.width,canvas.height);  //canvas中可以直接操作canvas所用到属性的各个CSS,这个后面还会提到
//下面三行先不必管
ctx.moveTo(0,0);
ctx.lineTo(200,200);
ctx.stroke()

JS操控canvas

上面说了,通过JS操作canvas元素前要先

  1. 得到元素
  2. 获取环境(参数)

下面的一些demo就省去这两行代码了。。。

首先,你要画比如一条线/一个图的话,假如canvas现在是你手中的一杆画笔,那你就要先“提笔” —— 从哪开始画:

ctx.moveTo(0,0);   //移动到【画布的】(0,0)坐标处“落笔”

moveTo的两个参数分别是:起始坐标X、Y。
然后
若是画直线,可以调用lineTo - API:

ctx.lineTo(100,100);   //从画布的(0,0)处“画”到(100,100)处

然后其实可以继续lineTo()…

ctx.lineTo(100,200);   //从画布的(100,100)处“画”到(100,200)处

这时,这些线条还只是在【内存】中,要其真正显示到页面上,则需调用stroke():

ctx.stroke();

ctx坑二:
若要再画一条线,不少初学者可能会将以上“绘制”部分代码再CV一遍,改变坐标即“大功告成”,但是真是这样的吗?
经检验,第一条线要“深色”一些:这是因为整段代码有两个stroke() —— 即第一条线被“画”了两次。

其实若要画多个图形,只要先把moveTo、lineTo…全部完成,再最后“一次性”调用 ctx.stroke(); 即可。
但这样一来又有一个问题:若是就想让两条线颜色不一样怎么办?
canvas API提供了下面的函数:

ctx.beginPath();   //开启一条“新的”内存路径

只要按原来的方法绘制时把这个函数加到“第二条绘制线”的moveTo函数前即可。

canvas画图形

上面是画线,那么诸如圆、长方形…这些图形怎么画?

圆形:ctx.arc(参数1,参2,参3,起始弧度,终止弧度,顺时针/逆时针画);

  • 参1:圆心坐标X
  • 参2:圆心坐标Y
  • 参3:半径r
  • 最后一个参数:true代表“逆时针”,false为“顺时针”
ctx.arc(300,300,50,0,2*Math.PI,true);
ctx.stroke();

矩形:ctx.strokeRect(左上角X,左上角Y,宽,高);
(因为是strokeRect这种stroke前缀的函数其实都是经过stroke()封装过的,所以可以直接显示在屏幕上)

其实,矩形还有两种画法:

  • 通过lineTo画四条线,最后一条的终点坐标和第一条的起点坐标相同
  • 通过lineTo画三条线,最后通过“闭合函数”:ctx.closePath() 将图形路径闭合

曾经看到好多“图片+JS雪花掉落效果”的文章,其实这个用canvas也可以轻易实现:

/**animCtx:canvas画布上下文对象
*/
var circles = [];   //“雪花”集
setInterval(function() {// 擦出画布animCtx.clearRect(0, 0, animCtx.canvas.width, animCtx.canvas.height);// 绘制下落的圆形for(var i=0; i<=10; i++) {if(!circles[i]) {   //保证每片“雪花”垂直下落(在每片雪花没消失前x不变,y改变,不走这里)circles[i] = {};circles[i].radius = Math.floor(Math.random() * 5) + 1;circles[i].y = - circles[i].radius - Math.floor(Math.random() * 10);circles[i].x = i * 60 + Math.floor(Math.random() * 10) - 5;circles[i].vy = Math.floor(Math.random() * 5) + 1;}animCtx.beginPath();animCtx.arc(circles[i].x, circles[i].y, circles[i].radius, 0, Math.PI * 2);animCtx.fillStyle = "rgba(255, 255, 255, 0.5)";animCtx.fill();circles[i].y = circles[i].y + circles[i].vy;   //如果雪花没消失,下一次出现(setInterval)的位置if(circles[i].y > animCtx.canvas.height + circles[i].radius * 2) {circles[i] = undefined;}}
}, 100);

JS填充canvas与canvas描边

上面的图形画着是挺爽的,就是颜色未免太单一了一些:
我们可以通过 ctx.fill() 填充函数填充整个图形(内部)为“黑色”(默认颜色)(视觉上看“自动闭合了路径”)emmmmmmm,这样全部都变成黑色了,不过我可以在前面用 ctx.fillStyle="颜色值" 来改变整个图形的颜色 —— 这之后fill()就只剩“填充”的功能了。

若是要只改变图形边框的颜色呢?其实上面说的一个函数本身就有“描边”的功能:ctx.stroke()
你当然可以理解为“只有为图形边框添加了颜色,才能显示出来”:毫无疑问,它默认也是黑色的。不过我们也可以用API:ctx.strokeStyle="颜色值" 来改变图形边框的颜色。
我们还可以通过 ctx.lineWidth=数字值; 来改变边框的宽度。

canvas中允许“边框设置”和“填充设置”同时出现。


canvas中还有一个比较重要的地方是:保存和恢复绘制状态
需要用到两个“上下文”函数:context.save();context.restore();
他们是基于【栈】的:你可以多次save,但是restore时也只能一次一次的“恢复到上一次的状态”!

他们就像是“合并图形”一样,可以让“save()前的”、“save()后的”、“restore()后的”绘制共存于一个canvas中!通常我们会这么使用:制造一个“合理的”canvas环境,然后save保存,然后绘制一个图形,再restore恢复save前的状态(切记:此时save后绘制的图形并不会消失!这就是“合并”),然后再去绘制下一个图形。

canvas使用渐变色

canvas可以“分层”设置不同线性渐变色:

var gradient=context.createLinearGradient(0,0,canvas.width,canvas.height);gradient.addColorStop(0,'blue');
gradient.addColorStop(0.25,'blue');
gradient.addColorStop(0.5,'white');
gradient.addColorStop(0.75,'red');
gradient.addColorStop(1,'yellow');//渲染(取决于gradient后(或者说下一行之后)干了什么,就渲染什么)
context.fillStyle=gradient;
//它和“context.globalAlpha”一样,是一个“前置”行为

JS图形变换(平移、旋转、缩放)

如上面“画线”所说:

ctx.moveTo(0,0);
ctx.lineTo(100,100);
ctx.stroke();

平移:ctx.translate(X方向,Y方向);
大家可以试下分别将translate函数放在moveTo前、lineTo前、最后,分别有什么效果!

旋转:ctx.rotate(旋转角度); —— 以弧度为单位:

//旋转45°
ctx.rotate(Math.PI / 4);

缩放:ctx.scale(X轴缩放,Y轴缩放);

//X轴不缩放,Y轴变为原来的1/2
ctx.scale(1,0.5);

图形变换的效果也会“自上而下叠加”!

如果觉得叠加效果并不是想要的,可以将某个变换片段代码放到 ctx.save() 【保存环境函数】和 ctx.restore() 【恢复环境函数】(恢复到save()函数之前的环境)的“包裹”中。

canvas文字

var str="hello world";

我们怎么把展示到canvas画布中呢?

ctx.fillText(str,0,100);   //参数:文字,X坐标,Y坐标
//或
ctx.strokeText(str,0,200);   //若有颜色,则上面的为填充,这里为描边(字体呈镂空效果)

当然,这里的坐标位置你也可以“自定义”,比如:在整个canvas中水平居中,距离画布底部30的位置?
context.fillText(mxcIdText,originWidth/2,originHeight-30);

填充:

能不能改变他的样式?
(开头说了一句“canvas里能直接改变元素CSS样式值”不知道大家还记得不记得)

ctx.font="50px sans-serif";   //改变字体大小

并且加上strokeText函数:

也可以改变文字的位置,如:

ctx.textAlign="center";   //文字居中(水平)
ctx.textBaseline="middle";   //文字垂直居中

既然能控制大小和位置,肯定也能获取一些自身信息:

let width=ctx.measureText(str).width;   //获取文本宽度

这样,我们就能做一些有意义的事,比如文本X/Y坐标是多少时设置Align才能让水平居中、比如根据一个元素的width(文字字数)控制另一个元素的位置。。。这些都在末尾demo中有用到。

很遗憾的是,canvas并不支持获取文本的“高度”


2020-08-30更新
但是经过计算,对于大多数字型来说,将字母“M”的宽度再稍微增加一点(一般是1/6),就可以得出几乎近似的文本高度了:

var approHeight=function(){return context.measureText('M').width*(1+1/6);
};

在canvas中展示图片

canvas作为一个“特殊的结构”,其图片的展示方式肯定也不同寻常:

//加载图片对象
let img=new Image();
//设置src属性
img.src="xxx.xx";
//展示
ctx.drawImage(img,0,0);   //ctx.drawImage(img对象,左上角X坐标,左上角Y坐标);

然后我们“自信满满地”打开图片,发现…没有东西!!!

这是因为Image()的加载需要一定时间,而我们直接插入了src:切记!一定要在load中完成img的“展示”。(和H5的File()加载展示一样的道理)

img.onload=function(){ctx.drawImage(img,0,0);
}

这样完成是完成了,但图片样式是固定的,不好看啊。
没关系,我们有“第二种展示方法”,可以将其进行缩放:

ctx.drawImage(img对象,左上角X坐标,左上角Y坐标,宽,高);

然后我们又发现缩放后图片中图标是挺好看的,但文字太模糊了,难受的一批,于是我们想:怎么把图标单独显示出来呢?
没关系,我们还有“第三种展示方法”:

ctx.drawImage(img对象,截取起点X坐标,截取起点Y坐标,截取终点X坐标,截取终点Y坐标,绘制位置X坐标,绘制位置Y坐标,宽,高);

其实“图片”的展示还有一种方式 —— 图形画刷 ,它可以将图片为背景填充展示到canvas区域:

var pattern=ctx.createPattern(img对象,"模式");
ctx.fillStyle=pattern;

其中,“模式”和CSS中【背景图片】的展示也很类似:

  • no-repeat
  • repeat
  • repeat-x
  • repeat-y

你可能想不到:最后生成的canvas是可以直接“图片另存为”/“复制”的 —— canvas确实是image的一种“变异形式”?
不行,这用着不放心啊,还是图片巴适些:

canvas.toDataURL("image/png")

我们常用这个API来将canvas转为png图片格式 —— 大概是因为png好操作吧。
它返回的是一个base64的链接 —— 可直接装到img的src上!

其实这个API还有第二个参数,不太常用:
encoderOptions(可选) 图片质量,取值范围为 0 到 1 。
如果指定图片格式为 image/jpeg 或 image/webp,而且超出取值范围,将会使用默认值 0.92,其他参数会被忽略。

canvas阴影设置

  • X轴偏移:ctx.shadowOffsetX=数字值; (数字值相对于图形)
  • Y轴偏移:ctx.shadowOffsetY=数字值; (数字值相对与图形)
  • 阴影颜色:ctx.shadowColor='颜色值如:rgba(0,0,0,0.2)';
  • 模糊半径:ctx.shadowBlur=数字值;

阴影会作用于其下所有设置的canvas上(文本、图形、图片…)

离屏canvas

这个在大加载量、频繁JS动画 and DOM重绘量巨大的场景下应用极广。它基于这样的原理:把涉及大量DOM重绘、频繁加载的元素(比如小球运动场景下的背景格的样式改变)单独拿出来放在某位置地方(display:none;)自己加载,在触发操作后,通过:

真实canvas元素上下文对象.drawImage(离屏canvas元素, 起始位置X, 起始位置Y, 真实canvas元素宽, 真实canvas元素高,起始位置X, 起始位置Y, 离屏canvas元素宽,离屏canvas元素高);

将元素的“样子”刻画到主要显示的canvas上!

要记得“适当地”擦干画布:canvas元素上下文对象.clearRect()

2020-12-19更新

发现其实离屏(双重)技术还有一种更为便捷的使用方式:

(function drawFrame() {requestAnimationFrame(drawFrame);primaryCtx.save(); //Freeze redraw// 一些操作primaryCtx.restore(); //And now do the redraw
})();

但是使用场景并不常见,猜测可能是和 save 和 restore 函数冲突有关吧。


canvas名片生成程序代码

代码较多,已打包到百度网盘,可直接免费下载:

链接 提取码
https://pan.baidu.com/s/1EIJp0MNAD4gvTsBRwkglLg xqwk

HTML5 canvas基础与「生成名片」应用程序相关推荐

  1. 计算机主板上主要组件的是,计算机应用基础选择题「附答案」

    计算机应用基础选择题「附答案」 一.单选题 1.计算机具有逻辑判断能力,主要取决于____. A:硬件 B:体积 C:编制的软件 D:基本字长 答案: C 评析:此题没有评析 2.第三代计算机采用的主 ...

  2. excel计算机基础知识考试题,2017年计算机excel基础考试题「附答案」

    2017年计算机excel基础考试题「附答案」 一.单选题 1.Excel主界面窗口中编辑栏上的"fx"按钮用来向单元格插入________. A:文字 B:数字 C:公式 D:函 ...

  3. 2017大学计算机基础书,2017大学计算机基础试题「含答案」

    2017大学计算机基础试题「含答案」 一.单选题 1.完整的计算机系统由(C)组成. A.运算器.控制器.存储器.输入设备和输出设备 B.主机和外部设备 C.硬件系统和软件系统 D.主机箱.显示器.键 ...

  4. word2007计算机应用能力试题,计算机应用基础试题「附答案」

    计算机应用基础试题「附答案」 一.选择题 1.在WORD2000中,以下关于段落的操作说法正确的是 C A.按住ALT键的同时单击段落的任意位置可以选该段落 B.按住ALT键的同时双击段落的任意位置可 ...

  5. 大学生计算机应用与基础,大学生计算机应用基础试题「附答案」

    大学生计算机应用基础试题「附答案」 (8页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 大学生计算机应用基础试题「附答案」 一.选择题 1. ...

  6. 计算机文化基础在线答题第二次,2017计算机文化基础考试题「附答案」

    2017计算机文化基础考试题「附答案」 一.选择题 1.在Windows中,为了弹出"显示属性"对话框以进行显示器的设置,下列操作中正确的是______. A:用鼠标右键单击&qu ...

  7. 计算机基础word试题七年级,2017年计算机基础试题「有答案」

    2017年计算机基础试题「有答案」 一.单项选择 共60题 (共计60分) 第1题 (1.0分) 在Word中,在页面设置选项中,系统默认的纸张大小是(). A:A4 B:B5 C:A3 D:16开 ...

  8. html5 canvas基础与动画开发详解-吴华-专题视频课程

    html5 canvas基础与动画开发详解-533人已学习 课程介绍         一.本课程几乎包括所有canvas常用的api用法讲解 二.包括以下案例应用: 1.坐标系绘制 2.图片裁剪与填充 ...

  9. 以太坊「生成艺术」热潮来袭,一文教你如何应对

    注:原文来自bankless,作者是William M. Peaster. 几个小时前,下面这件艺术品以超过40万美元的价格成功售出.???? Ringer #666 那下面这个呢? Chromie ...

最新文章

  1. 面向未来的智能硬件:研究通用高端智能控制器开发智能体系结构
  2. 【Flask项目2】创建用户模块的蓝图(7)
  3. 原始性能数字– Spring Boot 2 Webflux与Spring Boot 1
  4. Leetcode--145. 二叉树的后序遍历(迭代递归)
  5. 双非本科:337家Java后台面试总结
  6. 机器学习 | 特征选择(Feature Selection)
  7. 教您如何获取App的ipa安装包
  8. h264封装ts文件资料相关
  9. 《王者荣耀》手游产品分析报告:崛起的王者荣耀,胜负就是这么简单!
  10. Linode跨节点迁移:从Tokyo到Fremont
  11. 2020年Web前端学习网站导航
  12. HDU 6095 Rikka with Competition
  13. HashSet 原理结构
  14. Rust中的channel
  15. 臂式血压计PCBA方案
  16. flask 开启debug 以及development模式
  17. 【ArcGIS Pro微课1000例】0020:ArcGIS Pro中河流(曲线)、湖泊(水体色)图例制作案例教程
  18. 【指针训练——八道题】
  19. 能开matlab的轻薄本,求推荐女生用轻薄本 - 笔记本电脑(Notebook)版 - 北大未名BBS...
  20. 对象的发布与逸出简单理解

热门文章

  1. CC2591和CC2592区别
  2. 2Pai荣湃单通道数字隔离器π110M30兼容代替Si8410AB-D-IS 3.0kVrms 10Mbps 结构简单 方案更加灵活
  3. 安装和配置Firefox的浏览器驱动
  4. linux系统如何修改磁盘名称,Linux系统怎么修改磁盘参数(名称,盘符等等
  5. 【操作系统基础】系统接口与系统调用
  6. Pennylane混合经典量子分类器-Mnist分类
  7. Origin添加列的方法
  8. sdcard, emmc, sdio, sd标准
  9. 发明专利申请所需要的资料及程序
  10. 软件测试大赛之移动测试练习题-全能计算器