canvas 实现画板

254 阅读2分钟

1 前言

canvas本身没有绘图能力,只是定义了一个容器,都是由canvas内部的CanvasRenderingContext2D对象来做。

2 简介

介绍一下需要用到的属性

标签描述
height设置 canvas 的高度。
width设置 canvas 的宽度。
clearRect(x,y,width,height)清除指定矩形区域,让清除部分完全透明
ctx.strokeStyle可以改变画笔颜色
ctx.beginPath()设置开始路径
ctx.moveTo(x,y)设置起点
ctx.lineTo(x,y)设置终点
ctx.stroke()绘制
ctx.closePath()结束路径
ctx.save()保存当前绘制状态
ctx.clip()当前剪贴区域
ctx.restore()恢复之前保存的绘图状态
ctx.arc(弧形圆心x坐标,y坐标,半径,起始角(以3点钟的位置开始),结束角、方向(true表示逆时针,false表示顺时针))绘制一个弧形

3 代码实现

3.1 静态页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>画板</title>
    <style type="text/css">
        * {
            padding: 0;
            margin: 0;
        }

        #box {
            width: 600px;
            height: 500px;
            margin: 100px auto;
            border: 1px solid black;
        }

        #box .control {
            height: 100px;
        }

        #box .control div {
            height: 50px;
            line-height: 50px;
        }

        #box .control .changeColor {
            padding-left: 15px;
        }

        #box .control .changeColor input {
            width: 30px;
            height: 30px;
            margin: 0 15px;
            vertical-align: middle;
        }

        #box .control .changeColor input:first-of-type {
            background-color: black;
        }

        #box .control .changeColor input:nth-of-type(2) {
            background-color: pink;
        }

        #box .control .changeColor input:nth-of-type(3) {
            background-color: red;
        }

        #box .control .changeColor input:nth-of-type(4) {
            background-color: orange;
        }

        #box .control .changeColor input:nth-of-type(5) {
            background-color: brown;
        }

        #box .control .changeColor input:nth-of-type(6) {
            background-color: purple;
        }

        #box .control .clear {
            height: 50px;
        }

        #box .control .clear input {
            width: 100px;
            height: 50px;
            margin-left: 15px;
            font-size: 20px;
            background-color: oldlace;
        }

        #canvas {
            background-color: blanchedalmond;
        }

        b {
            font-size: 20px;
        }
    </style>
</head>
<body>
<div id="box">
    <div class="control">
        <div class="changeColor">
            选择画笔颜色:
            <input type="button"/>
            <input type="button"/>
            <input type="button"/>
            <input type="button"/>
            <input type="button"/>
            <input type="button"/>
        </div>
        <div class="clear">
            <input type="button" value="清空画布"/>
            当前选中的颜色是:<b>黑色</b>
            <input type="button" value="橡皮擦"/>
        </div>
    </div>
    <canvas id="canvas" width="600" height="400"></canvas>
</div>
</body>
</html>

静态页面.png

3.2 画笔功能

画笔实现思路

  1. 获取canvas
  2. 设置初始化当前画布功能为画笔状态,以为我们后边要做橡皮擦功能,点击橡皮擦和颜色的时候要做一个区分。
  3. 鼠标按下记录鼠标点击位置距离canvas画布的坐标并移动,记录上一个坐标点,然后移动鼠标开始画画
  4. 鼠标抬起移除鼠标移动事件
