`; } else if (selectedElement.type === 'emoji' || selectedElement.type === 'character') { controls.innerHTML = `
`; } else if (selectedElement.type === 'text') { controls.innerHTML = `
`; } } else { document.getElementById('selectedElementInfo').style.display = 'none'; } } window.updateSelectedWidth = function(width) { if (selectedElement && selectedElement.type === 'shape') { selectedElement.width = parseInt(width); updateSelectedInfo(); updatePunCanvas(); } } window.updateSelectedHeight = function(height) { if (selectedElement && selectedElement.type === 'shape') { selectedElement.height = parseInt(height); updateSelectedInfo(); updatePunCanvas(); } } window.updateSelectedSize = function(size) { if (selectedElement && (selectedElement.type === 'emoji' || selectedElement.type === 'character')) { selectedElement.size = parseInt(size); updateSelectedInfo(); updatePunCanvas(); } } window.updateSelectedFontSize = function(fontSize) { if (selectedElement && selectedElement.type === 'text') { selectedElement.fontSize = parseInt(fontSize); updateSelectedInfo(); updatePunCanvas(); } } window.updateSelectedTextColor = function(color) { if (selectedElement && selectedElement.type === 'text') { selectedElement.color = color; updatePunCanvas(); } } window.updateSelectedColor = function(color, type) { if (selectedElement && selectedElement.type === 'shape') { if (type === 'bg') { selectedElement.bgColor = color; } else if (type === 'border') { selectedElement.borderColor = color; } updatePunCanvas(); } } window.updateSelectedBorderWidth = function(width) { if (selectedElement && selectedElement.type === 'shape') { selectedElement.borderWidth = parseInt(width); updateSelectedInfo(); updatePunCanvas(); } } function getMousePos(e) { const rect = punCanvas.getBoundingClientRect(); const scaleX = punCanvas.width / rect.width; const scaleY = punCanvas.height / rect.height; const clientX = e.clientX !== undefined ? e.clientX : (e.touches && e.touches[0] ? e.touches[0].clientX : 0); const clientY = e.clientY !== undefined ? e.clientY : (e.touches && e.touches[0] ? e.touches[0].clientY : 0); return { x: (clientX - rect.left) * scaleX, y: (clientY - rect.top) * scaleY }; } function findElementAtPos(x, y) { for (let i = canvasElements.length - 1; i >= 0; i--) { const element = canvasElements[i]; if (element.type === 'emoji' || element.type === 'character') { const size = element.size || 60; if (x >= element.x - size/2 && x <= element.x + size/2 && y >= element.y - size/2 && y <= element.y + size/2) { return element; } } else if (element.type === 'shape') { const w = element.width; const h = element.height; if (x >= element.x - w/2 && x <= element.x + w/2 && y >= element.y - h/2 && y <= element.y + h/2) { return element; } } else if (element.type === 'text') { punCtx.font = 'bold ' + element.fontSize + 'px ' + element.fontFamily; const metrics = punCtx.measureText(element.text); const width = metrics.width + 20; const height = element.fontSize + 20; if (x >= element.x - width/2 && x <= element.x + width/2 && y >= element.y - height/2 && y <= element.y + height/2) { return element; } } } return null; } function findResizeHandle(element, x, y) { if (element.type !== 'shape') return null; const w = element.width; const h = element.height; const handleSize = 12; const handles = [ { name: 'br', x: element.x + w/2, y: element.y + h/2 }, { name: 'bl', x: element.x - w/2, y: element.y + h/2 }, { name: 'tr', x: element.x + w/2, y: element.y - h/2 }, { name: 'tl', x: element.x - w/2, y: element.y - h/2 } ]; for (let handle of handles) { if (x >= handle.x - handleSize/2 && x <= handle.x + handleSize/2 && y >= handle.y - handleSize/2 && y <= handle.y + handleSize/2) { return handle.name; } } return null; } function handleStart(e) { e.preventDefault(); const pos = getMousePos(e); const element = findElementAtPos(pos.x, pos.y); if (element) { // Check if clicking on resize handle for shapes if (element.type === 'shape' && selectedElement === element) { const handle = findResizeHandle(element, pos.x, pos.y); if (handle) { element.resizing = true; element.resizeHandle = handle; element.startWidth = element.width; element.startHeight = element.height; element.startX = element.x; element.startY = element.y; element.startMouseX = pos.x; element.startMouseY = pos.y; return; } } selectedElement = element; isDragging = true; dragOffset = { x: pos.x - element.x, y: pos.y - element.y }; updateSelectedInfo(); updatePunCanvas(); } else { selectedElement = null; updateSelectedInfo(); updatePunCanvas(); } } function handleMove(e) { e.preventDefault(); const pos = getMousePos(e); // Handle shape resizing if (selectedElement && selectedElement.resizing && selectedElement.type === 'shape') { const deltaX = pos.x - selectedElement.startMouseX; const deltaY = pos.y - selectedElement.startMouseY; let newWidth = selectedElement.startWidth; let newHeight = selectedElement.startHeight; switch(selectedElement.resizeHandle) { case 'br': // Bottom-right newWidth = Math.max(30, Math.min(punCanvas.width, selectedElement.startWidth + deltaX * 2)); newHeight = Math.max(30, Math.min(punCanvas.height, selectedElement.startHeight + deltaY * 2)); break; case 'bl': // Bottom-left newWidth = Math.max(30, Math.min(punCanvas.width, selectedElement.startWidth - deltaX * 2)); newHeight = Math.max(30, Math.min(punCanvas.height, selectedElement.startHeight + deltaY * 2)); break; case 'tr': // Top-right newWidth = Math.max(30, Math.min(punCanvas.width, selectedElement.startWidth + deltaX * 2)); newHeight = Math.max(30, Math.min(punCanvas.height, selectedElement.startHeight - deltaY * 2)); break; case 'tl': // Top-left newWidth = Math.max(30, Math.min(punCanvas.width, selectedElement.startWidth - deltaX * 2)); newHeight = Math.max(30, Math.min(punCanvas.height, selectedElement.startHeight - deltaY * 2)); break; } selectedElement.width = newWidth; selectedElement.height = newHeight; updateSelectedInfo(); updatePunCanvas(); return; } // Handle element dragging if (isDragging && selectedElement) { selectedElement.x = pos.x - dragOffset.x; selectedElement.y = pos.y - dragOffset.y; updatePunCanvas(); } // Update cursor for resize handles if (selectedElement && selectedElement.type === 'shape' && !isDragging && !selectedElement.resizing) { const handle = findResizeHandle(selectedElement, pos.x, pos.y); if (handle) { if (handle === 'br' || handle === 'tl') { punCanvas.style.cursor = 'nwse-resize'; } else { punCanvas.style.cursor = 'nesw-resize'; } } else { punCanvas.style.cursor = 'move'; } } else if (findElementAtPos(pos.x, pos.y)) { punCanvas.style.cursor = 'move'; } else { punCanvas.style.cursor = 'default'; } } function handleEnd(e) { if (selectedElement && selectedElement.resizing) { selectedElement.resizing = false; selectedElement.resizeHandle = null; } isDragging = false; punCanvas.style.cursor = 'default'; } function handleDoubleTap(e) { e.preventDefault(); const pos = getMousePos(e); const element = findElementAtPos(pos.x, pos.y); if (element) { const index = canvasElements.indexOf(element); if (index > -1) { canvasElements.splice(index, 1); if (element === mainTextElement) { mainTextElement = null; } if (element === selectedElement) { selectedElement = null; document.getElementById('selectedElementInfo').style.display = 'none'; } updatePunCanvas(); } } } punCanvas.addEventListener('mousedown', handleStart); punCanvas.addEventListener('mousemove', handleMove); punCanvas.addEventListener('mouseup', handleEnd); punCanvas.addEventListener('dblclick', handleDoubleTap); punCanvas.addEventListener('touchstart', function(e) { const currentTime = new Date().getTime(); const tapLength = currentTime - lastTapTime; if (tapLength < 300 && tapLength > 0) { handleDoubleTap(e); lastTapTime = 0; } else { handleStart(e); lastTapTime = currentTime; } }, { passive: false }); punCanvas.addEventListener('touchmove', handleMove, { passive: false }); punCanvas.addEventListener('touchend', handleEnd, { passive: false }); window.downloadPunImage = function() { const link = document.createElement('a'); link.download = 'my-pun-image.png'; link.href = punCanvas.toDataURL(); link.click(); } window.sharePunToFacebook = function() { downloadPunImage(); setTimeout(function() { const punText = document.getElementById('punTextInput').value; const shareUrl = encodeURIComponent(window.location.href); const shareText = encodeURIComponent(punText + ' - Created with Pun Generator!'); const facebookUrl = 'https://www.facebook.com/sharer/sharer.php?u=' + shareUrl + '"e=' + shareText; window.open(facebookUrl, '_blank'); }, 500); } window.sharePunToTwitter = function() { downloadPunImage(); setTimeout(function() { const punText = document.getElementById('punTextInput').value; const shareUrl = encodeURIComponent(window.location.href); const tweetText = encodeURIComponent(punText + '\n\nCreated with Pun Generator! ðĻ\n'); const twitterUrl = 'https://twitter.com/intent/tweet?text=' + tweetText + '&url=' + shareUrl; window.open(twitterUrl, '_blank'); }, 500); } window.sharePunToPinterest = function() { downloadPunImage(); setTimeout(function() { const punText = document.getElementById('punTextInput').value; const shareUrl = encodeURIComponent(window.location.href); const description = encodeURIComponent(punText + ' - Created with Pun Generator!'); const pinterestUrl = 'https://www.pinterest.com/pin/create/button/?url=' + shareUrl + '&description=' + description; window.open(pinterestUrl, '_blank'); }, 500); } })();