function createPuck(c) { const puck = document.createElement('div'); puck.className = 'puck'; const well = document.createElement('div'); well.className = 'well'; well.style.backgroundColor = c; puck.appendChild(well); const puckMenu = document.createElement('div'); puckMenu.className = 'puck-menu'; puck.appendChild(puckMenu); const selectHandle = document.createElement('div'); selectHandle.className = 'select-handle'; selectHandle.innerHTML = ''; puckMenu.appendChild(selectHandle); const copyHandle = document.createElement('div'); copyHandle.className = 'copy-handle'; copyHandle.innerHTML = ''; puckMenu.appendChild(copyHandle); const deleteHandle = document.createElement('div'); deleteHandle.className = 'delete-handle'; deleteHandle.innerHTML = ''; puckMenu.appendChild(deleteHandle); const updateHandle = document.createElement('div'); updateHandle.className = 'update-handle'; updateHandle.innerHTML = ''; puckMenu.appendChild(updateHandle); const dragHandle = document.createElement('div'); dragHandle.className = 'drag-handle'; dragHandle.innerHTML = ''; puckMenu.appendChild(dragHandle); well.addEventListener('mousedown', (e) => { let isMixing = true; let startX = e.clientX; let startY = e.clientY; document.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); function onMouseMove(e) { if (isMixing) { const distance = Math.sqrt(Math.pow(e.clientX - startX, 2) + Math.pow(e.clientY - startY, 2)); const t = Math.min(1, distance / 300); const mixedColor = mixbox.lerp(color, well.style.backgroundColor, t); color = mixedColor; startX = e.clientX; startY = e.clientY; } } function onMouseUp() { isMixing = false; document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); } }); dragHandle.addEventListener('mousedown', (e) => { let isMovingPuck = true; let startX = e.clientX; let startY = e.clientY; let left = puck.offsetLeft; let top = puck.offsetTop; document.addEventListener('mousemove', (e) => { if (isMovingPuck) { puck.style.left = left + e.clientX - startX + 'px'; puck.style.top = top + e.clientY - startY + 'px'; } }); document.addEventListener('mouseup', () => { isMovingPuck = false; document.removeEventListener('mousemove', () => {}); document.removeEventListener('mouseup', () => {}); }); }); updateHandle.addEventListener('click', () => { console.log('update'); well.style.backgroundColor = color; }); selectHandle.addEventListener('click', () => { console.log('select'); color = well.style.backgroundColor; console.log(color); updateColorPreview(); }); copyHandle.addEventListener('click', () => { pucks.push(createPuck(well.style.backgroundColor)); }); deleteHandle.addEventListener('click', () => { pucks = pucks.filter(p => p !== puck); puck.remove(); }); canvasArea.appendChild(puck); let canvasWidth = canvasArea.offsetWidth; let canvasHeight = canvasArea.offsetHeight; let randonX = Math.floor(Math.random() * canvasWidth); let randonY = Math.floor(Math.random() * canvasHeight); puck.style.left = randonX + 'px'; puck.style.top = randonY + 'px'; return puck; }