<script type="text/javascript">
    var canvas = document.querySelector("#canvas");
    var ctx = canvas.getContext("2d");

    //初始化当前画布为画笔状态
    canvas.isDraw = true;

    //按下事件
    canvas.addEventListener("mousedown",function(e){
        //鼠标点击在canvas中的位置

        var x = e.offsetX;
        var y = e.offsetY;

        //记录旧的点
        this.oldPoint = {
                x : x - 1,
                y : y - 1
        }

        if (this.isDraw) {
                //画笔功能
                draw(x,y);
        } else {
                //橡皮擦功能
                clearPart(x,y);
        }

        //绑定移动和抬起事件
        this.addEventListener("mousemove",move);
        this.addEventListener("mouseup",up);
    })

    function up() {
        this.removeEventListener("mousemove",move);
    }

    function move(e) {
        var x = e.offsetX;
        var y = e.offsetY;

        if (this.isDraw) {
                //画笔功能
                draw(x,y);
        } else {
                //橡皮擦功能
                clearPart(x,y);
        }

        this.oldPoint = {
                x : x,
                y : y
        }

    }

    //画的方法
    function draw(x,y){
        ctx.beginPath();

        //线的宽度
        ctx.lineWidth = 5;

        //线的样式
        ctx.lineCap = "round";
        ctx.moveTo(x,y);
        ctx.lineTo(canvas.oldPoint.x,canvas.oldPoint.y);
        ctx.stroke();
        ctx.closePath();
    }
</script>

3.3 颜色选择

颜色实现思路

  1. 点击颜色让画布的ctx.strokeStyle等于你点击的背景颜色
  2. 创建颜色数据结构,根据颜色改变b标签的内容
//获取改变颜色按钮
var btns = document.querySelectorAll(".changeColor input");
for (var i = 0; i < btns.length; i++) {
    btns[i].onclick = changeColor;
}

//颜色匹配数据结构
var colorObj = {
    "#000000" : "黑色",
    "#ffc0cb" : "粉色",
    "#ff0000" : "红色",
    "#ffa500" : "橘色",
    "#a52a2a" : "棕色",
    "#800080" : "紫色"
}

//改变画笔颜色
function changeColor() {
    ctx.strokeStyle = getComputedStyle(this,null).backgroundColor;
    var b = document.querySelector("b");
    b.style.color = ctx.strokeStyle;

    b.innerHTML = colorObj[ctx.strokeStyle];

    //改变画笔状态
    canvas.isDraw = true;
}

画笔.gif

3.4 橡皮擦

橡皮擦思路

  1. 获取元素节点,改变橡皮擦状态
  2. 利用canvas剪裁的思路 裁剪(在canvas中的裁剪和平时的裁剪功能不一样在这里,裁剪是指在裁剪区域去显示我们所画的图)
var clearBtn = document.querySelector(".clear input:last-of-type");	
    clearBtn.onclick = function () {
        //改变状态为橡皮擦状态
        canvas.isDraw = false;
    }
    //橡皮擦功能
    function clearPart(x,y) {
        //保存场景
        ctx.save();
        ctx.beginPath();
        ctx.arc(x,y,10,0,Math.PI * 2,false);
        ctx.clip();
        ctx.clearRect(0,0,canvas.width,canvas.height);
        //还原场景
        ctx.restore();
    }

橡皮擦.gif

3.5 清空画布

清空画布思路

  1. 获取元素节点
  2. 点击按钮清空canvas画布
var clearAllBtn  = document.querySelector(".clear input");
    clearAllBtn.onclick = function () {
        ctx.clearRect(0,0,canvas.width,canvas.height);
    }

清空画布.gif

4 完整代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>画板</title>
    <style type="text/css">
        * {
            padding: 0;
            margin: 0;
        }

        #box {
            width: 600px;
            height: 500px;
            margin: 100px auto;
            border: 1px solid black;
        }

        #box .control {
            height: 100px;
        }

        #box .control div {
            height: 50px;
            line-height: 50px;
        }

        #box .control .changeColor {
            padding-left: 15px;
        }

        #box .control .changeColor input {
            width: 30px;
            height: 30px;
            margin: 0 15px;
            vertical-align: middle;
        }

        #box .control .changeColor input:first-of-type {
            background-color: black;
        }

        #box .control .changeColor input:nth-of-type(2) {
            background-color: pink;
        }

        #box .control .changeColor input:nth-of-type(3) {
            background-color: red;
        }

        #box .control .changeColor input:nth-of-type(4) {
            background-color: orange;
        }

        #box .control .changeColor input:nth-of-type(5) {
            background-color: brown;
        }

        #box .control .changeColor input:nth-of-type(6) {
            background-color: purple;
        }

        #box .control .clear {
            height: 50px;
        }

        #box .control .clear input {
            width: 100px;
            height: 50px;
            margin-left: 15px;
            font-size: 20px;
            background-color: oldlace;
        }

        #canvas {
            background-color: blanchedalmond;
        }

        b {
            font-size: 20px;
        }
    </style>
