封装成js和css文件:
painter.js
/*
* @Author: ion
* @Date: 2018-10-12 00:43:22
* @Last Modified by: ion
* @Last Modified time: 2018-10-12 01:48:58
*/
var record =[];
var $elBox;
$(function(){
//下载图片
var downloadImage = document.getElementById('downloadImage');
bindButtonEvent(downloadImage, "click", saveAsLocalImage);
//设置画笔颜色
$("#penColor").colpick({
layout:'rgbhex',
color:'ff8800',
onSubmit:function(hsb,hex,rgb,el) {
$(el).css('background-color', '#'+hex);
$(el).colpickHide();
$(el).attr('color-mark','#'+hex);
}
}).css('background-color', '#ff8800');
});
//初始化界面,为控件区域添加必要的html元素
function initUI($el){
var view = `
<div class="painter_win">
<div class="setWH">
<span>请输入画布大小:</span>
<div class="setCanvas">
<input type="text" id="canvas_width" value="500"> x <input type="text" id="canvas_height" value="300">
</div>
<button id="submitSet" onclick="createCanvas()">确定</button>
</div>
<div class="tool">
<ul>
<li>
画笔颜色
<input type="text" id="penColor" color-mark="#ff8800">
</li>
<li id="setWe">
画笔粗细
<input type="text" id="penWeight" value="3">
</li>
<li class="reduceW" onclick="backStep()">撤回</li>
<li class="reduceW" onclick="clearCanvas()">清空</li>
<li id="downloadImage">下载图片</li>
</ul>
</div>
<div id="content"></div>
</div>
`;
$el.append(view);
$elBox=$el;
}
//创建canvas画布
function createCanvas(){
if(!$("#content #box")[0]){
var width = $(".painter_win .setWH #canvas_width").val();
var height = $(".painter_win .setWH #canvas_height").val();
if(width || height){
var boxOffsetX =$elBox[0].offsetLeft;
var boxOffsetY =$elBox[0].offsetTop;
initCanvas(width,height,boxOffsetX,boxOffsetY);
$(".tool").show();
}else{
alert("请输入画布大小");
}
}
}
//初始化画布,添加鼠标事件
function initCanvas(width,height,boxOffsetX,boxOffsetY){
let txt = `<canvas id="box" width="${width}" height="${height}"></canvas>`;
$("#content").append(txt);
$("#box").css({
'position' : 'relative',
'left' : '50%',
'margin-left': -width/2,
'margin-top' : '20px'
});
var box=document.getElementById('box');
var ctx=box.getContext('2d');
box.onmousedown=function(e){
record.push(box.toDataURL());
e=e||window.event;
var penColor = $("#penColor").attr('color-mark');
var penWeight = $("#penWeight").val();
ctx.strokeStyle= penColor;
ctx.lineWidth = penWeight;
ctx.beginPath();
var ox=e.clientX-box.offsetLeft-boxOffsetX;
var oy=e.clientY-box.offsetTop-boxOffsetY;
ctx.moveTo(ox,oy);
box.onmousemove=function(e){
var ox1=e.clientX-box.offsetLeft-boxOffsetX;
var oy1=e.clientY-box.offsetTop-boxOffsetY;
ctx.lineTo(ox1,oy1);
ctx.stroke();
}
box.onmouseup=function(){
box.onmousemove=null;
ctx.closePath();
}
}
}
//撤销
function backStep(){
if(record.length>0){
//不加上下面语句会出现oc is not defined问题,暂未理解
ctx=box.getContext('2d');
var canvasPic = new Image();
resetCanvas();
canvasPic.src = record.pop();
//一定要加载完图片再进行绘制
canvasPic.onload = function(){
ctx.drawImage(canvasPic, 0, 0);
}
}
}
// 清空canvas画布
function resetCanvas(){
//canvas每当高度或宽度被重设时,画布内容就会被清空
box.height = box.height;
}
//清空操作 把操作记录也清空
function clearCanvas(){
resetCanvas();
record = [];
}
//添加事件监听 兼容IE
function bindButtonEvent(element, type, handler){
if(element.addEventListener) {
element.addEventListener(type, handler, false);
} else {
element.attachEvent('on'+type, handler);
}
}
//保存本地
function saveAsLocalImage () {
var box=document.getElementById('box');
var image = box.toDataURL("image/png").replace("image/png", "image/octet-stream");
window.location.href=image;
}
painter.css
/*
* @Author: ion
* @Date: 2018-10-12 00:21:13
* @Last Modified by: ion
* @Last Modified time: 2018-10-12 01:00:34
*/
*{margin:0;padding: 0}
.painter_win{background-color: #f2f2f2;width: 100%;font-size: 16px;}
.painter_win>.setWH{padding: 40px;}
canvas#box{border: 2px solid #333;box-shadow: 10px 10px 5px #9E9E9E;}
.painter_win .setWH{background: #ccc;}
.setWH .setCanvas{display: inline;}
.setWH #canvas_width,.setWH #canvas_height{width: 50px;}
.tool{overflow: hidden;display: none;}
.setWH #submitSet{margin-left: 20px;text-decoration: none;padding: 4px 9px;
border-radius: 7px;background: #03A9F4;color: #fff;}
.tool ul{list-style: none;position: relative;left: 50%;margin-left: -284px;margin-top:20px;overflow: hidden;}
.tool ul>li{float: left;width: 90px; background-color: #03A9F4;color: #fff;padding: 10px;text-align: center;margin-left: 20px;border-radius: 6px;cursor: pointer;}
.tool ul>li:first-child{margin-left: 0;}
.tool ul>li:hover{background-color: #3f51b5;color: #03A9F4}
.tool ul>li.reduceW{width:58px;}
.tool .setWe{text-align: left;}
.tool #penWeight,.tool #penColor{width: 17px;display: inline-block;color: #605454;}
.tool #penColor{cursor: pointer;}
.painter_win #content{width: 100%;}
html引用控件说明:
/*
*使用要先在头部引用colpick.css和painter.css
* colpick.js和painter.js依赖于jquery,故需先引入jquery库
* 引入脚本样式文件多的时候可以配置require.js引入
*/
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>canvas鼠标绘图</title>
<link rel="stylesheet" href="colpick.css" type="text/css"/>
<link rel="stylesheet" href="painter.css" type="text/css"/>
<style>
.canvasArea{display: inline-block;position: absolute;top: 50%;left: 50%;width: 700px;background-color: #ccc;margin-left: -350px; margin-top: -250px;}
</style>
</head>
<body>
//在指定区域div引用控件
<div class="canvasArea"></div>
</body>
<script src="jquery-3.3.1.js"></script>
<script src="colpick.js" type="text/javascript"></script>
<script src="painter.js"></script>
<script>
var area = $(".canvasArea");
initUI(area);
</script>
</html>
写到晚上两点终于完成了,1点之后效率太低,一个很简单的问题想了足足一个小时,还是要早睡早起啊,晚上真的脑子转不起来,不早了,晚安!