canvas
是一个标签,简单理解为一个有特殊功能的盒子标签,最好在标签上写上宽高属性和背景色,否则在页面上看不到效果。canvas 是一个二维网格,canvas 默认左上角坐标为 (0,0),可以通过translate(x,y)来更改原点坐标。
注:在低版本浏览器中不兼容,需要提示用户
绘制形式有三种:描边,填充和描边+填充。
beginPath(): 清除当前所有子路径,以此来重置当前路径,重新规划一条路径。
closePath(): 用于封闭某段开放路径。不是必需的,如果图形是已经闭合了的,即当前点为开始点,该函数什么也不做。
画线:
moveTo(x,y) 定义线条开始坐标
lineTo(x,y) 定义线条结束坐标
线段也是基于路径绘制的,称为线性路径,创建线性路径的方法:moveTO()与lineTo(),在创建路径之后调用stroke()方法,才能在Canvas中画出线段出来。
moveTo(x,y): 将笔触移动到指定的坐标x以及y上,向当前路径中增加一条子路径,该方法不会清除当前路径中的任何子路径。
lineTo(x,y): 绘制一条从当前位置到指定x以及y位置的直线,如果当前路径中没有子路径,那么这个方法的行为与moveTo()一样。如果当前路径中存在子路径,此方法会将你所指定的这个点加入子路径中。
画圆:
arc(x,y,r,start,stop)
文本:
font - 定义字体
fillText(text,x,y) - 在 canvas 上绘制实心的文本
strokeText(text,x,y) - 在 canvas 上绘制空心的文本
渐变:
createLinearGradient(x,y,x1,y1) - 创建线条渐变
createRadialGradient(x,y,r,x1,y1,r1) - 创建一个径向/圆渐变
画图片:
drawImage(image,x,y)
线宽:
lineWidth => 数值
图形落地:
stroke() => 将设计好的图形绘制出来
strokeStyle => css常用色值均可使用,图形颜色
绘制矩形:
fillRect(x,y,width,height)
fillStyle => css常用色值均可使用,图形填充颜色
清除画布:
clearRect(x,y,width,height)
绘图模糊的问题
单设canvas画布css样式的宽高会导致绘制模糊:
- 可以通过同时设置标签上的width和height属性来改善
- 可以将canvas宽高设为2倍后再缩小一倍
- 套一个父级div,只设定父级盒子宽高cavas标签自动继承宽高(无法自适应各类手机屏,不推荐)
- 只设定canvas标签上的width和height的属性(无法自适应各类手机屏,不推荐)
创建&线性&基础知识
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>创建一个canvas</title>
<style>
canvas{
background: #000;
margin: 0 auto;
display: block;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="500px" height="500px">您的浏览器版本过低,请先升级浏览器!</canvas>
<script type="text/javascript">
// 获取canvas标签
var _canvas = document.getElementById("myCanvas");
// 获取上下文对象创建2d画布
var ctx = _canvas.getContext("2d");
// 固定两步可以简写为
// let ctx = document.getElementById("myCanvas").getContext("2d");
//设置绘图原点,相对于上一个原点,默认(0,0)
ctx.translate(250,20);
(function drawLine(){
// 画一条直线
// 开启一条路径
ctx.beginPath();
// 从哪里开始移动
ctx.moveTo(100,100);
// 移动到哪里去
ctx.lineTo(200,200);
// 线的颜色(不写默认黑色,后设覆盖先设)
ctx.strokeStyle = "yellow";
// lineTo可以写多个,首位相连
ctx.lineTo(200,260);
ctx.lineTo(100,260);
// 设置线宽,不能带单位
ctx.lineWidth = 14;
// 画线
ctx.stroke();
// 结束路径
ctx.closePath();
})()
// 通过画线的方式画一个边线方块
function drawSquare(){
// 重置原点
ctx.translate(-250,20);
ctx.lineWidth = 2;
// 几何图形[一条线一个颜色]
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(100,200);
ctx.strokeStyle = "blue";
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(100,200);
ctx.lineTo(200,200);
ctx.strokeStyle = "yellow";
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(200,200);
ctx.lineTo(200,100);
ctx.strokeStyle = "pink";
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(200,100);
ctx.lineTo(100,100);
ctx.strokeStyle = "red";
ctx.stroke();
ctx.closePath();
}
drawSquare()
// 画三角形
function drawTriangle(){
// 绿色填充三角形
ctx.translate(150, 0);
ctx.fillStyle = 'green';
ctx.strokeStyle = "red";
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(50, 150);
ctx.lineTo(150, 150);
ctx.fill();
// 要先关闭路径再画线 => 具体不同可以自行更换代码位置查看
ctx.closePath();
ctx.stroke();
// 红色填充三角形
ctx.translate(150, 0);
ctx.fillStyle = 'green';
ctx.strokeStyle = "#fff";
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(50, 150);
ctx.lineTo(150, 150);
ctx.closePath();
// 先填充颜色再画边线 不然边线会被遮挡一半
// 引申:类似table的值,1=2,要实现真正的1单位宽度就需要设置0.5
ctx.fill();
ctx.stroke();
}
drawTriangle()
// 验证上方引申
function drawLineWidth(){
ctx.translate(-250,230);
ctx.strokeStyle = "#fff";
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(250, 50);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(50.5, 150.5);
ctx.lineTo(250.5, 150.5);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(50, 200);
ctx.lineTo(252, 200);
ctx.stroke();
ctx.closePath();
}
drawLineWidth()
// 不存在层级概念(z-index),后画的会覆盖在之前的上面
// 渐变色
function drawLineColor(){
ctx.lineWidth = 4;
var gradient = ctx.createLinearGradient(0, 0, 250, 250);
gradient.addColorStop(0, 'blue');
gradient.addColorStop(0.5, 'purple');
gradient.addColorStop(1, 'yellow');
ctx.strokeStyle = gradient;
ctx.beginPath();
ctx.lineTo(50, 50);
ctx.lineTo(200, 200);
ctx.stroke();
}
drawLineColor()
</script>
</body>
</html>
填充矩形&清除画布&随机柱状图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>随机统计图</title>
<style>
canvas{
background: #000;
margin: 0 auto;
display: block;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="500px" height="500px">您的浏览器版本过低,请先升级浏览器!</canvas>
<script type="text/javascript">
// 固定两步
let ctx = document.getElementById("myCanvas").getContext("2d");
ctx.beginPath();
// fillRect(x,y,width,height) 画一个规则矩形,前两个起始位置的坐标,后两个值是长和宽
// fillStyle用来设置填充色,默认是黑色
ctx.fillStyle='pink'
ctx.fillRect(100,20,60,20)
// 渐变色矩形
// 创建线性渐变
let grd=ctx.createLinearGradient(0,100,100,100);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
ctx.fillStyle=grd;
ctx.fillRect(10,10,150,80);
//创建径向渐变
var rad=ctx.createRadialGradient(90,90,10,100,90,100);
rad.addColorStop(0,"red");
rad.addColorStop(1,"white");
ctx.fillStyle=rad;
ctx.fillRect(30,30,150,150);
// 画一个‘回’字
ctx.fillStyle='yellow'
ctx.fillRect(10,10,60,60)
// ctx.fillStyle='pink'
// 用清除的方式
ctx.clearRect(15,15,50,50)
ctx.fillStyle='yellow'
ctx.fillRect(20,20,40,40)
// 用同色矩形覆盖
ctx.fillStyle='#000'
ctx.fillRect(25,25,30,30)
ctx.closePath();
// 随机颜色柱状图
(function drawChart(){
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(100,400);
ctx.lineTo(400,400);
ctx.strokeStyle='red';
ctx.stroke();
ctx.closePath();
for (let i=0;i<7;i++) {
// 随机高度
let height = Math.random()*280+10;
// 随机颜色
ctx.fillStyle="#"+parseInt(Math.random()*0Xffffff).toString(16);
//画柱子
ctx.fillRect(120+40*i,400-height,20,height)
}
})()
</script>
</body>
</html>
运用canvas画个调皮笑脸
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>画圆脸</title>
<style>
canvas{
margin: 0 auto;
display: block;
border: 2px solid #ccc;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="500px" height="500px">您的浏览器版本过低,请先升级浏览器!</canvas>
<script type="text/javascript">
// 固定两步
let ctx = document.getElementById("myCanvas").getContext("2d");
// 圆脸(圆圈) false顺时针
ctx.beginPath();
ctx.arc(250,250,100,0,Math.PI*2,false)
ctx.lineWidth = 10
ctx.strokeStyle='red'
ctx.stroke();
ctx.closePath();
// 左眼(圆形) true逆时针
ctx.beginPath();
ctx.arc(220,210,15,0,Math.PI*2,true)
ctx.fillStyle='red'
ctx.fill();
ctx.closePath();
// 右眼(线形)
ctx.beginPath();
ctx.lineWidth = 8;
ctx.moveTo(300,199);
ctx.lineTo(280,210);
ctx.lineTo(300,220);
ctx.stroke();
ctx.closePath();
// 嘴(圆弧)
ctx.beginPath();
ctx.lineWidth = 8;
ctx.arc(250,260,50,0,Math.PI,false)
ctx.stroke();
ctx.closePath();
</script>
</body>
</html>
画爱心动效(类进度条)
<!DOCTYPE html>
<html>
<head>
<title>Draw Heart</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
html {
height: 100%;
margin: 0;
}
body {
height: 100%;
}
.wrap{
width: 100vw;
height: 874px;
background: skyblue;
position: fixed;
bottom: 0;
left: 0;
}
#myCanvas {
width: 100%;
height: 500px;
display: block;
position: absolute;
z-index: 99;
}
img{
z-index: 999;
}
#bgCanvas {
width: 100%;
height: 500px;
display: block;
}
.bottom{
width: 100vw;
height: 180px;
background: red;
}
.usr-info{
width: 100vw;
height: 190px;
background: yellow;
}
.btn{
width: 86px;
height: 86px;
border-radius: 50%;
background-color: blue;
position: absolute;
top: -136px;
right: 20px;
z-index: 9;
}
</style>
</head>
<body>
<div class="wrap">
<div class="btn"></div>
<div class="usr-info">
</div>
<canvas id="myCanvas"></canvas>
<canvas id="bgCanvas"></canvas>
<div class="bottom">
</div>
</div>
<script type="text/javascript">
var r = 5;
var radian;//弧度
var i;
var radianDecrement;//弧度增量
var intervalId;
var num = 360;//分割为 360 个点
var ctx;
let timer = null;
let newX = 0
let newY = 0
window.onload = function () {
ctx = document.getElementById("myCanvas").getContext("2d");//找到元素并获取2d画图权限
drawHeart();
intervalId = setInterval(()=>printHeart(), 10);
drawBg()
}
function drawBg(){
content = document.getElementById("bgCanvas").getContext("2d");//找到元素并获取2d画图权限
content.beginPath(); //开始绘图
// content.translate(250,250); //设置绘图原点
radian = 0;//弧度设为初始弧度
content.moveTo(getX(radian),getY(radian)); //移动绘图游标至原点
while(radian <= (Math.PI*2)){ //每增加一次弧度,绘制一条线
radian += Math.PI/180;
X = getX(radian);
Y = getY(radian);
content.lineTo(X,Y);
}
//设置描边样式
content.stroke(); //对路径描边
content.textBaseline="middle"; // 控制文字在坐标点的垂直方向位置
content.textAlign='center'; // 控制文字在坐标点的水平方向位置
content.font="bold 12px Alin"; // 只有设置了字体风格再设置大小(注意参数位置)
var gard1 = content.createLinearGradient(0, 50, 50, 50); //线性渐变的起止坐标
gard1.addColorStop(0,"red");
gard1.addColorStop(1,"blue");
content.fillStyle=gard1
content.fillText('安咯,这里是字符串',10,30);
}
// 画爱心
function drawHeart() {
radian = 0;//弧度设为初始弧度
ctx.moveTo(getX(radian), getY(radian));//初始点开始移动
var grd = ctx.createLinearGradient(50, 50, 150, 150); //线性渐变的起止坐标
grd.addColorStop(0,"red");
grd.addColorStop(1,"yellow");
ctx.lineWidth = 3;//设置线的宽度
ctx.strokeStyle = grd;// 设置线的颜色
i = 0;// 计数器
}
// 头像爱心路线
function printHeart() {
radian += Math.PI/180;
ctx.lineTo(getX(radian), getY(radian));//在旧点和新点之间连线
ctx.clearRect(0, 0, 300, 400);
ctx.stroke();//画线
var imgpeople = new Image()
imgpeople.src = "https://cdn-app-tx-bj.colorv.com/colorv/resource/ec6a8f22b19ef0496e4f97548fa3b664.png"
ctx.drawImage(imgpeople,getX(radian)-10, getY(radian)-10, 20,20);
i++;
if (i >= 180) {
clearInterval(intervalId);
}
}
function getX(t) {//由弧度得到 X 坐标
return 150 + r * (15 * Math.pow(Math.sin(t), 3));
}
function getY(t) {//由弧度得到 Y 坐标
return 70 - r * (14 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(3 * t));
}
</script>
</body>
</html>
画旋转太极
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>太极</title>
<style>
*{
padding: 0;
list-style: none;
margin: 0;
}
canvas{
display: block;
margin: 50px auto;
animation: rotate 2s linear infinite;
}
@keyframes rotate{
100%{
transform: rotate(360deg)
}
}
</style>
</head>
<body>
<canvas width="400" height="400" class="canvas"></canvas>
<script>
var canvas=document.querySelector(".canvas"),
ctx=canvas.getContext("2d"),
deg=Math.PI / 180;
ctx.beginPath();
ctx.arc(200,200,200,-deg*90,deg*90);
ctx.fillStyle="#000";
ctx.fill();
ctx.beginPath();
ctx.arc(200,200,200,deg*90,deg*270)
ctx.strokeStyle="#000";
ctx.stroke();
ctx.beginPath();
ctx.arc(200,100,100,-deg*90,deg*90);
ctx.fillStyle="#fff";
ctx.fill();
ctx.beginPath();
ctx.arc(200,300,100,deg*90,deg*270);
ctx.fillStyle="#000";
ctx.fill();
ctx.beginPath();
ctx.arc(200,100,30,0,deg*360);
ctx.fillStyle="#000";
ctx.fill();
ctx.beginPath();
ctx.arc(200,300,30,0,deg*360);
ctx.fillStyle="#fff";
ctx.fill();
</script>
</body>
</html>
圆环图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>扇形图</title>
<style>
*{
margin: 0;
padding: 0;
list-style: none;
}canvas{
display: block;
margin: 50px auto;
border: 1px solid #000;
}
</style>
</head>
<body>
<canvas width="800" height="500"></canvas>
<script>
//数据
var dataArray = [{
ang: 98,
color: "orangered",
num: 98
}, {
ang: 24,
color: "skyblue",
num: 24
}, {
ang: 54,
color: "orange",
num: 54
}, {
ang: 78,
color: "hotpink",
num: 78
}, {
ang: 100,
color: "greenyellow",
num: 100
}, {
ang: 16,
color: "tomato",
num: 16
}, {
ang: 86,
color: "wheat",
num: 86
}, {
ang: 48,
color: "aqua",
num: 48
}, {
ang: 90,
color: "#ccc",
num: 90
}];
var canvas = document.querySelector("canvas"),
deg = Math.PI / 180,
ctx = canvas.getContext("2d"),
start = 0;
var sum=dataArray.reduce(function(cur,pre){//求取所有数据总和
cur+=pre.ang;
return cur;
},0);
ctx.translate(400,250);//移动画布中心点
dataArray.forEach(function(item){//循环数组
var sanl = item.ang / sum * 360,//计算数据比例
end = start + sanl;//求结束点
//画扇形
ctx.beginPath();
ctx.fillStyle = item.color;//扇形颜色
ctx.moveTo( 0 , 0 );
ctx.arc( 0 , 0 , 200 , start * deg,end * deg);
ctx.fill();
//求中心点
var center=(start + sanl/2)*deg,
preX=Math.cos(center)*200,
preY=Math.sin(center)*200,
preX1=Math.cos(center)*230,
preY1=Math.sin(center)*230;
ctx.beginPath();
ctx.strokeStyle=item.color;
ctx.moveTo(preX,preY);
ctx.lineTo(preX1,preY1);
var x3=preX1<0?preX1 - 100:preX1 + 100;
ctx.lineTo(x3,preY1);
ctx.stroke();
ctx.beginPath();
ctx.arc(x3, preY1, 5, 0, 360 * deg);
ctx.fill();
ctx.font = "16px nomal";
ctx.textAlign = "center";
x3 = preX1 < 0 ? preX1 - 60 : preX1 + 60;
ctx.fillText(item.num, x3, preY1 - 5);
start=end;
})
//中心大白圆
ctx.beginPath();
ctx.fillStyle="#fff";
ctx.arc(0,0,150,0,360*deg);
ctx.fill();
</script>
</body>
</html>
刻度尺
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>刻度尺</title>
<style>
*{
margin: 0;
padding: 0;
list-style: none;
}canvas{
display: block;
border: 1px solid #000;
margin: 50px auto;
}
</style>
</head>
<body>
<canvas width="530" height="100" class="canvas"></canvas>
<script>
var canvas=document.querySelector(".canvas"),
ctx=canvas.getContext("2d");
du=Math.PI /180;
ctx.fillStyle="#ccc";
ctx.fillRect(0,40,530,60);
ctx.arc(50,70,20,0,du*360);
ctx.fillStyle="red";
ctx.fill();
ctx.beginPath();//开启路径
ctx.arc(200,68,15,0,du*360);
ctx.fillStyle="yellow";
ctx.fill();
ctx.beginPath();//开启路径
ctx.arc(300,67,10,0,du*360);
ctx.fillStyle="skyblue";
ctx.fill();
var data={
num:10*10+1,//刻度线
x:10,//x轴坐标
y:5,//y轴坐标
deg:5,//间隙宽
height:10,//线高
}
render(data);//调用渲染方法
function render(obj){
for(var i=0;i < obj.num;i++){//循环划线
ctx.beginPath();//开启路径
ctx.moveTo(obj.deg*i+obj.x,obj.y);//起始坐标
ctx.fillStyle="#000";//线颜色
ctx.font="14px normal";//数字大小
ctx.textAlign="center";//水平居中
ctx.textBaseline="middle";//垂直居中
if(i%10===0){
ctx.lineTo(obj.deg*i+obj.x,obj.height+10);
ctx.fillText(i / 10,obj.x+i*obj.deg,30)
}
else{
ctx.lineTo(obj.deg*i+obj.x,i%5===0?obj.height+5:obj.height);
}
ctx.stroke();//描边 切记描边
}
}
</script>
</body>
</html>
表盘(类转速表)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>表盘</title>
<style>
*{
padding: 0;
margin: 0;
list-style: none;
}canvas{
border: 1px solid #000;
margin: 50px auto;
display: block;
}
</style>
</head>
<body>
<canvas width="500" height="500" class="canvas"></canvas>
<script>
var canvas=document.querySelector(".canvas"),
ctx=canvas.getContext("2d"),
deg=Math.PI/180;
//进度条
ctx.beginPath();
ctx.translate(250,250);//改变中心
ctx.lineWidth="20";//线宽
ctx.lineCap="round";//线端点样式
ctx.strokeStyle="#ccc";//线颜色
ctx.arc(0,0,150,deg*150,deg*30);//画半圆
ctx.stroke();//描边
//刻度线-刻度值
for(var i=0;i<=100;i++){
ctx.save();//保存原画布状态
ctx.beginPath();
ctx.lineWidth="1";//线粗
ctx.strokeStyle="#000";//线的颜色
ctx.textAlign="center";//字体居中
ctx.font="16px normal";//字体大小
ctx.rotate((i*2.4 - 120)*deg);//每条线的位置
if(i%10===0){
ctx.moveTo(0,-170);
ctx.lineTo(0,-195);
ctx.fillText(i,0,-200);//刻度值
}else{
ctx.moveTo(0,-170);
ctx.lineTo(0,-185);
}
ctx.stroke();//描边
ctx.restore();//返回保存过的路径状态和属性
}
//动画
var num=0;
function draw(){
num++;
if(num<100){
requestAnimationFrame(draw);
}
var endDeg = 150 + 2.4 * num;//每一个刻度所占度数
ctx.clearRect(-55, -50, 110, 100);//用于改变数据 视觉效果
var color=ctx.createLinearGradient(0,250,200,250);//设置渐变色
color.addColorStop(0,'yellow');//起始颜色
color.addColorStop(1,"red");//终止颜色
ctx.beginPath();
ctx.lineWidth=20;//线宽
ctx.lineCap="round";//圆角端点
ctx.strokeStyle=color;//渐变色
ctx.arc(0,0,150,deg*150,endDeg*deg);
ctx.stroke();
//数字
ctx.font="50px normal";//字体大小
ctx.textAlign="center";//水平居中
ctx.textBaseline="middle";//垂直居中
ctx.fillText(num+"%",0,0)//数据展示位置
}
draw();
</script>
</body>
</html>
画板(类画图工具)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
canvas {
display: block;
}
</style>
</head>
<body>
<canvas width="500" height="400"></canvas>
<div class="wrapper">
<input id="color" type="color" value="#ffffff">
<input id="range" type="range" max="50" min="5">
<button id="brush" type="button">画笔</button>
<button id="rubbish" type="button">垃圾桶</button>
<button id="save" type="button">保存</button>
</div>
<script>
function $(selector) {
return typeof selector === "string" ? document.querySelector(selector) : selector;
};
var canvas = document.querySelector("canvas"),
ctx = canvas.getContext("2d");
ctx.fillRect(0, 0, canvas.width, canvas.height);
bindEventFn();
function bindEventFn() {
$("#brush").addEventListener("click", brushFn);
$("#rubbish").addEventListener("click", rubshFn);
$("#save").addEventListener("click", saveFn);
canvas.addEventListener("mousedown", startFn)
};
//1.source-over
//这是默认值,他表示绘制的图形将画在现有画布之上
//2.destination-out
//在与源不重叠的区域上保留目标。其他部分都变成透明的。
function brushFn() {
if (this.innerHTML === "画笔") {
this.innerHTML = "橡皮擦";
ctx.globalCompositeOperation = "source-over";
} else {
this.innerHTML = "画笔";
ctx.globalCompositeOperation = "destination-out";
}
}
function saveFn() {
//把画布转换为路径
var src = canvas.toDataURL();
var img = new Image(); //创建一张图片
img.src = src;
img.onload = function() {
document.body.appendChild(img);
}
}
function rubshFn() {
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
var startPos = null;
function startFn(e) {
startPos = {
x: e.pageX - this.offsetLeft,
y: e.pageY - this.offsetTop
};
ctx.beginPath();
ctx.moveTo(startPos.x, startPos.y)
canvas.addEventListener("mousemove", moveFn);
canvas.addEventListener("mouseup", upFn);
};
function moveFn(e) {
var moveX = e.pageX - this.offsetLeft,
moveY = e.pageY - this.offsetTop;
ctx.lineWidth = $("#range").value;
ctx.strokeStyle = $("#color").value;
ctx.lineTo(moveX, moveY);
ctx.stroke();
};
function upFn() {
canvas.removeEventListener("mousemove", moveFn);
}
</script>
</body>
</html>