</head>
<body>
<div id="box">
    <div class="control">
        <div class="changeColor">
            选择画笔颜色:
            <input type="button"/>
            <input type="button"/>
            <input type="button"/>
            <input type="button"/>
            <input type="button"/>
            <input type="button"/>
        </div>
        <div class="clear">
            <input type="button" value="清空画布"/>
            当前选中的颜色是:<b>黑色</b>
            <input type="button" value="橡皮擦"/>
        </div>
    </div>
    <canvas id="canvas" width="600" height="400"></canvas>
</div>
<script type="text/javascript">
    var canvas = document.querySelector("#canvas");
    var ctx = canvas.getContext("2d");

    //初始化当前画布为画笔状态
    canvas.isDraw = true;

    //按下事件
    canvas.addEventListener("mousedown", function (e) {
        //计算出鼠标点击在canvas中的位置

        var x = e.offsetX;
        var y = e.offsetY;

        //记录旧的点
        this.oldPoint = {
            x: x - 1,
            y: y - 1
        }

        if (this.isDraw) {
            //画笔功能
            draw(x, y);
        } else {
            //橡皮擦功能
            clearPart(x, y);
        }

        //绑定移动和抬起事件
        this.addEventListener("mousemove", move);
        this.addEventListener("mouseup", up);
    });

    function up() {
        this.removeEventListener("mousemove", move);
    }

    function move(e) {
        var x = e.offsetX;
        var y = e.offsetY;

        if (this.isDraw) {
            //画笔功能
            draw(x, y);
        } else {
            //橡皮擦功能
            clearPart(x, y);
        }

        this.oldPoint = {
            x: x,
            y: y
        }

    }

    //画的方法
    function draw(x, y) {
        ctx.beginPath();

        //线的宽度
        ctx.lineWidth = 5;

        //线的样式
        ctx.lineCap = "round";
        ctx.moveTo(x, y);
        ctx.lineTo(canvas.oldPoint.x, canvas.oldPoint.y);
        ctx.stroke();
        ctx.closePath();
    }

    //获取改变颜色按钮
    var btns = document.querySelectorAll(".changeColor input");
    for (var i = 0; i < btns.length; i++) {
        btns[i].onclick = changeColor;
    }

    //颜色匹配数据结构
    var colorObj = {
        "#000000": "黑色",
        "#ffc0cb": "粉色",
        "#ff0000": "红色",
        "#ffa500": "橘色",
        "#a52a2a": "棕色",
        "#800080": "紫色"
    };

    //改变画笔颜色
    function changeColor() {
        ctx.strokeStyle = getComputedStyle(this, null).backgroundColor;
        var b = document.querySelector("b");
        b.style.color = ctx.strokeStyle;

        b.innerHTML = colorObj[ctx.strokeStyle];

        //改变画笔状态
        canvas.isDraw = true;
    }

    var clearAllBtn = document.querySelector(".clear input");
    clearAllBtn.onclick = function () {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
    };

    //橡皮擦按钮
    var clearBtn = document.querySelector(".clear input:last-of-type");

    clearBtn.onclick = function () {
        //改变状态为橡皮擦状态
        canvas.isDraw = false;
    };

    //橡皮擦功能
    function clearPart(x, y) {
        //保存场景
        ctx.save();
        ctx.beginPath();
        ctx.arc(x, y, 10, 0, Math.PI * 2, false);
        ctx.clip();
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        //还原场景
        ctx.restore();
    }

</script>
</body>
</html>

5 最后

录屏总感觉哪里不对,后来发现单词写错了,比较懒,不想改了,就这样看吧哈哈。

各位,早点下班,顺便留下你的脚印,谢谢