[JavaScript]创建一个canvas画板-小结(2)

项目链接:GitHub

项目预览:Github Pages

项目描述:通过MDN提供的教程和API,创建一个拥有基本功能(包括绘画,橡皮擦,保存等)的canvas画板。

承接上一小结

目前我们的canvas画板是可以在浏览器上使用的,但是如果我们的项目如果想要在手机端或者其他可以使用触屏功能的设备上使用,则需要进行一些额外的工作。

画板适配移动端

添加viewport

在HTML的head中添加meta :

来自MDN的解释:

width属性控制视口的宽度。可以像width=600这样设为确切的像素数,或者设为device-width这一特殊值来指代比例为100%时屏幕宽度的CSS像素数值。(相应有height及device-height属性,可能对包含基于视口高度调整大小及位置的元素的页面有用。)
initial-scale属性控制页面最初加载时的缩放等级。maximum-scale、minimum-scale及user-scalable属性控制允许用户以怎样的方式放大或缩小页面。

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

增加touch监听事件

在浏览器中,我们使用canvas需要监听的是鼠标mouse的事件,但是在手机端或者拥有触屏功能的设备上,mouse事件是无效的,我们需要监听touch事件。

首先我们先整理一下思路,我们需要做的是一个特性检测:如果用户使用的设备支持触屏功能,那么我们可以监听touch事件;反之,我们则监听mouse事件。

又因为触屏设备的坐标获取和浏览器不一样,所以我们还应该使用开发者工具提供的API,另外获取触屏设备的坐标。

那我们之前的listenToUser()函数可以改写为这样:

function listenToUser(canvas, ctx) {
    // 确定用户点击的此刻坐标
    var lastPoint = { x: undefined, y: undefined }

    // 画圆
    function drawCir(x, y, radius) {
        ctx.beginPath()
        ctx.arc(x, y, radius, 0, 360)
        ctx.fill()
    }

    // 画线
    function drawLine(x1, y1, x2, y2, ) {
        ctx.beginPath()
        ctx.moveTo(x1, y1)
        ctx.lineWidth = lineWidth
        ctx.lineTo(x2, y2)
        ctx.stroke()
        ctx.closePath()
    }

    // 特性检测
    if (document.body.ontouchstart !== undefined){
        // 如果设备支持触屏
        canvas.ontouchstart = function(keyWord) {
            
            //获取触屏设备坐标
            var x = keyWord.touches[0].clientX;
            var y = keyWord.touches[0].clientY;
            
            if (eraserEnabled) {
                using = true
                ctx.clearRect(x, y, 10, 10)
            } else {
                // 确定此刻用户所点击的坐标,以配合下一个点的坐标
                using = true;
                lastPoint = { x: x, y: y }
            }
        }
        canvas.ontouchmove = function(keyWord) {
            
            var x = keyWord.touches[0].clientX;
            var y = keyWord.touches[0].clientY;
    
            if (eraserEnabled) {
                if (using) {
                    ctx.clearRect(x, y, 10, 10)
                }
            } else {
                if (using) {
                    var newPoint = { x: x, y: y }
                    drawLine(lastPoint.x, lastPoint.y, newPoint.x, newPoint.y)
                    //这句话很重要
                    lastPoint = newPoint
                }
            }
        }
        canvas.ontouchend = function(keyWord) {
            using = false
        }
    } else {
        // 如果设备不支持触屏
        canvas.onmousedown = function (keyWord) {
            var x = keyWord.clientX;
            var y = keyWord.clientY;
            if (eraserEnabled) {
                using = true
                ctx.clearRect(x, y, 10, 10)
            } else {
                // 确定此刻用户所点击的坐标,以配合下一个点的坐标
                using = true;
                lastPoint = { x: x, y: y }
            }
        }
        canvas.onmousemove = function (keyWord) {
    
            var x = keyWord.clientX;
            var y = keyWord.clientY;
    
            if (eraserEnabled) {
                if (using) {
                    ctx.clearRect(x, y, 10, 10)
                }
            } else {
                if (using) {
                    var newPoint = { x: x, y: y }
                    drawLine(lastPoint.x, lastPoint.y, newPoint.x, newPoint.y)
                    //这句话很重要
                    lastPoint = newPoint
                }
            }
        }
        canvas.onmouseup = function (keyWord) {
            using = false
        }
    }
}

关于移动端的设配就完成了。

添加画笔颜色

添加功能:默认画笔是黑色,用户可以根据自己的需要,选择画笔的颜色。

在index.html中添加:

<ol class="pickColor">
    <li id="black" class="active"></li>
    <li id="red" ></li>
    <li id="yellow"></li>
    <li id="blue"></li>
</ol>

用户点击了某一种画笔颜色,我们就为这个画笔添加一个class active,去除同级元素的active,同时吧画笔的颜色设置为选择画笔颜色:

css中添加:

.pickColor li.active {
    box-shadow: 0 0 3px rgba(0, 0, 0, 0.95);
    transform: scale(1.1);
}

main.js中添加:

black.onclick = function(keyWord){
    ctx.strokeStyle = "black"
    black.classList.add("active")
    red.classList.remove("active")
    yellow.classList.remove("active")
    blue.classList.remove("active")
}
red.onclick = function(keyWord){
    ctx.strokeStyle = "red"
    red.classList.add("active")
    yellow.classList.remove("active")
    black.classList.remove("active")
    blue.classList.remove("active")
}
yellow.onclick = function(keyWord){
    ctx.strokeStyle = "yellow"
    yellow.classList.add("active")
    red.classList.remove("active")
    black.classList.remove("active")
    blue.classList.remove("active")
}
blue.onclick = function(keyWord){
    ctx.strokeStyle = "blue"
    blue.classList.add("active")
    yellow.classList.remove("active")
    black.classList.remove("active")
    red.classList.remove("active")
}

PS:代码有点臃肿,不好看,写完博客我会优化一下。

可选画笔粗细

选择画笔粗细也是和选择画笔颜色一个套路:划分画笔粗细分别赋予一个id并设置class,每当点击某个画笔选择的同时,就触发点击事件,执行函数,设置画笔粗细:

<ol class="penSize">
    <li id="thin" class="thin"></li>
    <li id="thick" class="thick"></li>
</ol>
thin.onclick = function() {
    lineWidth = 5
}
thick.onclick = function() {
    lineWidth = 10
}

清除画板

google关键词搜索: JavaScript canvas clear,我们根据Stack Overflow上的回答了解清除canvas画板的方案了:

<!-- 这里使用了iconfont的symbol,不了解的朋友也可以直接用一个button然后设置id使用 -->
<svg  id="clear" class="icon">
    <use xlink:href="#icon-clear1"></use>
</svg>
clear.onclick = function() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
}

只要点击一下就可以一键清除画板了~

保存画板

好不容易画好了一幅画,想要保存下来分享给朋友?google关键词搜索: JavaScript canvas save as image,使用现有的保存方案:

<svg  id="download" class="icon">
    <use xlink:href="#icon-save1"></use>
</svg>

js:

download.onclick = function() {
    var url = canvas.toDataURL("img/png")
    var a = document.createElement("a")
    document.body.appendChild(a)
    a.href = url
    a.download = 'My images'
    a.target = "_blank"
    a.click()
}

这样,我们的canvas经过了选择画笔颜色,选择画笔粗细,绘画,橡皮擦,清除,保存等一系列步骤,终于可以完成一幅画了。

文中罗列的只是关键的步骤,详细代码我已上传到了自己的GitHub,有兴趣的朋友可以来我的GitHub做客~。

原文地址:https://www.cnblogs.com/No-harm/p/9493854.html