黑板

实现原理

思路

  1. 可以移动的画笔 线条是连贯的
  2. 使用鼠标左键能够在黑板上写字
  3. 使用鼠标右键能够擦除已写的字
  4. 画笔和橡皮擦切换

关键步骤

绘制从固定点放射出来的直线

window.onload = function (){
    var cvs = document.getElementById("cvs");
    var ctx = cvs.getContext("2d");

    var lastX = 250;
    var lastY = 250;
    cvs.onmousedown = function(e){
        paint(e);
    }
}

// 绘制
function paint(e){ // e是鼠标事件参数
    ctx.beginPath();
    ctx.moveTo(lastX, lastY);
    ctx.lineTo(e.offsetX, e.offsetY);
    ctx.stroke();
}

绘制折线

// 绘制
function paint(e){ // e是鼠标事件参数
    // 第一次绘制时初始化lastX,lastY的值
    if (lastX === undefined) {
        lastX = e.offsetX;
        lastY = e.offsetY;
        return;
    }

    // 绘制线段
    ctx.beginPath();
    ctx.moveTo(lastX, lastY);
    ctx.lineTo(e.offsetX, e.offsetY);
    ctx.stroke();

    // 记录上次的结束点
    lastX = e.offsetX;
    lastY = e.offsetY;
}

自由绘制

cvs.onmousemove = function(e){
    paint(e);
}

鼠标按下才绘图

var state = 0; // 0: 什么都不做 1: 绘制

cvs.onmousedown = function(e){
    state = 1;
}

cvs.onmouseup = function (){
    // 重置状态
    state = 0;
}

cvs.onmousemove = function(e) {
    if (state === 1) {
        paint(e);
    } 
}

擦除

var state = 0; // 0: 什么都不做 1: 绘制 2: 擦除

cvs.onmousedown = function(e){
    if(e.button == 0) 
        state = 1;
    else if (e.button == 2)
        state = 2;
}

cvs.onmouseup = function (){
    // 重置状态
    state = 0;
    lastX = lastY = undefined; 
}

cvs.onmousemove = function(e) {
    if (state === 1) {
        paint(e);
    } else if (state === 2){
        eraser(e);
    }
}

// 擦除
function eraser(e){
    var w = 50;
    var h = 50;
    var x = e.offsetX - w/2
    var y = e.offsetY - h/2;
    ctx.clearRect(x, y , w, h);
}

设置样式

ctx.lineWidth = 7;
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctx.strokeStyle = "royalblue";

完整代码

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <script type="text/javascript">
            window.onload = function() {
                var cvs = document.getElementById("cvs");
                var ctx = cvs.getContext("2d");

                // 上次画线时的结束点坐标
                var lastX;
                var lastY;
                var state = 0; // 0: 什么都不做 1: 绘制 2: 擦除

                ctx.lineWidth = 7;
                ctx.lineCap = "round";
                ctx.lineJoin = "round";
                ctx.strokeStyle = "royalblue";

                cvs.onmousedown = function(e){
                    console.log(e.button);
                    if(e.button == 0) 
                        state = 1;
                    else if (e.button == 2)
                        state = 2;
                }

                cvs.onmouseup = function (){
                    // 重置状态
                    state = 0;
                    lastX = lastY = undefined; 
                }

                cvs.onmousemove = function(e) {
                    if (state === 1) {
                        paint(e);
                    } else if (state === 2){
                        eraser(e);
                    }
                }

                // 绘制
                function paint(e){ // e是鼠标事件参数
                    // 第一次绘制时初始化lastX,lastY的值
                    if(lastX === undefined) {
                        lastX = e.offsetX;
                        lastY = e.offsetY;
                        return;
                    }

                    // 绘制线段
                    ctx.beginPath();
                    ctx.moveTo(lastX, lastY);
                    ctx.lineTo(e.offsetX, e.offsetY);
                    ctx.stroke();

                    // 记录上次的结束点
                    lastX = e.offsetX;
                    lastY = e.offsetY;
                }

                // 擦除
                function eraser(e){
                    var w = 50;
                    var h = 50;
                    var x = e.offsetX - w/2
                    var y = e.offsetY - h/2;
                    ctx.clearRect(x, y , w, h);
                }
            }
        </script>
    </head>

    <body>
        <canvas id="cvs" width="500" height="500"></canvas>
    </body>

</html>

results matching ""

    No results matching ""