使用canvas写的黑板

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<title>无标题文档</title>
<style>
    *{
        margin: 0;
        padding: 0;
    }
    canvas{
        display: block;
        margin: 15px auto;
    }
	.flex{
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        justify-content: space-around;
        width: 500px;
        margin: 0 auto;
    }
    .flex li{
        padding: 3px 10px;
        background-color:cadetblue;
        color: #ffffff;
        margin: 5px 10px;
    }
    #pp{
        /* display: none; */
    }
</style>
</head>
<body>
<div>
    
</div>
<canvas width="500" height="300"  id="myCanvas" style="border:1px solid #000000;"></canvas>
<ul class="flex">
    <li onclick="cuxi()">
        加粗
        <input type="range" id="ran" value="5">
    </li>
    <li>
        <input onchange="color()" type="color" id="clor">
    </li>
    <li onclick="miao()">描边</li>
    <li onclick="cl()">清空</li>
    <li onclick="sh()">上一步</li>
    <li onclick="xiangpi()">橡皮</li>
    <li onclick="bao()">转成图片</li>
    <li onclick="down()">下载</li>
    <li onclick="yuan()">画圆</li>
    <li onclick="wujiao()">五角</li>
    <li onclick="miaobian()">描边</li>
</ul>
<img src="" id="pp">

<img src="https://img-blog.csdnimg.cn/2022010708251664031.png">
</body>
<script>
        var obj = document.getElementById("myCanvas");
        var ctx=obj.getContext("2d");
        var wid1 = parseInt(getComputedStyle(obj)['width']),
            heig1 = parseInt(getComputedStyle(obj)['height']);
        var maxX =wid1;//X轴可移动最大距离
        var maxY = heig1;//Y轴可移动最大距离
        var kai = {};//画笔开始坐标
        var lujing = [];//路径数组
        var shang = [];//撤销记录
        var yanse = document.getElementById("clor")//画笔颜色
        var ran = document.getElementById("ran")//笔触粗细
        var imgss = document.getElementById("pp");//转成图片
        var moveX;//鼠标x轴距离
        var moveX;//鼠标y轴距离
        var isyuan=0;//0 普通画线  1 以圆画线
    function drap(obj) {
        obj.addEventListener('mousedown', start);
 
        function start(event) {
            // 鼠标左键
            if (event.button == 0) {
                // getComputedStyle(obj)['margin-left'] return XXpx需要转成整型
                // 如果有obj有margin值而不加这个数组拖拽会出现位置偏移
                offsetX = event.pageX - obj.offsetLeft ;
                offsetY = event.pageY - obj.offsetTop;
                // 绑定事件,同样unbind解绑定,此效果的实现最后必须要解绑定,否则鼠标松开后拖拽效果依然存在
                //movemove事件必须绑定到$(document)上,鼠标移动是在整个屏幕上的
                document.addEventListener('mousemove', move);
                //此处的$(document)可以改为obj
                document.addEventListener('mouseup', stop);
                kai.x = offsetX;
                kai.y = offsetY;
                isyuan==0? xian():(isyuan==1?yuan(kai.x,kai.y):wujiao(kai.x,kai.y));
            }
            return false;//阻止默认事件或冒泡
        }
 
        function move(event) {
            moveX = (event.pageX - obj.offsetLeft)
            moveY = (event.pageY - obj.offsetTop)
            //范围限定  最小时取最大  最大时取最小
            if(moveX < 0) {
                moveX=0
            }else if(moveX>maxX){
                moveX=maxX;
            }
            if(moveY < 0) {
                moveY=0;
            }else if(moveY>maxY){
                moveY=maxY; 
            }
            let ff = {
                x:moveX,
                y:moveY
            }
            lujing.push(ff);
            isyuan==0? xian():(isyuan==1?yuan(moveX,moveY):wujiao(moveX,moveY));
            return false;//阻止默认事件或冒泡
        }
 
        function stop(envet) {
            lujing = [];
            img();
            document.removeEventListener('mousemove', move);
            document.removeEventListener('mouseup', stop);
            return false;//阻止默认事件或冒泡
        }
    };
