Files
JMuseum/public/js/drawing_tools_.js
2018-02-26 14:09:18 +08:00

257 lines
8.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 初始化 */
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];
}