odin-etch-a-sketch/script.js

395 lines
10 KiB
JavaScript
Raw Permalink Normal View History

2023-11-09 18:20:28 -07:00
const container = document.querySelector(".container");
const conWidth = container.clientWidth;
const grid = document.createElement("div");
2023-11-09 20:15:53 -07:00
const gridSlider = document.querySelector("#gridSlider");
2023-11-11 15:09:20 -07:00
gridSlider.defaultValue = 16;
const sliderLabel = document.querySelector("#sliderLabel");
const rangeKnob = document.querySelector("#range-knob");
2023-11-11 15:09:20 -07:00
let numGrid;
2023-11-10 13:28:36 -07:00
const buttons = document.querySelectorAll(".pen");
2023-11-10 12:51:07 -07:00
const colorPicker = document.querySelector("#custom-color");
2023-11-10 17:32:29 -07:00
let colorValue;
2023-11-11 15:09:20 -07:00
const backColorPicker = document.querySelector("#back-col-picker");
const transLabel = document.querySelector("#trans-label");
const transSlider = document.querySelector("#canvas-trans");
2023-11-12 22:12:11 -07:00
const rangeSlider = document.querySelector('input[type="range"]');
2023-11-12 23:49:00 -07:00
const reset = document.querySelector("#reset");
2023-11-12 22:12:11 -07:00
2023-11-10 18:39:02 -07:00
//the next few variables are set to be used to test if
//a given button has been clicked
2023-11-10 07:49:31 -07:00
let isRgb;
2023-11-10 08:07:36 -07:00
let isTint;
let isShade;
let isOpaque;
let isTrans;
2023-11-10 12:51:07 -07:00
let isBlack;
let isWhite;
let isErase;
2023-11-09 20:15:53 -07:00
2023-11-10 19:21:39 -07:00
resetGrid();
2023-11-10 13:28:36 -07:00
buttons.forEach((button) => {
button.addEventListener ("click", changeColor);
});
colorPicker.addEventListener("input", changeColor);
2023-11-10 19:28:05 -07:00
colorPicker.addEventListener("change", changeColor);
colorPicker.addEventListener("click", changeColor);
backColorPicker.addEventListener("input", pickBackground);
2023-11-12 22:12:11 -07:00
transSlider.addEventListener("input", adjustTransparency);
2023-11-12 23:49:00 -07:00
rangeSlider.addEventListener('input', changeSliderColor);
2023-11-12 22:12:11 -07:00
gridSlider.addEventListener("input", getGridDimensions);
2023-11-13 09:45:15 -07:00
2023-11-13 08:01:39 -07:00
rangeKnob.addEventListener("pointerdown", (e) => {
document.addEventListener("pointermove", rotateKnob);
document.addEventListener("pointerup", () => {
document.removeEventListener("pointermove", rotateKnob);
2023-11-11 15:09:20 -07:00
});
});
2023-11-13 09:45:15 -07:00
rangeKnob.addEventListener("touchstart", (e) => {
e.preventDefault();
document.addEventListener("touchmove", rotateKnob);
document.addEventListener("touchend", () => {
2023-11-13 09:45:15 -07:00
document.removeEventListener("touchmove", rotateKnob);
});
});
2023-11-10 19:23:03 -07:00
reset.addEventListener("click", resetGrid);
function resetGrid() {
gridSlider.value = gridSlider.defaultValue;
2023-11-11 23:45:04 -07:00
container.style.backgroundColor = "rgb(180, 254, 235)";
backColorPicker.value = "#b4feeb";
colorPicker.value = "#000000";
colorValue = "black";
2023-11-13 03:56:40 -07:00
rangeKnob.style.transform = `rotate(101.309deg)`;
transSlider.value = 1;
2023-11-12 22:32:22 -07:00
transSlider.style.backgroundColor = "rgb(180, 254, 235)";
rangeSlider.style.setProperty('--canvas-color', "rgb(180, 254, 235)");
rangeSlider.style.setProperty('--range-value', `100%`);
transLabel.textContent = transSlider.value
2023-11-10 19:21:39 -07:00
getGridDimensions();
}
2023-11-10 19:23:03 -07:00
2023-11-11 16:26:33 -07:00
function rotateKnob(e) {
const knobBounds = rangeKnob.getBoundingClientRect();
const knobCenter = {
2023-11-12 10:03:16 -07:00
x: knobBounds.left + knobBounds.width / 2,
y: knobBounds.top + knobBounds.height / 2
};
let angle //= Math.atan2(e.clientX - knobCenter.x, -(e.clientY - knobCenter.y)) * (180 / Math.PI);
if (e.clientX) {
// Pointer/mouse event
angle = Math.atan2(e.clientX - knobCenter.x, -(e.clientY - knobCenter.y)) * (180 / Math.PI);
} else if (e.touches[0].clientX) {
// Touch event
angle = Math.atan2(e.touches[0].clientX - knobCenter.x, -(e.touches[0].clientY - knobCenter.y)) * (180 / Math.PI);
}
2023-11-11 16:26:33 -07:00
rangeKnob.style.transform = `rotate(${angle}deg)`;
2023-11-11 17:30:17 -07:00
updateGridSlider(angle);
2023-11-11 16:26:33 -07:00
}
2023-11-12 10:03:16 -07:00
2023-11-11 17:30:17 -07:00
function updateGridSlider(angle) {
const maxRotation = 360;
const minSliderVal = gridSlider.min;
const maxSliderVal = gridSlider.max;
const sliderVal = (angle + maxRotation) % maxRotation;
const normalizedValue = (sliderVal / maxRotation) * (maxSliderVal - minSliderVal) + minSliderVal;
2023-11-11 16:26:33 -07:00
2023-11-11 17:30:17 -07:00
gridSlider.value = normalizedValue;
getGridDimensions(normalizedValue);
}
2023-11-11 16:26:33 -07:00
2023-11-11 17:30:17 -07:00
function getGridDimensions(val) {
numGrid = val;
while (container.firstChild) {
container.removeChild(container.lastChild);
}
2023-11-10 19:21:39 -07:00
createGrid();
}
2023-11-09 18:20:28 -07:00
function createGrid() {
2023-11-10 18:39:02 -07:00
numGrid = gridSlider.value;
2023-11-09 18:20:28 -07:00
const gridArea = numGrid ** 2;
const gridWidth = 100 / numGrid;
2023-11-09 15:14:02 -07:00
2023-11-10 18:39:02 -07:00
sliderLabel.textContent = numGrid;
2023-11-10 20:10:38 -07:00
grid.classList.add("grid", "grid-on");
grid.style.width = gridWidth + '%';
grid.style.height = gridWidth + '%';
grid.style.opacity = 0.9;
2023-11-09 15:14:02 -07:00
2023-11-09 16:31:23 -07:00
for (let i = 0; i < gridArea; i++){
container.appendChild(grid.cloneNode(true));
}
2023-11-09 18:20:28 -07:00
const gridItems = document.querySelectorAll(".grid");
2023-11-10 20:10:38 -07:00
const gridToggle = document.querySelector("#gridToggle");
2023-11-09 18:20:28 -07:00
gridItems.forEach((item) => {
2023-11-13 08:01:39 -07:00
item.addEventListener("pointerover", colorGrid);
2023-11-09 18:20:28 -07:00
});
container.addEventListener("touchmove", function(e) {
2023-11-13 11:30:12 -07:00
e.preventDefault();
gridItems.forEach((item) => {
const rect = item.getBoundingClientRect();
const touch = e.touches[0];
// Check if the touch is within the boundaries of the current grid item
if (
touch.clientX >= rect.left &&
touch.clientX <= rect.right &&
touch.clientY >= rect.top &&
touch.clientY <= rect.bottom
) {
colorGrid.call(item);
}
});
}, {passive: false});
2023-11-10 20:10:38 -07:00
gridToggle.addEventListener("click", () => {
gridItems.forEach((item) => {
toggleGridView(item);
});
});
}
function toggleGridView(gridItem) {
if (gridItem.classList.contains("grid-on")){
gridItem.classList.remove("grid-on");
gridItem.classList.add("grid-off");
} else {
gridItem.classList.remove("grid-off");
gridItem.classList.add("grid-on");
}
}
2023-11-12 23:49:00 -07:00
function changeSliderColor() {
const percentage = ((rangeSlider.value - rangeSlider.min) / (rangeSlider.max - rangeSlider.min)) * 100;
rangeSlider.style.setProperty('--range-value', `${percentage}%`);
}
2023-11-10 20:10:38 -07:00
function pickBackground() {
const currentColor = container.style.backgroundColor;
let num = currentColor.match(/\d+/g);
let num2 = convertHexToRGB(backColorPicker.value);
let r;
let g;
let b;
let a;
if (currentColor.includes("rgba")) {
console.log(num2);
console.log(num)
r = num2[0];
g = num2[1];
b = num2[2];
a = num[3]+ "."+ num[4];
container.style.backgroundColor = `rgba(${r},${g},${b},${a})`;
2023-11-12 22:32:22 -07:00
transSlider.style.backgroundColor = `rgba(${r},${g},${b},${a})`;
rangeSlider.style.setProperty('--canvas-color', `rgba(${r},${g},${b},${a})`);
} else {
container.style.backgroundColor = backColorPicker.value;
2023-11-12 22:32:22 -07:00
transSlider.style.backgroundColor = backColorPicker.value;
rangeSlider.style.setProperty('--canvas-color', backColorPicker.value);
}
}
function convertHexToRGB(val) {
hex = val.replace(/^#/, '');
// Parse the hex value
const bigint = parseInt(hex, 16);
// Extract RGB components
const r = (bigint >> 16) & 255;
const g = (bigint >> 8) & 255;
const b = bigint & 255;
return ([r, g, b]);
2023-11-09 20:15:53 -07:00
}
2023-11-09 16:31:23 -07:00
function adjustTransparency() {
const currentColor = container.style.backgroundColor;
let num = currentColor.match(/\d+/g);
let r;
let g;
let b;
let a;
r = +num[0];
g = +num[1];
b = +num[2];
a = transSlider.value;
transLabel.textContent = a;
container.style.backgroundColor = `rgba(${r},${g},${b},${a})`;
2023-11-12 22:32:22 -07:00
transSlider.style.backgroundColor = `rgba(${r},${g},${b},${a})`;
rangeSlider.style.setProperty('--canvas-color', `rgba(${r},${g},${b},${a})`);
}
2023-11-09 20:15:53 -07:00
function colorGrid() {
2023-11-10 07:49:31 -07:00
if (isRgb) {
2023-11-10 12:51:07 -07:00
this.style.backgroundColor = randomizeColor();
2023-11-10 08:26:39 -07:00
} else if (isTint) {
2023-11-10 12:51:07 -07:00
this.style.backgroundColor = tintColor(this.style.backgroundColor);
2023-11-10 09:20:46 -07:00
} else if (isShade) {
2023-11-10 12:51:07 -07:00
this.style.backgroundColor = shadeColor(this.style.backgroundColor);
} else if (isOpaque){
this.style.opacity = makeOpaque(this.style.opacity);
} else if (isTrans) {
this.style.opacity = makeTransparent(this.style.opacity);
2023-11-10 12:51:07 -07:00
} else if (isBlack) {
this.style.backgroundColor = "rgb(0, 0, 0)";
} else if (isWhite) {
this.style.backgroundColor = "rgb(255, 255, 255)";
} else if (isErase) {
this.style.backgroundColor = "";
2023-11-28 04:22:12 -07:00
this.style.opacity = 0.9;
2023-11-10 07:49:31 -07:00
} else {
this.style.backgroundColor = colorPicker.value;
2023-11-10 07:49:31 -07:00
}
}
function changeColor() {
const buttonID = this.id;
colorPicker.classList.remove ("is-active");
buttons.forEach(btn => btn.classList.remove("is-active"));
this.classList.add("is-active");
2023-11-10 07:49:31 -07:00
if (buttonID === "rgbColor") {
isRgb = true;
} else {
isRgb = false;
}
2023-11-10 08:26:39 -07:00
if (buttonID === "tint") {
isTint = true;
} else {
isTint = false
}
2023-11-10 09:20:46 -07:00
if (buttonID === "shade") {
isShade = true;
} else {
isShade = false
}
if (buttonID === "opacity") {
isOpaque = true;
} else {
isOpaque = false
}
if (buttonID === "trans") {
isTrans = true;
} else {
isTrans = false
}
2023-11-10 12:51:07 -07:00
if (buttonID === "whiteColor") {
isWhite = true;
} else {
isWhite = false
}
if (buttonID === "blackColor") {
isBlack = true;
} else {
isBlack = false
}
if (buttonID === "erase") {
isErase = true;
} else {
isErase = false
}
2023-11-09 20:15:53 -07:00
}
2023-11-09 16:31:23 -07:00
2023-11-10 08:26:39 -07:00
function randomizeColor() {
2023-11-09 23:17:42 -07:00
let r = Math.floor(Math.random() * 255);
let g = Math.floor(Math.random() * 255);
let b = Math.floor(Math.random() * 255);
return `rgb(${r},${g},${b})`;
2023-11-10 09:20:46 -07:00
}
2023-11-10 09:20:46 -07:00
function tintColor(value) {
if (!value) {
value = container.style.backgroundColor
}
2023-11-10 09:20:46 -07:00
let num = value.match(/\d+/g);
let r = +num[0] + (0.25 * (255 - +num[0]));
let g = +num[1] + (0.25 * (255 - +num[1]));
let b = +num[2] + (0.25 * (255 - +num[2]));
2023-11-10 09:20:46 -07:00
return`rgb(${r},${g},${b})`;
}
2023-11-10 09:20:46 -07:00
function shadeColor(value) {
if (!value) {
value = container.style.backgroundColor
}
2023-11-10 09:20:46 -07:00
let num = value.match(/\d+/g);
let r = +num[0] * .75;
let g = +num[1] * .75;
let b = +num[2] * .75;
2023-11-09 23:17:42 -07:00
2023-11-10 09:20:46 -07:00
return`rgb(${r},${g},${b})`;
2023-11-09 23:17:42 -07:00
}
function makeOpaque(value) {
let num = +value;
if (num < 1){
num += .1
}
return num;
}
function makeTransparent(value) {
let num = +value;
if (num > 0){
num -= .1
}
return num;
2023-11-10 13:28:36 -07:00
}