//    鼠标滑动
    drap(obj);

    // 画线开始
    function xian(){
        ctx.beginPath();
        ctx.moveTo(kai.x,kai.y);
        for(let i in lujing){
            ctx.lineTo(lujing[i].x,lujing[i].y);
        }
       
        ctx.stroke();
       
    };
    function cuxi(){
        ctx.beginPath();
        ctx.lineWidth=ran.value;
    };
    function miao(){

    };
    function xiangpi(){
        ctx.beginPath();
        ctx.lineWidth=30;
        ctx.strokeStyle="#FFFFFF";
        ctx.moveTo(kai.x,kai.y);
        for(let i in lujing){
            ctx.lineTo(lujing[i].x,lujing[i].y);
        }
    };
    function cl(){
        ctx.clearRect(0, 0, wid1, heig1);
        shang=[];
    };
    // var imgss = document.getElementById("pp");
    function img(){
        // var image = new Image();
	    // image.src = obj.toDataURL("image/png");
        // image.className = 'ims'+shang.length;
       // shang.push(obj.toDataURL("image/png"))
        // imgss.src =  shang[shang.length-1];思路是转化吧画布转成图片路径有缺陷
        //新方法是拷贝画布的颜色数据到数组
        
        shang.push(ctx.getImageData(0, 0, wid1, heig1))
    }
    function sh(){
        if(shang.length>1){
            shang.pop();
            // console.log(shang)
            // imgss.src =  shang[shang.length-1];
            // obj.width = imgss.width;
            // obj.height =  imgss.height;
            // ctx.clearRect(0, 0, wid1, heig1);
            // let canvasPic = new Image();
            // canvasPic.src =  shang[shang.length-1];
            // ctx.drawImage(canvasPic,0,0);
            ctx.putImageData(shang[shang.length-1], 0, 0)
           
        }else{
            cl();
            shang=[];
        } 
    };
    function bao(){
       
        // var image = new Image();
        // image.src = obj.toDataURL("image/png");生成一张图片
        imgss.src = obj.toDataURL("image/png");
    };
    function color(){
        var val =yanse.value;
        ctx.strokeStyle=val;
    }
    function down(){
        bao();
        let name = prompt('请输入要保存的图片名称', 'canvas绘制图片');
        var a = document.createElement('a');          // 创建一个a节点插入的document
        var event = new MouseEvent('click')           // 模拟鼠标click点击事件
        a.download = name                 // 设置a节点的download属性值
        a.href =  imgss.src;                                 // 将图片的src赋值给a节点的href
        a.dispatchEvent(event)                        // 触发鼠标点击事件
    }

    // 画空心的
    function miaobian(x,y){
        ctx.beginPath();
        ctx.lineWidth=ran.value>5?ran.value:5;
        ctx.arc(x,y,ran.value/2,0,2*Math.PI);
        ctx.fill();
        ctx.stroke();
        ctx.closePath();
    }
    // 画圆

    function yuan(x,y){
        isyuan = 1;
        ctx.beginPath();
        ctx.lineWidth=ran.value>5?ran.value:5;
        ctx.arc(x,y,ran.value/2,0,2*Math.PI);
        ctx.fill();
        ctx.stroke();
        ctx.closePath();
       
    }
    function wujiao(x,y){
        isyuan = 2;
        let  radius = parseInt(ran.value)
        let inRadius = radius / 2
        let perAngle = 2 * Math.PI / 5
        ctx.beginPath();
        ctx.lineWidth=ran.value>5?ran.value:5;
        for (let i = 0; i <= 5; i++) {
            ctx.lineTo(x + Math.sin(i * perAngle) * radius, y - Math.cos(i * perAngle) * radius)
            ctx.lineTo(x + Math.sin(i * perAngle + perAngle / 2) * inRadius, y - Math.cos(i * perAngle + perAngle / 2) * inRadius)
        }
        ctx.stroke()
        ctx.closePath;
    }
</script>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值