7F-畫版
連結
使用語言
HTML、CSS、Bootstrap、JavaScript(ES6)、Canvas API
BOSS 弱點
- 【特定技術】遊戲規則
- 繪圖區請使用 Canvas 來設計,上方的控制列與下方的畫筆調整可不用
- SAVE :點擊後可直接下載轉出的 PNG 圖片
- CLEAR ALL:清除畫版樣式
- UNDO、REDO:上一步、下一步
- 點擊箭頭時,功能列介面皆可進行收闔
- 【擴充功能】請再自行增加「兩個功能」,我相信勇者們都是很有梗的~
擴充功能
- 支援手機操作
- 支援手機版型
- 橡皮擦
心得
這次是我第一次使用 Bootstrap,之前從來都沒有用過,所以一開始查了蠻多資料了,也不知道用的方法正不正確,不過官方文檔寫得很棒所以其實上手並不難。
Canvas API 的部分,最基礎的畫畫功能其實很簡單,參考 Google
到的文章,很快就可以寫出最基本的東西,之後加上去的功能…花的時間比較多。
點一下畫筆可以切換橡皮擦跟畫筆,橡皮擦是用背景顏色去做的。
之前從來沒有寫過 CSS 的動畫,所以一開始也是去翻文檔,這部分卡了比較久一點,版型我花了超久才弄好…
功能
SAVE
生成一個 Element 把該填的資料填進去,之後再用 click()
觸發。
const link = document.createElement('a')
link.href = canvas.toDataURL()
link.download = 'cancas.png'
link.click()
CLEAR ALL
用 clearRect()
指定範圍清空。
ctx.clearRect(0, 0, canvas.width, canvas.height)
UNDO & REDO
參考資料:連結
做法是用兩個陣列 undoDataStack[]
跟 redoDataStack[]
儲存 UNDO & REDO 的ctx.getImageData()
資料。
還有一個選項是 STACK_MAX_SIZE
可以設定最高紀錄多少步驟,防止瀏覽器效能不足。
控制 .disable
在沒有下一步時關閉按鈕。
const STACK_MAX_SIZE = 30
const undoDataStack = []
let redoDataStack = []
const saveDraw = () => {
redoDataStack = []
document.querySelector('.nav-redo').classList.add('disable')
if (undoDataStack.length >= STACK_MAX_SIZE) { undoDataStack.pop() }
undoDataStack.unshift(ctx.getImageData(0, 0, canvas.width, canvas.height))
document.querySelector('.nav-undo').classList.remove('disable')
}
const undo = () => {
if (undoDataStack.length <= 0) return
redoDataStack.unshift(ctx.getImageData(0, 0, canvas.width, canvas.height))
document.querySelector('.nav-redo').classList.remove('disable')
const imageData = undoDataStack.shift()
ctx.putImageData(imageData, 0, 0)
if (undoDataStack.length <= 0) { document.querySelector('.nav-undo').classList.add('disable') }
}
const redo = () => {
if (redoDataStack.length <= 0) return
undoDataStack.unshift(ctx.getImageData(0, 0, canvas.width, canvas.height))
document.querySelector('.nav-undo').classList.remove('disable')
const imageData = redoDataStack.shift()
ctx.putImageData(imageData, 0, 0)
if (redoDataStack.length <= 0) { document.querySelector('.nav-redo').classList.add('disable') }
}
手機版操作
觸控螢幕監聽事件
canvas.addEventListener('touchstart', touchStart) // mousedown
canvas.addEventListener('touchmove', touchMove) // mousemove
canvas.addEventListener('touchend', touchEnd) // mouseup
參考資料
Tags