基于html5 canvas做批改作業(yè)的小插件

今天公司有一個新的需求,就是要在返回的作業(yè)照片里面可以涂鴉批改,批改完后就連同批改后的照片上傳到服務器。這對我不怎么熟悉canvas的人來說是個挑戰(zhàn)。
需求分析
- 能進行批改,就是相當于畫筆
- 能進行畫筆的撤回功能
- 能進行全部畫筆的清除功能
- 可以轉(zhuǎn)化畫筆的顏色
技術上的實現(xiàn)思路
在聽到這需求后的第一反應就是用canvas來做,所以我在w3school閱讀了 canvas的API .
1.將圖片轉(zhuǎn)到canvas,用到API: drawImage()
2畫筆的實現(xiàn)
- 當按下鼠標(mousedown)記錄開始點startX, startY
- 當移動鼠標的時候(mousemove)就獲取當前的鼠標的坐標e.clientX, e.clientY,獲取到了當前的坐標后,與上一個點的坐標軸的左邊進行連線(lineTo ),這樣就能畫出了一條橫線了
- 當鼠標松開左鍵(mouseup)時候,就清除mousemove的函數(shù)
3.清除功能:講原始的圖片再次用drawImage()函數(shù)來重置
4.撤回功能:在每次按下鼠標那時候,用getImageData()函數(shù)獲取當前的圖像記錄到數(shù)組里面,然后按撤回則使用putImageData()函數(shù)放在canvas
5.畫筆的顏色:在mousemove里面改變strokeStyle筆的顏色
代碼實現(xiàn)
移動鼠標畫出線條的代碼
let self = this; this.canvasNode = document.createElement('canvas'); let styleString = this.utils.formatStyle(CANVAS_STYLE); // CANVAS_STYLE是canvas的樣式 this.canvasNode.setAttribute('id','canvas'); // 一定要設置這width 和 height let ratio = this.imgNode.width / this.imgNode.height, height = this.imgNode.height, width = this.imgNode.width; let tempWidth , tempHeight; // 按比例伸縮 if(ratio >= window.innerWidth / window.innerHeight){ if(width > window.innerWidth){ tempWidth = window.innerWidth; tempHeight = height * window.innerWidth / width; } else { tempWidth = width; tempHeight = height; } }else{ if(height > window.innerHeight){ tempWidth = width * window.innerHeight / width; tempHeight = window.innerHeight; }else{ tempWidth = width; tempHeight = height; } } this.canvasNode.height = tempHeight; this.canvasNode.width = tempWidth; styleString = Object.assign({'width': tempWidth, 'height': tempHeight}, CANVAS_STYLE); this.canvasNode.setAttribute('style', styleString); let ctx = this.canvasNode.getContext('2d'), startX = 0, startY = 0; let image = new Image() ; image.setAttribute("crossOrigin",'Anonymous') // 加時間戳因為這圖片的域名沒設置跨域https://www.jianshu.com/p/c3aa975923de image.src = this.imgNode.src + '?t=' + new Date().getTime(); image.height = tempHeight; image.width = tempWidth; image.onload = function(){ ctx.drawImage(image, 0, 0, tempWidth, tempHeight); } // 鼠標移動事件 let mousemoveFn = function(e) { ctx.beginPath(); ctx.lineWidth = 3; ctx.strokeStyle = self.currentColor; if(startX == e.clientX - self.canvasNode.offsetLeft || startY === e.clientY - self.canvasNode.offsetTop ) return ctx.moveTo(startX,startY); ctx.lineTo(e.clientX - self.canvasNode.offsetLeft , e.clientY - self.canvasNode.offsetTop ); ctx.stroke(); startX = e.clientX - self.canvasNode.offsetLeft; startY = e.clientY - self.canvasNode.offsetTop ; // 37是header的高度 } // 鼠標按下事件 this.canvasNode.addEventListener("mousedown",function(e){ startX = e.clientX - self.canvasNode.offsetLeft; startY = e.clientY - self.canvasNode.offsetTop ; // 如果在mouseup那里記錄 則在撤回時候要做多一個步驟 let imageData = ctx.getImageData(0,0, self.canvasNode.width, self.canvasNode.height); self.imageDataArray.push(imageData); // 這imageDataArray用來記錄畫筆的筆畫 self.canvasNode.addEventListener("mousemove", mousemoveFn, false); },false); this.canvasNode.addEventListener('mouseup', function(e){ self.canvasNode.removeEventListener('mousemove', mousemoveFn); }); this.bgNode.appendChild(this.canvasNode);
遇到的問題
1.圖片的跨域問題 因為這個域名只設置了192.168.6.*的跨域,所以我localhost的域名會報跨域的問題(只對192.168.6.*的跨域是同事告訴我的,不然我還在傻乎乎的查問題)
解決辦法:設置vue.congfig.js文件的dev下的host
2.圖片的按比例伸縮完按保存后圖片的尺寸變了 我用toDataURL()方法輸出的base64后的圖片尺寸變了。原因:在我把圖片draw上canvas上時候,用了上面代碼的圖片那比例伸縮的算法把圖片變小了,所以畫在canvas上的圖片也變小了...
解決辦法:(待解決)
總結
- 第一次接觸canvas與圖片相結合的功能,讓我熟悉了canvas的api
- 在遇到?jīng)]做過的功能之前,一定要先定下心來運用你所知道的知識思考下有沒可行的方法,找到了突破點就可以做了
- 在你碰上不熟悉的知識時候,一定要先看api,我這canvas之前不怎么會的,之后我細看了幾遍的api,我就可以上手去做功能了,并且在w3school看到的例子讓我覺得canvas真的很強大
到此這篇關于基于html5 canvas做批改作業(yè)的小插件的文章就介紹到這了,更多相關canvas 批改作業(yè)插件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持腳本之家!
相關文章
- Microdata作為HTML5新增的一個特性,它允許開發(fā)者在HTML文檔中添加更多的語義信息,以便于搜索引擎和瀏覽器更好地理解頁面內(nèi)容,本文將探討HTML5中Microdata的使用方法以及2025-04-21
- 在HTML語法中,表格主要通過< table >、< tr >和< td >3個標簽構成,本文通過實例代碼講解HTML5表格語法格式,感興趣的朋友一起看看吧2025-04-21
- 這篇文章主要介紹了HTML5中使用媒體查詢和Flexbox進行響應式布局的方法,簡要介紹了CSS Grid布局的基礎知識和如何實現(xiàn)自動換行的網(wǎng)格布局,感興趣的朋友一起看看吧2025-04-21
基于Canvas的Html5多時區(qū)動態(tài)時鐘實戰(zhàn)代碼
本文介紹了如何使用Canvas在HTML5上實現(xiàn)一個多時區(qū)動態(tài)時鐘的web展示,通過Canvas的API,可以繪制出6個不同城市的時鐘,并且這些時鐘可以動態(tài)轉(zhuǎn)動,每個時鐘上都會標注出對應的2025-03-11HTML5 data-*自定義數(shù)據(jù)屬性的示例代碼
HTML5的自定義數(shù)據(jù)屬性(data-*)提供了一種標準化的方法在HTML元素上存儲額外信息,可以通過JavaScript訪問、修改和在CSS中使用,文章還介紹了高級用法,如存儲JSON數(shù)據(jù)、事2025-03-11- 在HTML5中,下拉框(<select>標簽)作為表單的重要組成部分,為用戶提供了一個從預定義選項中選擇值的方式,本文將深入探討<select>標簽的屬性、樣式,并重點介2025-02-27
- 本文介紹了HTML5InputDatePicker對象表示HTML``元素,是HTML5中的新對象,介紹了日期、周、月份、時間、日期+時間、本地日期時間等不同類型的日期選擇器,感興趣的朋友一起看2025-02-17
- 本文介紹了HTML5中的超鏈接、相對路徑和圖片的使用方法,超鏈接可以創(chuàng)建指向另一個文檔或頁面內(nèi)部書簽的鏈接,相對路徑用于在同一服務器內(nèi)部跳轉(zhuǎn)頁面,圖片標簽用于引入外部圖2025-02-17
- 本文介紹了HTML5超鏈接的創(chuàng)建方法,包括基本語法、創(chuàng)建圖像超鏈接的邊框去除方法以及錨點鏈接的使用,還討論了超鏈接的四種不同狀態(tài)(link、visited、hover、active)的CSS樣2025-02-17
- 最近看一些技術網(wǎng)站發(fā)現(xiàn)了details 標簽的妙用,這個不用js即可實現(xiàn)展開/收縮信息,很方便用來讓用戶先才答案,然后下面點擊再給出答案的效果,這里就為大家簡單介紹一下,2024-11-03