H5網頁塗鴉canvas


最近做了個播放頁面,標題和一個iframe;需要對這個iframe可以進行網頁塗鴉。
網頁塗鴉肯定是canvas了。網上找了個差不多的,實驗下來問題很多,干脆自己一步步修改,學習。

效果:

 


本項目沒有引入其他的任何工具庫,復制代碼可以直接運行,下面貼出代碼:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>小小英語-閱讀</title>
        <meta name="viewport" content="width=device-width,height=device-height,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <meta name="apple-mobile-web-app-status-bar-style" content="black">
        <meta name="format-detection" content="telephone=no">
        <meta name="description" content="數千冊優質分級閱讀繪本">
        <style>
            *{
                padding:0;margin:0;
            }
            li{
                list-style-type:none;
            }
            html,body{
                height:100%;
             }
            .content-page{
                min-width:1500px;
                min-height: 100%;
                background:#f6f6f6;
            }
            #page{
                position:relative;
                width:1200px;
                margin:0 auto;
                border-top:1px solid rgba(0,0,0,0)
            }
            h3{
                position: relative;
                margin:40px 0;
                color:#ff8e5d; 
                font-size:30px;
                text-align:center;
            }
            .back{
                position:absolute;
                left:0;
                top:50%;
                transform:translate(0,-50%);
                font-family:PingFang-SC-Regular;
                font-size:20px;
                padding-left:20px;
                background:url('../assets/images/icon_back-red.png') no-repeat;
                background-size:20px 20px;
            }
            #content-iframe{
                width:100%;
                background: #ccc;
                min-height: 800px;
                border:none;

            }
            #canvas{
                position:absolute;
                left:0;
                top:0;
                z-index:100;
                cursor:default;
                top:120px;
                left:50%;
                transform:translate(-50%,0);
                display: none;/*canvas剛進來是隱藏的,需要選顏色激活*/
            }
            .right-bar{
                width:100px;
                position: absolute;
                right:-120px;
                top:120px;
                color:#000;
                z-index:1;
            }
            .word{
                font-size:24px;
                font-family:FredokaOne-Regular;
                color:rgba(255,142,93,1);
                text-align:center;
            }
            .right-bar>span{
                display: block;
                width:90px;
                height:40px;
                color:#fff;
                font-size:16px;
                padding:0;
                line-height: 40px;
                border:none;
                background: #FF8E5D;
                margin:18px auto;
                text-align: center;
                cursor: pointer;
            }
            .btn-active{background:#ED723D !important}
            #color{
                padding-left:8px;
                margin-top:10px;
            }
             #color>i{
                position:relative;
                display:inline-block;
                width:34px;
                height:34px;
                border-radius: 50%;
                margin-right:8px;
                margin-bottom:5px;
                border:none;
                cursor: pointer;
                z-index:50;
            }
            .color-active{
                position:absolute;
                top:50%;
                left:50%;
                transform:translate(-50%,-50%);
                
                display: block;
                border: 1px solid #FF8E5D;
                border-radius: 50%;
                width:40px;
                height:40px;
                z-index:40;
                display: none;
            }
            .i1{
                background:#DF4BFF;
            }
            .i2{
                background:#9CCB68;
            }
            .i3{
                background:#3DC1FF;
            }
            .i4{
                background:#FFD338;
            }
            .i5{
                background:#FF6262;
            }
            .i6{
                background: #000000;
            }
        </style>
    </head>
    <body>
    <div class="content-page">
        <div id="page">
            <h3>
                標題
                <p class="back" @click="goBack()">
                    返回上一級
                </p>
            </h3>
            <iframe id="content-iframe" :src="iframeUrl">
                
            </iframe>
            <div class="right-bar">
                        <div class="word">color</div>
                        <div id="color">
                            <i class="i1"><span class="color-active"></span></i>
                            <i class="i2"><span class="color-active"></span></i>
                            <i class="i3"><span class="color-active"></span></i>
                            <i class="i4"><span class="color-active"></span></i>
                            <i class="i5"><span class="color-active"></span></i>
                            <i class="i6"><span class="color-active"></span></i>
                        </div>
                      
                        <span id="eraser">橡皮擦</span>
                        <span id="revocation">撤銷</span>
                        <span id="clear">清除</span>
                        <span id="hide" class="btn-active">關閉</span>
                    
            </div>
        </div>
    
        <canvas id="canvas" width="740" height="420">您的<u>瀏覽器</u>不支持 canvas 標簽</canvas>
        
    </div>
    <script type="text/javascript">
        var paint={
            load:function(){   
                this.x=[];//記錄鼠標移動是的X坐標
                this.y=[];//記錄鼠標移動是的Y坐標
                this.clickDrag=[];
                this.lock=false;//鼠標移動前,判斷鼠標是否按下
                this.isEraser=false;
                this.storageColor="#f00";
                this.eraserRadius=15;//擦除半徑值
                this.color=["#DF4BFF","#9CCB68","#3DC1FF","#FFD338","#FF6262","#000000"];//畫筆顏色
                this.$=function(id){return typeof id=="string"?document.getElementById(id):id;};
                this.canvas=this.$("canvas");
                this.canvas.width=this.$('content-iframe').offsetWidth;//設定canvas的寬度
                this.canvas.height=this.$('content-iframe').offsetHeight;//設定canvas的高度
                if (!this.canvas.getContext) {
                    alert("您的瀏覽器不支持 canvas 標簽");
                    return;
                }
                this.cxt=this.canvas.getContext('2d');
                this.cxt.lineJoin = "round";//context.lineJoin - 指定兩條線段的連接方式
                this.cxt.lineWidth = 5;//線條的寬度
                this.iptClear=this.$("clear");
                this.revocation=this.$("revocation");
                this.hide = this.$('hide');
                this.eraser = this.$('eraser');

                this.colorSpan = this.$('color').getElementsByTagName('span');//顏色的外框的span集合
                this.imgArr = [];//保存每個狀態,撤銷的時候用到
                this.touch =("createTouch" in document);//判定是否為手持設備
                this.StartEvent = this.touch ? "touchstart" : "mousedown";//支持觸摸式使用相應的事件替代
                this.MoveEvent = this.touch ? "touchmove" : "mousemove";
                this.EndEvent = this.touch ? "touchend" : "mouseup";
                this.bind();
            },
            bind:function(){
                var t=this;
                this.hide.onclick = function(){
                    t.canvas.style.display = 'none';
                    t.eraser.className = "";
                    t.hide.className  = 'btn-active'
                    t.hideColorSpan();
                }
                /*清除畫布*/
                this.iptClear.onclick=function(){
                    t.cxt.clearRect(0, 0, t.canvas.width, t.canvas.height-1);
                };
                /*鼠標按下事件,記錄鼠標位置,並繪制,解鎖lock,打開mousemove事件*/
                this.canvas['on'+t.StartEvent]=function(e){   
                    // debugger;
                    t.imgArr.push(t.cxt.getImageData(0, 0,t.canvas.width,t.canvas.height));
                    var touch=t.touch ? e.touches[0] : e;
                    var box = t.canvas.getBoundingClientRect();
                    var _x = (touch.clientX - box.left) * t.canvas.width / box.width
                    var _y = (touch.clientY - box.top) * t.canvas.height / box.height            
                    if(t.isEraser){
                        t.resetEraser(_x,_y,touch);
                    }else{
                        t.movePoint(_x,_y);//記錄鼠標位置
                        t.drawPoint();//繪制路線
                    }
                    t.lock=true;
                };
                /*鼠標移動事件*/
                this.canvas['on'+t.MoveEvent]=function(e){
                    // console.log(t.touch);
                    var touch=t.touch ? e.touches[0] : e;
                    //var touch = e;
                    if(t.lock){
                        var touch=t.touch ? e.touches[0] : e;
                        var box = t.canvas.getBoundingClientRect();
                        var _x = (touch.clientX - box.left) * t.canvas.width / box.width
                        var _y = (touch.clientY - box.top) * t.canvas.height / box.height   
                        if(t.isEraser){
                            t.resetEraser(_x,_y,touch);
                        }
                        else{
                            t.movePoint(_x,_y,true);//記錄鼠標位置
                            t.drawPoint();//繪制路線
                        }
                    }
                };
                this.canvas['on'+t.EndEvent]=function(e){
                    /*重置數據*/
                    t.lock=false;
                    t.x=[];
                    t.y=[];
                    t.clickDrag=[];
                    clearInterval(t.Timer);
                    t.Timer=null;
                    
                };
                this.revocation.onclick=function(){
                    if(t.imgArr.length>0){
                        t.cxt.putImageData(t.imgArr[t.imgArr.length-1], 0, 0);
                        t.imgArr.pop();
                    }
                   
                };
                this.changeColor();
                /*橡皮擦*/
                this.$("eraser").onclick=function(e){
                    if(t.hide.className ===''){
                        t.hideColorSpan();//這里是
                        t.isEraser=true;
                        t.eraser.className = 'btn-active';
                    }
                    
                };
            },
            movePoint:function(x,y,dragging){   
                // debugger;
                /*將鼠標坐標添加到各自對應的數組里*/
                this.x.push(x);
                this.y.push(y);
                this.clickDrag.push(y);
            },
            drawPoint:function(x,y,radius){
                for(var i=0; i < this.x.length; i++){  
                    this.cxt.beginPath();//context.beginPath() , 准備繪制一條路徑
                    if(this.clickDrag[i] && i){//當是拖動而且i!=0時,從上一個點開始畫線。
                        this.cxt.moveTo(this.x[i-1], this.y[i-1]);//context.moveTo(x, y) , 新開一個路徑,並指定路徑的起點
                    }else{
                        this.cxt.moveTo(this.x[i]-1, this.y[i]);
                    }
                    this.cxt.lineTo(this.x[i], this.y[i]);//context.lineTo(x, y) , 將當前點與指定的點用一條筆直的路徑連接起來
                    this.cxt.closePath();//context.closePath() , 如果當前路徑是打開的則關閉它
                    this.cxt.stroke();//context.stroke() , 繪制當前路徑
                }
            },
            preventDefault:function(e){
                /*阻止默認*/
                var touch=this.touch ? e.touches[0] : e;
                if(this.touch)touch.preventDefault();
                else window.event.returnValue = false;
            },
            changeColor:function(){
                /*為按鈕添加事件*/
                var t=this,iptNum=this.$("color").getElementsByTagName("i");
                for(let i=0,l=iptNum.length;i<l;i++){//這里要么用let,要么用閉包
                     iptNum[i].index=i;
                     iptNum[i].onclick=function(){
                        t.hideColorSpan();//隱藏所有顏色的選中
                        t.colorSpan[i].style.display = 'block'//選中點擊的顏色
                        t.canvas.style.display = 'block';
                        // debugger;
                         t.cxt.save();
                         t.cxt.strokeStyle = t.color[this.index];
                         t.storageColor=t.color[this.index];
                         t.$("hide").className = '';
                         t.$("eraser").className = '';//清除橡皮擦選中狀態
                         t.cxt.strokeStyle = t.storageColor;
                         t.isEraser=false;
                     }
                 }
            },
            resetEraser:function(_x,_y,touch){   
                var t=this;
                //this.cxt.lineWidth = 30;
                /*source-over 默認,相交部分由后繪制圖形的填充(顏色,漸變,紋理)覆蓋,全部瀏覽器通過*/
                t.cxt.globalCompositeOperation = "destination-out";
                t.cxt.beginPath();
                t.cxt.arc(_x, _y, t.eraserRadius, 0, Math.PI * 2);
                t.cxt.strokeStyle = "rgba(250,250,250,0)";
                t.cxt.fill();
                t.cxt.globalCompositeOperation = "source-over"
            },
            hideColorSpan:function(){//隱藏顏色的選中狀態
                for(var i =0,length = this.colorSpan.length;i<length;i++){
                    this.colorSpan[i].style.display =  'none'
                }
            }
         
            
        };
        paint.load();
    </script>
 </body>
 </html>   

  


免責聲明!

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



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