canvas实现的画图板

Posted nicola-moon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了canvas实现的画图板相关的知识,希望对你有一定的参考价值。

起初

前些天开始补全html中还遗漏的知识点,想起来了canvas这个HTML5的新特性。感觉还是蛮有趣的,再加上想要通过这个练下JS,于是自己搞了个简易版的画图工具。

(本来是贴在CodePen上的,可是不知道为什么这两天Codepen打不开了……不会给墙了吧……)

实现功能

主要实现的功能大概就是下图这样啦,顺便画个蓝胖子祭天:

技术分享图片技术分享图片

代码

还是贴下代码吧,HTML部分里,样式就不贴了,稍微搞了下,主要也就是一个canvas:

<canvas>您的浏览器不支持画布!</canvas>
        <div id="toolbar">
            <h2>工具栏</h2>
            画笔颜色:<input id="penColor" type="color" /><br />
            背景颜色:<input id="bgColor" type="color" value="#FFE4E1"/><br />
            线条/橡皮 粗细:<br />
            <input id="lineWeight" type="range" value="1" min="0.5" max="10" step="0.1"/><br />
            画笔虚化:<br />
            <input id="blurRange" type="range" value="0" min="0" max="10" step="1" /><br />
            <input id="penButton" class="iButton" type="button" value="画笔"  /><br />
            <input id="lineButton" class="iButton" type="button" value="直线" /><br />
            <input id="rectButton" class="iButton" type="button" value="矩形" /><br />
            <input id="circleButton" class="iButton" type="button" value="正圆"/><br />
            <input id="eraserButton" class="iButton" type="button" value="橡皮" /><br />
            <input id="allclearButton" class="iButton" type="button" value="清空" /><br />
            
            <div id="rectDiv">
                矩形样式:<br />
                <button id="strokeRect"></button>
                <button id="fillRect"></button>
            </div>
            
            <div id="circleDiv">
                正圆样式:<br />
                <button id="strokeCircle"></button>
                <button id="fillCircle"></button>
            </div>
        </div>

