<link href="https://fonts.googleapis.com/css2?family=Great+Vibes&family=Playfair+Display:wght@700&family=Montserrat:wght@700&family=Special+Elite&display=swap" rel="stylesheet">
<div id="stone-app" style="max-width: 800px; margin: auto; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: #fff; border: 1px solid #ddd; padding: 25px; border-radius: 12px; box-shadow: 0 4px 15px rgba(0,0,0,0.1);">
<h2 style="text-align: center; color: #333; margin-bottom: 20px;">Personalize Your Stone</h2>
<div style="display: flex; flex-wrap: wrap; gap: 25px;">
<div style="flex: 1; min-width: 260px; background: #f8f9fa; padding: 15px; border-radius: 8px;">
<label style="font-weight:bold; display:block; margin-bottom:5px; font-size: 14px;">Message:</label>
<input type="text" id="userInput" value="Dream Big" style="width:100%; padding:10px; margin-bottom:15px; border:1px solid #ccc; border-radius:4px;">
<label style="font-weight:bold; display:block; margin-bottom:5px; font-size: 14px;">Font Style:</label>
<select id="userFont" style="width:100%; padding:10px; margin-bottom:15px; border:1px solid #ccc; border-radius:4px;">
<option value="'Great Vibes', cursive">Elegant Script</option>
<option value="'Playfair Display', serif">Classic Bold Serif</option>
<option value="'Montserrat', sans-serif">Modern Clean</option>
<option value="'Special Elite', cursive">Typewriter Etched</option>
</select>
<label style="font-weight:bold; display:block; margin-bottom:5px; font-size: 14px;">Text Size:</label>
<input type="range" id="userSize" min="10" max="120" value="50" style="width:100%; margin-bottom:15px;">
<label style="font-weight:bold; display:block; margin-bottom:5px; font-size: 14px;">Tilt / Rotation:</label>
<input type="range" id="userRotate" min="-45" max="45" value="0" style="width:100%;">
<div style="margin-top:25px; display:flex; gap:10px;">
<button onclick="downloadStone()" style="flex:2; background:#2c7a7b; color:#fff; border:none; padding:12px; border-radius:6px; cursor:pointer; font-weight:bold;">Download Image</button>
<button onclick="resetStone()" style="flex:1; background:#e2e8f0; color:#4a5568; border:none; padding:12px; border-radius:6px; cursor:pointer;">Reset</button>
</div>
</div>
<div id="preview-wrapper" style="flex: 1.5; min-width: 300px; position: relative; display: inline-block; overflow: hidden; border-radius: 8px; border: 1px solid #eee;">
<img id="stoneBase" src="http://paulvalenzuela.com/wp-content/uploads/2026/02/images.jpeg" style="width: 100%; display: block; height: auto;" crossorigin="anonymous">
<div id="textOverlay" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); pointer-events: none; white-space: nowrap; color: rgba(0,0,0,0.6); text-align: center; text-shadow: 1px 1px 1px rgba(255,255,255,0.3);">
Dream Big
</div>
</div>
</div>
<canvas id="hiddenCanvas" style="display:none;"></canvas>
</div>
<script>
const userInput = document.getElementById('userInput');
const userFont = document.getElementById('userFont');
const userSize = document.getElementById('userSize');
const userRotate = document.getElementById('userRotate');
const textOverlay = document.getElementById('textOverlay');
const stoneBase = document.getElementById('stoneBase');
function updatePreview() {
textOverlay.innerText = userInput.value;
textOverlay.style.fontFamily = userFont.value;
textOverlay.style.fontSize = userSize.value + "px";
// Apply rotation and keep the center translation
textOverlay.style.transform = `translate(-50%, -50%) rotate(${userRotate.value}deg)`;
}
// Event listeners to catch changes
userInput.oninput = updatePreview;
userFont.onchange = updatePreview;
userSize.oninput = updatePreview;
userRotate.oninput = updatePreview;
function resetStone() {
userInput.value = "Dream Big";
userFont.selectedIndex = 0;
userSize.value = 50;
userRotate.value = 0;
updatePreview();
}
function downloadStone() {
const canvas = document.getElementById('hiddenCanvas');
const ctx = canvas.getContext('2d');
canvas.width = stoneBase.naturalWidth;
canvas.height = stoneBase.naturalHeight;
ctx.drawImage(stoneBase, 0, 0);
ctx.save();
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate(userRotate.value * Math.PI / 180);
const scaleFactor = stoneBase.naturalWidth / stoneBase.clientWidth;
ctx.font = (userSize.value * scaleFactor) + "px " + userFont.value.split(',')[0];
ctx.fillStyle = "rgba(0,0,0,0.65)";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(userInput.value, 0, 0);
ctx.restore();
const link = document.createElement('a');
link.download = 'custom-stone.png';
link.href = canvas.toDataURL('image/png');
link.click();
}
// Initial run to set default font correctly
window.onload = updatePreview;
</script>