想象一下,用几行代码就能创造出如此逼真的图像和动画,仿佛将艺术与科技完美融合,前端开发的Canvas技术正是这个数字化时代中最具魔力的一环,它不仅仅是网页的一部分,更是一个无限创意的画布,一个让你的想象力自由驰骋的平台。
目录
基础页面搭建
绘画操作
按钮点击事件
最后总结
基础页面搭建
接下来借助canvas实现一个简易的画版操作,首先这里我们设置一下画布的一些基础布局样式:
<body>
<canvas id="canvas" width="800" height="600" style="border: 1px solid #ccc;"></canvas>
<hr>
<button id="boldBtn" type="button">粗线条</button>
<button id="thinBtn" type="button">细线条</button>
<button id="saveBtn" type="button">保持签名</button>
<input type="color" name="" id="color" value="">
<button class="clearBtn">橡皮擦</button>
<button id="nullBtn">清空画布</button>
</body>
实现的效果如下所示,一个比较简陋的画布,以及一些基础操作的按钮:
绘画操作
接下来我们开始实现绘画操作的功能,通过监听鼠标不同情况的事件来实现画布上书写内容的操作,首先这里我们先绘制画布以及获取对应的dom元素进行操作:
<script>
// 获取canvas画布绘制上下文对象以及获取2d画笔对象
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
ctx.lineJoin = 'round'; // 线条连接处为圆角
ctx.lineCap = 'round'; // 线条端点为圆角
// 获取DOM元素
let boldBtn = document.getElementById("boldBtn");
let thinBtn = document.getElementById("thinBtn");
let saveBtn = document.getElementById("saveBtn");
let color = document.getElementById("color");
let clearBtn = document.getElementsByClassName("clearBtn")[0];
let nullBtn = document.getElementById("nullBtn");
</script>
接下来开始开始监听鼠标的按下、弹起、移动以及离开画布的四种情况的操作,完整代码如下:
<script>
// 获取canvas画布绘制上下文对象以及获取2d画笔对象
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
ctx.lineJoin = 'round'; // 线条连接处为圆角
ctx.lineCap = 'round'; // 线条端点为圆角
// 获取DOM元素
let boldBtn = document.getElementById("boldBtn");
let thinBtn = document.getElementById("thinBtn");
let saveBtn = document.getElementById("saveBtn");
let color = document.getElementById("color");
let clearBtn = document.getElementsByClassName("clearBtn")[0];
let nullBtn = document.getElementById("nullBtn");
// 设置是否开始绘画的变量
let isDraw = false;
// 鼠标按下去函数
canvas.onmousedown = function(e) {
isDraw = true; // 开始绘画
ctx.beginPath(); // 开始路径
// 获取鼠标点击的坐标
let x = e.pageX - canvas.offsetLeft;
let y = e.pageY - canvas.offsetTop;
ctx.moveTo(x, y); // 移动到当前点
}
// 鼠标移动函数
canvas.onmousemove = function(e) {
if (isDraw) { // 如果开始绘画
let x = e.pageX - canvas.offsetLeft;
let y = e.pageY - canvas.offsetTop;
ctx.lineTo(x, y); // 绘制
ctx.stroke()
}
}
// 鼠标弹起函数
canvas.onmouseup = function(e) {
isDraw = false; // 结束绘画
ctx.closePath(); // 结束路径
}
// 鼠标离开画布函数
canvas.onmouseleave = function(e) {
isDraw = false; // 结束绘画
ctx.closePath(); // 结束路径
}
</script>
最终呈现的效果如下所示:
按钮点击事件
接下来给画布下方的按钮设置对应的点击事件,让其能够实现对应的功能,如下:
粗线条:这里设置点击事件函数如下,遮盖策略设置在现有画布上下文之上绘制新图形,点击之后宽度增加到20,并添加对应激活类名active,删除其他按钮可能存在的active类名:
// 粗线条函数
boldBtn.onclick = function(e) {
ctx.globalCompositeOperation = 'source-over';
ctx.lineWidth = 20
boldBtn.classList.add("active");
thinBtn.classList.remove("active");
clearBtn.classList.remove("active");
}
细线条:这里设置点击事件函数如下,遮盖策略设置在现有画布上下文之上绘制新图形,点击之后宽度减少到2,并添加对应激活类名active,删除其他按钮可能存在的active类名:
// 细线条函数
thinBtn.onclick = function(e) {
ctx.globalCompositeOperation = 'source-over';
ctx.lineWidth = 2
thinBtn.classList.add("active");
boldBtn.classList.remove("active");
clearBtn.classList.remove("active");
}
保存签名:获取图片数据并创建一个a标签进行文件下载:
// 保存签名函数
saveBtn.onclick = function(e) {
let urlData = canvas.toDataURL(); // 获取图片数据
// let img = new Image()
// img.src = urlData; // 图片地址
// document.body.appendChild(img); // 添加图片到body
let downloadA = document.createElement("a"); // 创建a标签
downloadA.setAttribute("download", "签名"); // 设置下载文件名
downloadA.href = urlData; // 设置a标签的地址
downloadA.click(); // 点击a标签
}
修改颜色:设置监听函数,动态修改canvas颜色:
// 颜色选择函数
color.onchange = function(e) {
ctx.strokeStyle = color.value; // 设置线条颜色
}
橡皮擦:这里设置点击事件函数如下,遮盖策略设置现有内容保持在新图形不重叠的地方,点击之后区域呈现空白,并添加对应激活类名active,删除其他按钮可能存在的active类名:
// 橡皮擦函数
clearBtn.onclick = function(e) {
// 清除画布
ctx.globalCompositeOperation = 'destination-out';
ctx.lineWidth = 30
clearBtn.classList.add("active");
boldBtn.classList.remove("active");
thinBtn.classList.remove("active");
}
清空画布:调用canvas函数直接清除整个画布的内容:
// 清空画布函数
nullBtn.onclick = function(e) {
ctx.clearRect(0, 0, 800, 600);
}
最终呈现的效果如下所示:
最后总结
本次代码实现了一个简单的画板功能,让用户可以在网页上绘制、调整线条粗细、选择颜色、保存签名等操作。以下是代码的实现思路:
1)HTML结构部分:
在<body>中包含一个 <canvas> 元素,用于绘制图形。
一组按钮和一个颜色选择器,用于控制画笔的粗细、颜色以及清除和保存绘制的功能。
2)CSS部分:
定义了一个按钮的样式 .active,用于表示当前选中状态,例如粗线条、细线条、橡皮擦等按钮会根据点击状态变化背景颜色。
3)JavaScript部分:
《1》获取元素:
使用 document.getElementById 和 document.getElementsByClassName 获取 <canvas> 和各种控制按钮。
《2》绘图相关事件:
canvas.onmousedown:鼠标按下时开始绘画,记录起始点。
canvas.onmousemove:鼠标移动时,如果正在绘画(isDraw为真),则根据当前鼠标位置绘制线条。
canvas.onmouseup 和 canvas.onmouseleave:鼠标抬起或离开画布时结束绘画路径。《3》功能按钮事件:
粗线条 (boldBtn) 和 细线条 (thinBtn):设置线条宽度,并通过 classList 控制按钮的选中状态。
保存签名 (saveBtn):使用 canvas.toDataURL() 获取绘制内容的DataURL,创建一个下载链接,允许用户保存签名。
颜色选择 (color):通过 color.onchange 设置绘制线条的颜色。
橡皮擦 (clearBtn):使用 ctx.globalCompositeOperation = 'destination-out' 实现擦除效果,清除画布上的内容。
清空画布 (nullBtn):使用 ctx.clearRect() 清除整个画布的内容。《4》绘图上下文:
使用 getContext('2d') 获取 Canvas 2D 渲染上下文对象 ctx,设置线条的样式(圆角连接和端点)。
这段代码整合了 HTML、CSS 和 JavaScript,提供了一个简单而功能丰富的在线绘图工具,用户可以通过点击不同的按钮和操作来绘制、擦除、保存签名等。完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
button.active {
color: #fff;
background-color: orange;
}
</style>
</head>
<body>
<canvas id="canvas" width="800" height="600" style="border: 1px solid #ccc;"></canvas>
<hr>
<button id="boldBtn" type="button">粗线条</button>
<button id="thinBtn" type="button">细线条</button>
<button id="saveBtn" type="button">保存签名</button>
<input type="color" name="" id="color" value="">
<button class="clearBtn">橡皮擦</button>
<button id="nullBtn">清空画布</button>
<script>
// 获取canvas画布绘制上下文对象以及获取2d画笔对象
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
ctx.lineJoin = 'round'; // 线条连接处为圆角
ctx.lineCap = 'round'; // 线条端点为圆角
// 获取DOM元素
let boldBtn = document.getElementById("boldBtn");
let thinBtn = document.getElementById("thinBtn");
let saveBtn = document.getElementById("saveBtn");
let color = document.getElementById("color");
let clearBtn = document.getElementsByClassName("clearBtn")[0];
let nullBtn = document.getElementById("nullBtn");
// 设置是否开始绘画的变量
let isDraw = false;
// 鼠标按下去函数
canvas.onmousedown = function(e) {
isDraw = true; // 开始绘画
ctx.beginPath(); // 开始路径
// 获取鼠标点击的坐标
let x = e.pageX - canvas.offsetLeft;
let y = e.pageY - canvas.offsetTop;
ctx.moveTo(x, y); // 移动到当前点
}
// 鼠标移动函数
canvas.onmousemove = function(e) {
if (isDraw) { // 如果开始绘画
let x = e.pageX - canvas.offsetLeft;
let y = e.pageY - canvas.offsetTop;
ctx.lineTo(x, y); // 绘制
ctx.stroke()
}
}
// 鼠标弹起函数
canvas.onmouseup = function(e) {
isDraw = false; // 结束绘画
ctx.closePath(); // 结束路径
}
// 鼠标离开画布函数
canvas.onmouseleave = function(e) {
isDraw = false; // 结束绘画
ctx.closePath(); // 结束路径
}
// 粗线条函数
boldBtn.onclick = function(e) {
ctx.globalCompositeOperation = 'source-over';
ctx.lineWidth = 20
boldBtn.classList.add("active");
thinBtn.classList.remove("active");
clearBtn.classList.remove("active");
}
// 细线条函数
thinBtn.onclick = function(e) {
ctx.globalCompositeOperation = 'source-over';
ctx.lineWidth = 2
thinBtn.classList.add("active");
boldBtn.classList.remove("active");
clearBtn.classList.remove("active");
}
// 保存签名函数
saveBtn.onclick = function(e) {
let urlData = canvas.toDataURL(); // 获取图片数据
// let img = new Image()
// img.src = urlData; // 图片地址
// document.body.appendChild(img); // 添加图片到body
let downloadA = document.createElement("a"); // 创建a标签
downloadA.setAttribute("download", "签名"); // 设置下载文件名
downloadA.href = urlData; // 设置a标签的地址
downloadA.click(); // 点击a标签
}
// 颜色选择函数
color.onchange = function(e) {
ctx.strokeStyle = color.value; // 设置线条颜色
}
// 橡皮擦函数
clearBtn.onclick = function(e) {
// 清除画布
ctx.globalCompositeOperation = 'destination-out';
ctx.lineWidth = 30
clearBtn.classList.add("active");
boldBtn.classList.remove("active");
thinBtn.classList.remove("active");
}
// 清空画布函数
nullBtn.onclick = function(e) {
ctx.clearRect(0, 0, 800, 600);
}
</script>
</body>
</html>