这些也就是声明个元素,其实大头还是在JS上,不过确实也不是很麻烦,用一些基础语法也就搞定了:

            var can=document.getElementsByTagName("canvas");
            var cas=can[0].getContext("2d");
            var isSameMove=false;//轨迹结束判断
            function rectXY(){this.x1=0,this.y1=0,this.x2=0,this.y2=0};//矩形对象
            function lineXY(){this.x1=0,this.y1=0,this.x2=0,this.y2=0};//直线对象
            function circleXY(){this.x1=0,this.y1=0,this.x2=0,this.y2=0};//圆对象
            //重绘画布大小
            function resize(){
                can[0].height=window.innerHeight;
                can[0].width=window.innerWidth;
            }
            resize();
            //改变画笔颜色函数
            var penColor=document.getElementById("penColor");
            penColor.onchange=function(){
                penColor.click();
                cas.strokeStyle=this.value;
                cas.shadowColor=this.value;
            }
            //改变背景颜色函数
            var bgColor=document.getElementById("bgColor");
            bgColor.onchange=function(){
                bgColor.click();
                document.body.style.backgroundColor=this.value;
            }
            //改变线条粗细
            var lineWeight=document.getElementById("lineWeight");
            lineWeight.onchange=function(){
                cas.lineWidth=this.value;
            }
            //改变画笔虚化值
            var blurRange=document.getElementById("blurRange");
            blurRange.onchange=function(){
                cas.shadowColor=penColor.value;
                cas.shadowBlur=this.value;
            }
            //按钮事件判定
            var valueButton="pen";//按钮判断
            var buttons=document.getElementsByClassName("iButton");
            var penButton=document.getElementById("penButton");
            var lineButton=document.getElementById("lineButton");
            var rectButton=document.getElementById("rectButton");
            var circleButton=document.getElementById("circleButton");
            var eraserButton=document.getElementById("eraserButton");
            var allclearButton=document.getElementById("allclearButton");
            //矩形子按钮
            var rectStyle="stroke";//子按钮判断
            var rectDiv=document.getElementById("rectDiv");
            var strokeRectButton=document.getElementById("strokeRect");
            var fillRectButton=document.getElementById("fillRect");
            //正圆子按钮
            var circleStyle="stroke";//子按钮判断
            var circleDiv=document.getElementById("circleDiv");
            var strokeCircleButton=document.getElementById("strokeCircle");
            var fillCircleButton=document.getElementById("fillCircle");
            
            //点击画笔按钮
            penButton.onclick=function(){
                valueButton="pen";
                for(var i=0;i<buttons.length;i++){
                    buttons[i].style.backgroundColor="ghostwhite";
                }
                cas.globalCompositeOperation="source-over";
                rectDiv.style.display="none";
                circleDiv.style.display="none";
                penButton.style.backgroundColor="#FA8072";
            }
            //点击线按钮
            lineButton.onclick=function(){
                valueButton="line";
                for(var i=0;i<buttons.length;i++){
                    buttons[i].style.backgroundColor="ghostwhite";
                }
                cas.globalCompositeOperation="source-over";
                rectDiv.style.display="none";
                circleDiv.style.display="none";
                lineButton.style.backgroundColor="#FA8072";
            }
            //点击矩形按钮
            rectButton.onclick=function(){
                valueButton="rect";
                for(var i=0;i<buttons.length;i++){
                    buttons[i].style.backgroundColor="ghostwhite";
                }
                cas.globalCompositeOperation="source-over";
                circleDiv.style.display="none";
                rectButton.style.backgroundColor="#FA8072";
                rectDiv.style.display="block";
                rectStyle="stroke";
                strokeRectButton.style.boxShadow="0 0 5px black";
            }
            //点击矩形子按钮:空心矩形
            strokeRectButton.onclick=function(){
                rectStyle="stroke";
                fillRectButton.style.boxShadow="none";
                strokeRectButton.style.boxShadow="0 0 5px black";
            }
            //点击矩形子按钮:实心矩形
            fillRectButton.onclick=function(){
                rectStyle="fill";
                strokeRectButton.style.boxShadow="none";
                fillRectButton.style.boxShadow="0 0 5px black";
            }
            //点击圆按钮
            circleButton.onclick=function(){
                valueButton="circle";
                for(var i=0;i<buttons.length;i++){
                    buttons[i].style.backgroundColor="ghostwhite";
                }
                cas.globalCompositeOperation="source-over";
                rectDiv.style.display="none";
                circleButton.style.backgroundColor="#FA8072";
                circleDiv.style.display="block";
                circleStyle="stroke";
                strokeCircleButton.style.boxShadow="0 0 5px black";
            }
            //点击正圆子按钮:空心正圆
            strokeCircleButton.onclick=function(){
                circleStyle="stroke";
                fillCircleButton.style.boxShadow="none";
                strokeCircleButton.style.boxShadow="0 0 5px black";
            }
            //点击正圆子按钮:实心正圆
            fillCircleButton.onclick=function(){
                circleStyle="fill";
                strokeCircleButton.style.boxShadow="none";
                fillCircleButton.style.boxShadow="0 0 5px black";
            }
            //点击橡皮擦按钮
            eraserButton.onclick=function(){
                valueButton="eraser";
                for(var i=0;i<buttons.length;i++){
                    buttons[i].style.backgroundColor="ghostwhite";
                }
                eraserButton.style.backgroundColor="#FA8072";
                rectDiv.style.display="none";
                circleDiv.style.display="none";
                cas.globalCompositeOperation="destination-out";
            }
            //点击清除按钮
            allclearButton.onclick=function(){
                for(var i=0;i<buttons.length;i++){
                    buttons[i].style.backgroundColor="ghostwhite";
                }
                cas.globalCompositeOperation="source-over";
                rectDiv.style.display="none";
                circleDiv.style.display="none";
                penButton.style.backgroundColor="#FA8072";
                valueButton="pen";
                resize();
                cas.lineWidth=lineWeight.value;
                cas.strokeStyle=penColor.value;
                cas.shadowColor=penColor.value;
                cas.shadowBlur=blurRange.value;
            }
            //求鼠标坐标函数
            function windowToCanvas(canvas, x, y){
                var rect=canvas.getBoundingClientRect();
                return {
                    x: x - rect.left * (canvas.width/rect.width),
                    y: y - rect.top * (canvas.height/rect.height)
                };
            }
            //绘制图形函数
            can[0].onmousedown=function(e){
                /*
                //在点击处生成方块
                var color=["blue","red","black"];
                var e=event||window.event;
                var x=e.clientX;
                var y=e.clientY;
                var index=parseInt(Math.random()*3);
                cas.fillStyle=color[index];
                cas.fillRect(x,y,10,10);
                */
                //绘制轨迹
                if(valueButton=="pen"){
                    isSameMove=true;
                    var ele=windowToCanvas(can[0],e.clientX,e.clientY);
                    cas.beginPath();
                    cas.moveTo(ele.x,ele.y);
                    can[0].onmousemove=function(e){
                        if(isSameMove){
                            var ele=windowToCanvas(can[0],e.clientX,e.clientY);
                            cas.lineTo(ele.x,ele.y);
                            cas.stroke();
                            cas.save();
                        }
                    }
                }
                //绘制线
                if(valueButton=="line"){
                    var ele=windowToCanvas(can[0],e.clientX,e.clientY);
                    lineXY.x1=ele.x;
                    lineXY.y1=ele.y;
                }
                //绘制矩形
                if(valueButton=="rect"){
                    var ele=windowToCanvas(can[0],e.clientX,e.clientY);
                    rectXY.x1=ele.x;
                    rectXY.y1=ele.y;
                }
                //绘制圆
                if(valueButton=="circle"){
                    var ele=windowToCanvas(can[0],e.clientX,e.clientY);
                    circleXY.x1=ele.x;
                    circleXY.y1=ele.y;
                }
                //应用橡皮擦
                if(valueButton=="eraser"){
                    isSameMove=true;
                    var ele=windowToCanvas(can[0],e.clientX,e.clientY);
                    cas.beginPath();
                    cas.moveTo(ele.x,ele.y);
                    can[0].onmousemove=function(e){
                        if(isSameMove){
                            var ele=windowToCanvas(can[0],e.clientX,e.clientY);
                            cas.lineTo(ele.x,ele.y);
                            cas.stroke();
                            cas.save();
                        }
                    }    
                }
            }
            can[0].onmouseup=function(e){
                //画笔
                if(valueButton=="pen"){
                    isSameMove=false;
                }
                //直线
                if(valueButton=="line"){
                    var ele=windowToCanvas(can[0],e.clientX,e.clientY);
                    lineXY.x2=ele.x;
                    lineXY.y2=ele.y;
                    cas.beginPath();
                    cas.moveTo(lineXY.x1,lineXY.y1);
                    cas.lineTo(lineXY.x2,lineXY.y2);
                    cas.stroke();
                }
                //矩形
                if(valueButton=="rect"){
                    var ele=windowToCanvas(can[0],e.clientX,e.clientY);
                    rectXY.x2=ele.x;
                    rectXY.y2=ele.y;
                    if(rectStyle=="stroke"){
                        cas.strokeRect(rectXY.x1,rectXY.y1,rectXY.x2-rectXY.x1,rectXY.y2-rectXY.y1);
                    }
                    if(rectStyle=="fill"){
                        cas.fillStyle=penColor.value;
                        cas.fillRect(rectXY.x1,rectXY.y1,rectXY.x2-rectXY.x1,rectXY.y2-rectXY.y1);
                    }
                }
                //正圆
                if(valueButton=="circle"){
                    var ele=windowToCanvas(can[0],e.clientX,e.clientY);
                    circleXY.x2=ele.x;
                    circleXY.y2=ele.y;
                    cas.beginPath();
                    var cx=(circleXY.x1+circleXY.x2)/2;
                    var cy=(circleXY.y1+circleXY.y2)/2;
                    var r=Math.abs((circleXY.x1-circleXY.x2)/2);
                    cas.arc(cx,cy,r,0,Math.PI*2,true);
                    if(circleStyle=="fill"){
                        cas.fillStyle=penColor.value;
                        cas.fill();
                    }
                    cas.stroke();
                }
                //橡皮
                if(valueButton=="eraser"){
                    isSameMove=false;
                }
            }

后续

本来到后面还是想要实现下PS中那种图层功能来着,设想是通过新建图层按钮绑定创建新的canvas元素事件,让多个canvas覆盖整个窗口,然后通过给每个canvas添加display:flxed样式,按照图层顺序给它们的z-index赋值,达到图层叠加效果,其他一些图层操作也可以取巧实现。

可惜……理想是丰满的……搞了一个下午,脑子眼儿都疼了,但是遇到了一个坎儿,就是,新创建的canvas元素,无法和左侧工具栏内的按钮进行绑定,毕竟工具栏按钮的功能实现都是建立在最初canvas的基础上,试了一些方法,也没有完成,就只能搁置了……

果然还是要再多学习一下JS,还是基础有些薄弱啊。

以上是关于canvas实现的画图板的主要内容,如果未能解决你的问题,请参考以下文章

如何在canvas 画图加文字

JAVA实现简单的画图板

canvas实现矩形画图效果

canvas实现矩形画图效果

JAVA 画图板实现(基本画图功能+界面UI)界面实现

如何在UWP用C#实现HTML5中canvas各种画图操作