257 lines
8.6 KiB
JavaScript
257 lines
8.6 KiB
JavaScript
/* 初始化 */
|
||
let canvas = null,
|
||
mainColor = "black",
|
||
subColor = "black",
|
||
enableSubColor = true,
|
||
brushSize = 16,
|
||
strokeSize = 1;
|
||
|
||
let subColorDiv = $("div.sub-color-picker"),
|
||
sizeGroupText = $("label#sizeGroupText"),
|
||
strokeGroupText = $("label#strokeSizeGroupText");
|
||
|
||
let activedBrush = $("input#normalBrush"),
|
||
drawingMethod = normalBrush_Drawing;
|
||
|
||
let paintingImage;
|
||
|
||
/* 事件處理簽署 */
|
||
|
||
if (!isFinished) {
|
||
document.getElementById("resetCanvas").addEventListener("click", () => background(255));
|
||
document.getElementById("mainColorPicker").addEventListener("change", changeColor);
|
||
document.getElementById("subColorPicker").addEventListener("change", changeColor);
|
||
document.getElementById("subColorPicker").addEventListener("click", e => e.stopPropagation() ); //防止按下按鈕時,會動到上一層的sub-color-picker
|
||
document.querySelector("div.sub-color-picker").addEventListener("click", subColorDivClick);
|
||
document.getElementById("sizeUp").addEventListener("click", () => changeBrushSize(1));
|
||
document.getElementById("sizeDown").addEventListener("click", () => changeBrushSize(-1));
|
||
document.getElementById("sizeUp10").addEventListener("click", () => changeBrushSize(10));
|
||
document.getElementById("sizeDown10").addEventListener("click", () => changeBrushSize(-10));
|
||
document.getElementById("strokeSizeUp").addEventListener("click", () => changeStrokeSize(1));
|
||
document.getElementById("strokeSizeDown").addEventListener("click", () => changeStrokeSize(-1));
|
||
document.getElementById("strokeSizeUp10").addEventListener("click", () => changeStrokeSize(10));
|
||
document.getElementById("strokeSizeDown10").addEventListener("click", () => changeStrokeSize(-10));
|
||
document.getElementById("normalBrush").addEventListener("click", changeBrushStyle);
|
||
document.getElementById("slideBrush").addEventListener("click", changeBrushStyle);
|
||
document.getElementById("featherBrush").addEventListener("click", changeBrushStyle);
|
||
document.getElementById("furBrush").addEventListener("click", changeBrushStyle);
|
||
document.getElementById("stampBrush").addEventListener("click", changeBrushStyle);
|
||
}
|
||
|
||
$("#msgDialog").on('show.bs.modal', () => { drawingEnable = false; });
|
||
$("#msgDialog").on('hidden.bs.modal', () => { drawingEnable = true; });
|
||
|
||
/* p5.js */
|
||
|
||
// 預初始化的作業
|
||
function preload() {
|
||
if (paintingId) {
|
||
paintingImage = loadImage("/db/paintings/" + paintingId + ".png");
|
||
}
|
||
}
|
||
|
||
// 初始化畫布、畫布內容
|
||
function setup() {
|
||
// 依瀏覽器特性調整畫布版面
|
||
let isChrome = !!window.chrome && !!window.chrome.webstore;
|
||
if (isChrome) {
|
||
canvas = createCanvas(800, 450);
|
||
canvas.windowWidth = 800;
|
||
canvas.windowHeight = 450;
|
||
canvas.canvas.style = "width: 800px; height: 450px;";
|
||
}
|
||
else {
|
||
canvas = createCanvas(800, 450);
|
||
}
|
||
// 將p5的canvas設定在canvasContainer之下
|
||
canvas.parent("canvasContainer");
|
||
|
||
// 若有設定 paintingId ..
|
||
if (paintingId) {
|
||
// .. 且有讀取到畫作影像,則將畫作影像繪製到畫布上
|
||
if (paintingImage) {
|
||
image(paintingImage, 0, 0, canvas.width, canvas.height);
|
||
}
|
||
// .. 若沒有讀取到影像,則顯示訊息
|
||
else {
|
||
$("#msgDialog_title").text("畫作讀取錯誤");
|
||
$("#msgDialog_message").text("無法讀取到指定的畫作影像資料。請確認目前畫作是否所屬於您,或重新整理此頁面。");
|
||
$('#msgDialog').modal('show');
|
||
}
|
||
}
|
||
// 若沒有設定 paintingId ,則畫上空白畫布
|
||
else {
|
||
background(255);
|
||
}
|
||
}
|
||
|
||
// p5.js 中循環繪圖的函式
|
||
function draw() {}
|
||
|
||
function mousePressed() {
|
||
drawingMethod(true, false);
|
||
}
|
||
|
||
function mouseDragged() {
|
||
drawingMethod(false, false);
|
||
}
|
||
|
||
function mouseReleased() {
|
||
drawingMethod(false, true);
|
||
}
|
||
|
||
function isOutCanvas(x, y) {
|
||
return (x < 0 || x > canvas.width) || (y < 0 || y > canvas.height);
|
||
}
|
||
|
||
/* 不同的繪圖模式: 筆刷、滑筆、燕筆 */
|
||
var brushMethods = {"normalBrush" : normalBrush_Drawing,
|
||
"slideBrush" : slideBrush_Drawing,
|
||
"featherBrush" : featherBrush_Drawing,
|
||
"furBrush" : furBrush_Drawing,
|
||
"stampBrush" : stampBrush_Drawing };
|
||
var drawingEnable = true;
|
||
var lastPosition = { X: 0, Y: 0};
|
||
var isSliding = false;
|
||
var lastSize, desizeSpeed;
|
||
|
||
//筆刷
|
||
function normalBrush_Drawing(isMousePressed) {
|
||
if(isOutCanvas(mouseX, mouseY) || !drawingEnable) return;
|
||
if (isMousePressed) lastPosition = { X: mouseX, Y: mouseY };
|
||
strokeWeight(strokeSize);
|
||
enableSubColor ? stroke(subColor) : noStroke();
|
||
line(lastPosition.X, lastPosition.Y, mouseX, mouseY);
|
||
lastPosition.X = mouseX;
|
||
lastPosition.Y = mouseY;
|
||
}
|
||
|
||
//滑筆
|
||
function slideBrush_Drawing(isMousePressed, isMouseReleased) {
|
||
if (isMousePressed) {
|
||
if(isOutCanvas(mouseX, mouseY) || !drawingEnable) return;
|
||
lastPosition = { X: mouseX, Y: mouseY };
|
||
isSliding = true;
|
||
setTimeout(slideBrush_Moving, 10);
|
||
}
|
||
else if(isMouseReleased) {
|
||
isSliding = false;
|
||
}
|
||
else {
|
||
isSliding = !isOutCanvas(lastPosition.X, lastPosition.Y);
|
||
}
|
||
}
|
||
function slideBrush_Moving() {
|
||
var dx = mouseX - lastPosition.X, dy = mouseY - lastPosition.Y;
|
||
dx = Math.abs(dx) > 100 ? 2 * Math.sign(dx) : dx / 50;
|
||
dy = Math.abs(dy) > 100 ? 2 * Math.sign(dy) : dy / 50;
|
||
strokeWeight(strokeSize);
|
||
enableSubColor ? stroke(subColor) : noStroke();
|
||
line(lastPosition.X, lastPosition.Y, lastPosition.X + dx, lastPosition.Y + dy);
|
||
lastPosition.X += dx;
|
||
lastPosition.Y += dy;
|
||
if (isSliding && drawingMethod == slideBrush_Drawing)
|
||
setTimeout(slideBrush_Moving, 10);
|
||
}
|
||
|
||
//燕筆(燕尾筆)
|
||
function featherBrush_Drawing(isMousePressed) {
|
||
if(isOutCanvas(mouseX, mouseY) || !drawingEnable) return;
|
||
if (isMousePressed) {
|
||
lastPosition = { X: mouseX, Y: mouseY };
|
||
lastSize = strokeSize;
|
||
desizeSpeed = strokeSize / 20;
|
||
if(desizeSpeed < 0) desizeSpeed = 0.5;
|
||
}
|
||
else {
|
||
strokeWeight(lastSize);
|
||
enableSubColor ? stroke(subColor) : noStroke();
|
||
line(lastPosition.X, lastPosition.Y, mouseX, mouseY);
|
||
lastPosition.X = mouseX;
|
||
lastPosition.Y = mouseY;
|
||
if(lastSize > 0) lastSize = lastSize - 0.5;
|
||
}
|
||
}
|
||
|
||
//刺筆
|
||
function furBrush_Drawing(isMousePressed) {
|
||
if(isOutCanvas(mouseX, mouseY) || !drawingEnable) return;
|
||
if (isMousePressed) {
|
||
lastPosition = { X: mouseX, Y: mouseY };
|
||
}
|
||
else {
|
||
var dx = mouseX - lastPosition.X, dy = mouseY - lastPosition.Y;
|
||
dx = dx > 40 ? 2 : dx / 20;
|
||
dy = dy > 40 ? 2 : dy / 20;
|
||
strokeWeight(strokeSize);
|
||
enableSubColor ? stroke(subColor) : noStroke();
|
||
line(lastPosition.X, lastPosition.Y, mouseX, mouseY);
|
||
lastPosition.X += dx;
|
||
lastPosition.Y += dy;
|
||
}
|
||
}
|
||
|
||
//印筆
|
||
function stampBrush_Drawing() {
|
||
if(isOutCanvas(mouseX, mouseY) || !drawingEnable) return;
|
||
strokeWeight(strokeSize);
|
||
enableSubColor ? stroke(subColor) : noStroke();
|
||
fill(mainColor);
|
||
ellipse(mouseX, mouseY, brushSize, brushSize);
|
||
}
|
||
|
||
|
||
|
||
/* 繪圖板、工具區事件設定 */
|
||
|
||
/**
|
||
* 當使用者點下外框顏色,表示是否啟用外框色的事件處理。
|
||
* @param {DOMEvent} e 事件物件。
|
||
*/
|
||
function subColorDivClick(e) {
|
||
enableSubColor = !enableSubColor;
|
||
subColorDiv.css("backgroundColor", (enableSubColor ? "#cdffa5" : "#ffb6a4"));
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 當使用者變更比刷顏色時的事件。
|
||
* @param {DOMEvent} e 事件物件。
|
||
*/
|
||
function changeColor(e) {
|
||
var target = e.target ? e.srcElement : e.target;
|
||
if (target.id == "mainColorPicker")
|
||
mainColor = color(target.value);
|
||
else
|
||
subColor = color(target.value);
|
||
}
|
||
|
||
/**
|
||
* 變更比刷填滿的粗細大小。
|
||
* @param {number} d 筆刷大小的變更量。
|
||
*/
|
||
function changeBrushSize(d) {
|
||
if (brushSize + d < 1) brushSize = 1;
|
||
else if (brushSize + d > 128) brushSize = 128;
|
||
else brushSize += d;
|
||
sizeGroupText.text("填色大小 " + brushSize);
|
||
}
|
||
|
||
/**
|
||
* 變更比刷外框的粗細大小。
|
||
* @param {number} d 筆刷大小的變更量。
|
||
*/
|
||
function changeStrokeSize(d) {
|
||
if (strokeSize + d < 1) strokeSize = 1;
|
||
else if (strokeSize + d > 128) strokeSize = 128;
|
||
else strokeSize += d;
|
||
strokeGroupText.text("筆刷粗細 " + strokeSize);
|
||
}
|
||
|
||
//更變筆刷模式
|
||
function changeBrushStyle(e) {
|
||
activedBrush.removeClass("active");
|
||
activedBrush = $(e.target);
|
||
activedBrush.addClass("active");
|
||
drawingMethod = brushMethods[e.target.id];
|
||
} |