1
   | <canvas id="cvs" width="800" height="600" style="border: 1px solid #000000;"></canvas>
   | 
 
基本用法
綁定 canvas
1 2 3 4 5
   | const cvs=document.querySelector('#cvs') // 宣告  Canvas Content Object  getContext() 2d webgl //       2D 畫面 3D 畫面  const ctx= cvs.getContext('2d')
  | 
 
Fill 填滿
1 2 3 4 5 6
   | // 填滿顏色 ctx.fillStyle="red" // 透明度 1 為不透明 0 為完全透明 ctx.globalAlpha=0.5 //  fillRect(X,Y,weight,height) ctx.fillRect(50,50,100,100)
   | 
 
Stroke 描邊
1 2 3 4
   | // 描邊顏色 ctx.strokeStyle='blue' // strokeRect(X,Y,weight,height) ctx.strokeRect(100,100,100,100)
   | 
 
Path 路徑
1 2 3 4 5 6 7 8 9 10
   | // 開啟路徑 ctx.beginPath()  // 移動到當前所在位置 moveTo(X,Y) ctx.moveTo(300,300) // 與設定座標畫一直線 lineTo(X,Y) ctx.lineTo(400,500) // 關閉路徑 ctx.closePath() // 選擇顯現方式 stoke() fill() ctx.stroke()
   | 
 
繪製多邊形
1 2 3 4 5 6
   | ctx.beginPath() ctx.moveTo(300,300) ctx.lineTo(100,500) ctx.lineTo(500,500) ctx.closePath() ctx.fill()
   | 
 

影像處理、濾鏡
影像處理
1 2 3 4 5 6
   | let img=new Image()  img.src='../head.png' img.onload=function () { // 註冊 load 事件,圖片載入完成後,入完成後,才做繪製     // drawImage(img,X,Y,width,height)     ctx.drawImage(img,0,0,cvs.width,cvs.height) }
   | 
 
濾鏡
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
   | // Html     <button onclick="invertColor()">影像反轉</button>     <canvas id="cvs" width="800" height="600" style="border: 1px solid #000000;"></canvas> // JavaScript     function invertColor(){     let pixels=ctx.getImageData(0,0,cvs.width,cvs.height)     //一個像素佔據 4 個資料 (bytes) 。 r,g,b,a(範圍 0 ~ 255)     let pixelsData=pixels.data      for (let i = 0; i < pixelsData.length; i+=4) {         pixelsData[i]=255-pixelsData[i]         pixelsData[i+1]=255-pixelsData[i+1]         pixelsData[i+2]=255-pixelsData[i+2]              }     ctx.putImageData(pixels,0,0) }
   | 
 
檔案輸入、輸出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
   | // Html
  <input type="file"  onchange="loadFile(this)"> <button onclick="saveFile()">儲存檔案</button> <a href="" id="download"></a> <canvas id="cvs" width="800" height="600" style="border: 1px solid #000000;"></canvas>
  // JavaScript
  function loadFile(input){     // 抓取 input files     let files=input.files[0]     // 把 files 轉成網址     let url=URL.createObjectURL(files)     let img=new Image()     img.src=url     img.onload=function () {         ctx.drawImage(img,0,0,cvs.width,cvs.height)     } }
  function saveFile() {     const link=document.querySelector('#download')     // a 連結下載格式     link.download='image.jpg'     // canvas 輸出格式     link.href=cvs.toDataURL('image/jpeg')     link.click() }
   | 
 
畫線
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
   | let painting=false // 按下滑鼠代表開始畫畫 cvs.addEventListener('mousedown',startPosition) // 放下滑鼠代表完成畫畫 cvs.addEventListener('mouseup',finishedPosition) // 滑鼠移動代表正在畫畫 cvs.addEventListener('mousemove',draw) 
 
  function startPosition() { painting=true } function finishedPosition(e) {     painting=false     ctx.beginPath() } function draw(e) {     // 如果正在畫畫就 return     if(!painting)return     if(stroke && !eraser){         ctx.lineWidth=size         ctx.strokeStyle=color         ctx.lineCap='round'         ctx.lineTo(e.clientX,e.clientY)         ctx.stroke()         ctx.beginPath()         ctx.moveTo(e.clientX,e.clientY)     }else if(!stroke && eraser){         ctx.lineWidth=size         ctx.strokeStyle='#E8E8E8'         ctx.lineCap='round'         ctx.lineTo(e.clientX,e.clientY)         ctx.stroke()         ctx.beginPath()         ctx.moveTo(e.clientX,e.clientY)     } }
   | 
 
Undo、Redo
創建一個物件,每次畫完就擷取圖片存在物件裡,物件[步驟]讀取畫面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
   | let restore_array=[] let step=-1
 
   function finishedPosition(e) {     painting=false     ctx.beginPath()     console.log(e.type)     if(e.type!='mousedown'){         restore_array.push(ctx.getImageData(0,0,cvs.width,cvs.height))         step++     }     if(restore_array.length>0){         console.log(1)         domUndo.classList.add('btn-active')     }else{         domUndo.classList.remove('btn-active')     } }
      function undo(e) {     e.preventDefault()     if(step<=0){         allClear()         domUndo.classList.remove('btn-active')     }else{         console.log(restore_array)         domUndo.classList.add('btn-active')         step--         ctx.putImageData(restore_array[step],0,0)     }     if(step<restore_array.length&&step>=0){         domRedo.classList.add('btn-active')     }else{         domRedo.classList.remove('btn-active')     } } function redo(e) {     e.preventDefault()     console.log(step)     if(step==restore_array.length||step<0){         return     }else if(step<restore_array.length){         step++           ctx.putImageData(restore_array[step],0,0)     } }
 
   |