canvas實現的畫圖板


起初

前些天開始補全HTML中還遺漏的知識點,想起來了canvas這個HTML5的新特性。感覺還是蠻有趣的,再加上想要通過這個練下JS,於是自己搞了個簡易版的畫圖工具。

實現功能

(代碼和效果貼在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,還是基礎有些薄弱啊。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM