JavaScript 实践-做画板

506 阅读3分钟

使用JS制作画板,实现了画线功能

使用id定义的标签

在css里用 #号选择器

鼠标点击事件(鼠标点击时,调用鼠标点击的坐标)

canvas.onclick =(e)=> {       
    console.log(e.clientX)
    console.log(e.clientY)
    }
想确定鼠标点击事件点在哪里,可以使用特殊位置,例如左上角0,0

使用console.log(e.clientX)
    console.log(e.clientY)
可以调用鼠标点击位置

创建一个div,在鼠标点击时

let div = document.createElement('div');
让文档创建一个元素/标签 div

div.style.position = 'absolute';
让div的内联样式里面的position的值是absolute

css的样式语句可以直接写在html里

div.style.left = e.clientX + 'px';
div.style.top = e.clientY + 'px';
div.style.width = '6px';
div.style.height = '6px';
div.style.marginLeft = '-3px';           div的左边距减少3px
div.style.marginTop = '-3px';            div的上边距减少3px
div.style.borderRadius = '50%';          div变圆
div.style.backgroundColor = 'black';

调用div,div默认存放在内存中,不直接显示

canvas.appendChild(div);
在页面中添加div

第一部分整体思路

使用div画线,通过console.log 得到鼠标的位置
然后创建一个div,在上面加css样式
然后把div放到canvas.appendChild(div),调用这个div

让鼠标移动时的事件

onmousemove(鼠标移动)
onclick(点击鼠标)

canvas

默认是内联元素
用display:block;变成块级元素

100vw  和屏幕一样宽
100vh  和屏幕一样高

通过id找到获取canvas

let canvas = document.getElementById('canvas')      

fillstyle 填充样式

fillRext   填充矩形

ctx.linewidth = 10;    
canvas画的线宽是10

ctx.linecap='round';  (line线)(cap覆盖,尾部)(round圆形);线的尾部是圆的,不存在毛边

ctx.strokestyle='none';   stroke
描边样式无

canvas可以在声明时直接写宽高

<canvas id='canvas' width="100" height="100"></canvas>

canvas不支持在css里写跟屏幕一样的宽高,会拉伸里面的元素,变模糊

需要一开始把canvas写成跟屏幕一样宽高,使用JS可以获取屏幕的宽高

let canvas = document.getElementById('canvas');       
通过id找到/获取这个canvas         

canvas.width = document.documentElement.clientWidth;         
canvas.height = document.documentElement.clientHeight;         
把canvas的宽高变成屏幕的宽高

canvas.width 是html的宽
不能使用css的style.width的宽

让鼠标停止

给鼠标一个指示信息,让它看见信号就开始和暂停

使用if语句,用来监听鼠标的按下和松开事件

let painting = false;
let last; 
canvas.onmousedown = (e) => {            
painting = true;             
last = [e.clientX, e.clientY]         
}         

当鼠标按下的时候,painting的值是true,用painting监听事件

canvas.onmousemove =(e)=> {
    if (painting === true) {
        drawLine(last[0], last[1], e.clientX, e.clientY)
        last = [e.clientX, e.clientY]
        //last等于新的x,y
        } else {
        }
    }
    canvas.onmouseup = () => {
        painting = false
    }

canvas.onmousedown = () =>{}
鼠标   按下来
canvas.onmouseup = () => {}
鼠标    放开

canvas.onmousemove = (e) => {}

e是怎么来的

浏览器会调用canvas.onmousemove(事件相关信息),然后把事件相关信息回传给你
e可以随便起名,叫啥都行,是浏览器回传给你的信息

适配手机

手机没有鼠标,触摸屏touch事件

检测手机是否支持触摸屏

var isTouchDevice = 'ontouchstart' in document.documentElement;
检验ontouchstart是否在document上
如果document上有ontouchstart这个事件,就是支持触屏的

画线速度太快,会断点,使用在2点之间用线连接

function drawLine(x1, y1, x2, y2){
    ctx.beginPath();
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.stroke();
    }
    
 这个函数的意思是,我收取4个参数,你传4个参数给我,然后我调用这4个参数
 用这个参数画线

使用变量,来记忆上一次发生了什么

声明一个变量last(上次),上次要从第二次开始,第一次没有上一次

let last
canvas.onmousedown = (e) => {
    painting = true;
    last = [e.clientX, e.clientY]
    }
当鼠标按下的时候,painting的值是true,用painting监听事件

canvas.onmousemove = (e) => {
if (painting === true) {
drawLine(last[0], last[1], e.clientX, e.clientY)
last = [e.clientX, e.clientY]      //last等于新的x,y
} else {
}
}
canvas.onmouseup = () => {
painting = false
}

整体思路

在最外面声明一个变量 last
当鼠标按下时,把这个点作为上一次的点
在移动的时候,连接这一次和上一次的点
同时,更新上一次的点

练习代码(阶段性):

div 画线

canvas 画线

适配手机