{"id":103,"date":"2026-05-29T16:48:33","date_gmt":"2026-05-29T16:48:33","guid":{"rendered":"https:\/\/elpalaciodelaoportunidad.com\/palacio\/?page_id=103"},"modified":"2026-05-29T16:57:06","modified_gmt":"2026-05-29T16:57:06","slug":"ruleta","status":"publish","type":"page","link":"https:\/\/elpalaciodelaoportunidad.com\/palacio\/ruleta\/","title":{"rendered":"ruleta"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"103\" class=\"elementor elementor-103\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8045a39 e-flex e-con-boxed e-con e-parent\" data-id=\"8045a39\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-1fb1531 elementor-widget elementor-widget-html\" data-id=\"1fb1531\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\n<html lang=\"es\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=624, initial-scale=1.0\">\n<title>Ruleta de Premios - El Palacio<\/title>\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=DM+Sans:wght@400;500;700;800;900&display=swap\" rel=\"stylesheet\">\n<style>\n  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n\n  :root {\n    --red: #F40000;\n    --red-dark: #B30000;\n    --gold: #FFD700;\n    --gold-dark: #C9961A;\n    --white: #FFFFFF;\n    --bg: #D40000;\n  }\n\n  html, body {\n    width: 624px;\n    min-height: 1872px;\n    overflow-x: hidden;\n    background: var(--red);\n    font-family: 'DM Sans', sans-serif;\n  }\n\n  #app {\n    width: 624px;\n    min-height: 1872px;\n    background: linear-gradient(170deg, #FF1A1A 0%, #D40000 40%, #9B0000 100%);\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    justify-content: space-between;\n    padding: 64px 32px 72px;\n    position: relative;\n    overflow: hidden;\n  }\n\n  \/* Decorative background circles *\/\n  #app::before {\n    content: '';\n    position: absolute;\n    top: -120px;\n    right: -120px;\n    width: 400px;\n    height: 400px;\n    border-radius: 50%;\n    background: rgba(255,255,255,0.04);\n    pointer-events: none;\n  }\n  #app::after {\n    content: '';\n    position: absolute;\n    bottom: 200px;\n    left: -150px;\n    width: 500px;\n    height: 500px;\n    border-radius: 50%;\n    background: rgba(0,0,0,0.06);\n    pointer-events: none;\n  }\n\n  \/* \u2500\u2500 HEADER \u2500\u2500 *\/\n  .header {\n    text-align: center;\n    color: #fff;\n    z-index: 1;\n    width: 100%;\n  }\n  .header .eyebrow {\n    font-size: 16px;\n    font-weight: 500;\n    letter-spacing: 4px;\n    text-transform: uppercase;\n    opacity: 0.7;\n    margin-bottom: 12px;\n  }\n  .header h1 {\n    font-size: 72px;\n    font-weight: 900;\n    line-height: 0.95;\n    letter-spacing: -2px;\n    text-transform: uppercase;\n    color: #fff;\n  }\n  .header h1 span {\n    color: var(--gold);\n    display: block;\n  }\n  .header .subtitle {\n    font-size: 20px;\n    font-weight: 400;\n    opacity: 0.8;\n    margin-top: 16px;\n  }\n\n  \/* \u2500\u2500 WHEEL AREA \u2500\u2500 *\/\n  .wheel-section {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    width: 100%;\n    z-index: 1;\n    gap: 0;\n  }\n\n  .pointer-wrap {\n    position: relative;\n    width: 560px;\n    display: flex;\n    justify-content: center;\n  }\n  .pointer {\n    width: 0;\n    height: 0;\n    border-left: 22px solid transparent;\n    border-right: 22px solid transparent;\n    border-top: 48px solid var(--gold);\n    filter: drop-shadow(0 4px 8px rgba(0,0,0,0.5));\n    position: relative;\n    z-index: 5;\n    margin-bottom: -4px;\n  }\n  .pointer::after {\n    content: '';\n    position: absolute;\n    top: -54px;\n    left: -14px;\n    width: 28px;\n    height: 28px;\n    background: var(--gold);\n    border-radius: 50%;\n  }\n\n  canvas#wheel {\n    display: block;\n    border-radius: 50%;\n    box-shadow:\n      0 0 0 6px rgba(255,255,255,0.15),\n      0 0 0 12px rgba(255,255,255,0.06),\n      0 20px 80px rgba(0,0,0,0.6);\n  }\n\n  \/* \u2500\u2500 RESULT BOX \u2500\u2500 *\/\n  .result-area {\n    width: 100%;\n    max-width: 560px;\n    z-index: 1;\n  }\n\n  .result-box {\n    background: #fff;\n    border-radius: 24px;\n    padding: 36px 40px;\n    text-align: center;\n    min-height: 148px;\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    justify-content: center;\n    box-shadow: 0 12px 60px rgba(0,0,0,0.3);\n    position: relative;\n    overflow: hidden;\n    transition: transform 0.3s ease;\n  }\n  .result-box.winner {\n    animation: popIn 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);\n  }\n  @keyframes popIn {\n    0% { transform: scale(0.9); }\n    60% { transform: scale(1.04); }\n    100% { transform: scale(1); }\n  }\n\n  .result-idle {\n    font-size: 22px;\n    color: #aaa;\n    font-weight: 500;\n  }\n  .result-label {\n    font-size: 14px;\n    color: #aaa;\n    font-weight: 600;\n    letter-spacing: 3px;\n    text-transform: uppercase;\n    display: none;\n    margin-bottom: 10px;\n  }\n  .result-prize {\n    font-size: 52px;\n    font-weight: 900;\n    color: var(--red);\n    line-height: 1;\n    letter-spacing: -1px;\n    display: none;\n  }\n  .result-spinning {\n    font-size: 22px;\n    color: var(--red);\n    font-weight: 700;\n    display: none;\n    align-items: center;\n    gap: 10px;\n  }\n  .spinner-dot {\n    width: 10px;\n    height: 10px;\n    background: var(--red);\n    border-radius: 50%;\n    animation: bounce 0.6s infinite alternate;\n  }\n  .spinner-dot:nth-child(2) { animation-delay: 0.15s; }\n  .spinner-dot:nth-child(3) { animation-delay: 0.3s; }\n  @keyframes bounce {\n    from { transform: translateY(0); opacity: 0.4; }\n    to { transform: translateY(-8px); opacity: 1; }\n  }\n\n  \/* \u2500\u2500 BUTTON \u2500\u2500 *\/\n  .btn-wrap {\n    width: 100%;\n    max-width: 560px;\n    z-index: 1;\n  }\n\n  #spin-btn {\n    width: 100%;\n    background: var(--gold);\n    color: #1a0a00;\n    border: none;\n    border-radius: 100px;\n    padding: 36px 0;\n    font-family: 'DM Sans', sans-serif;\n    font-size: 36px;\n    font-weight: 900;\n    letter-spacing: 2px;\n    text-transform: uppercase;\n    cursor: pointer;\n    box-shadow: 0 8px 40px rgba(0,0,0,0.35), inset 0 1px 0 rgba(255,255,255,0.3);\n    transition: transform 0.15s, box-shadow 0.15s, background 0.2s;\n    position: relative;\n    overflow: hidden;\n  }\n  #spin-btn::after {\n    content: '';\n    position: absolute;\n    top: 0; left: -100%;\n    width: 60%;\n    height: 100%;\n    background: linear-gradient(90deg, transparent, rgba(255,255,255,0.25), transparent);\n    transform: skewX(-20deg);\n    transition: left 0.5s ease;\n  }\n  #spin-btn:not(:disabled):hover::after {\n    left: 160%;\n  }\n  #spin-btn:not(:disabled):active {\n    transform: scale(0.97);\n    box-shadow: 0 4px 20px rgba(0,0,0,0.3);\n  }\n  #spin-btn:disabled {\n    opacity: 0.45;\n    cursor: not-allowed;\n  }\n\n  \/* \u2500\u2500 FOOTER \u2500\u2500 *\/\n  .footer {\n    color: rgba(255,255,255,0.4);\n    font-size: 14px;\n    z-index: 1;\n    text-align: center;\n  }\n<\/style>\n<\/head>\n<body>\n<div id=\"app\">\n\n  <div class=\"header\">\n    <p class=\"eyebrow\">El Palacio de la Oportunidad<\/p>\n    <h1>Gir\u00e1<span>y gan\u00e1<\/span><\/h1>\n    <p class=\"subtitle\">\u00a1Prob\u00e1 tu suerte con la ruleta!<\/p>\n  <\/div>\n\n  <div class=\"wheel-section\">\n    <div class=\"pointer-wrap\">\n      <div class=\"pointer\"><\/div>\n    <\/div>\n    <canvas id=\"wheel\" width=\"560\" height=\"560\"><\/canvas>\n  <\/div>\n\n  <div class=\"result-area\">\n    <div class=\"result-box\" id=\"result-box\">\n      <span class=\"result-idle\" id=\"result-idle\">Toc\u00e1 el bot\u00f3n para girar<\/span>\n      <div class=\"result-spinning\" id=\"result-spinning\">\n        <div class=\"spinner-dot\"><\/div>\n        <div class=\"spinner-dot\"><\/div>\n        <div class=\"spinner-dot\"><\/div>\n      <\/div>\n      <span class=\"result-label\" id=\"result-label\">\u00a1TU PREMIO!<\/span>\n      <span class=\"result-prize\" id=\"result-prize\"><\/span>\n    <\/div>\n  <\/div>\n\n  <div class=\"btn-wrap\">\n    <button id=\"spin-btn\">\u00a1 GIRAR !<\/button>\n  <\/div>\n\n  <p class=\"footer\">V\u00e1lido para clientes en local \u00b7 Sujeto a disponibilidad<\/p>\n\n<\/div>\n\n<script>\nconst prizes = [\n  { label: \"10% OFF\",           color: \"#FF3333\", text: \"#fff\" },\n  { label: \"Env\u00edo\\ngratis\",     color: \"#FFFFFF\", text: \"#D40000\" },\n  { label: \"Premio\\nsorpresa\",  color: \"#FFD700\", text: \"#5a3000\" },\n  { label: \"2\u00d71\\naccesorios\",   color: \"#CC0000\", text: \"#fff\" },\n  { label: \"Cup\u00f3n\\n$500\",       color: \"#FFF5CC\", text: \"#7a4400\" },\n  { label: \"\u00a1Sin\\npremio!\",     color: \"#DDDDDD\", text: \"#666\" },\n  { label: \"15% OFF\",           color: \"#FF3333\", text: \"#fff\" },\n  { label: \"Bolsa\\nregalo\",     color: \"#FFD700\", text: \"#5a3000\" },\n];\n\nconst canvas = document.getElementById('wheel');\nconst ctx = canvas.getContext('2d');\nconst N = prizes.length;\nconst arc = (2 * Math.PI) \/ N;\nconst cx = canvas.width \/ 2;\nconst cy = canvas.height \/ 2;\nconst R = cx - 6;\nlet currentAngle = -Math.PI \/ 2;\nlet spinning = false;\n\nfunction wrapText(ctx, text, x, y, maxWidth, lineHeight) {\n  const lines = text.split('\\n');\n  const totalH = (lines.length - 1) * lineHeight;\n  lines.forEach((line, i) => {\n    ctx.fillText(line, x, y - totalH \/ 2 + i * lineHeight);\n  });\n}\n\nfunction drawWheel(angle) {\n  ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n  \/\/ outer ring\n  ctx.beginPath();\n  ctx.arc(cx, cy, R + 6, 0, 2 * Math.PI);\n  ctx.fillStyle = 'rgba(255,255,255,0.15)';\n  ctx.fill();\n\n  for (let i = 0; i < N; i++) {\n    const start = angle + i * arc;\n    const end = start + arc;\n\n    \/\/ sector fill\n    ctx.beginPath();\n    ctx.moveTo(cx, cy);\n    ctx.arc(cx, cy, R, start, end);\n    ctx.closePath();\n    ctx.fillStyle = prizes[i].color;\n    ctx.fill();\n\n    \/\/ sector border\n    ctx.strokeStyle = 'rgba(0,0,0,0.18)';\n    ctx.lineWidth = 2;\n    ctx.stroke();\n\n    \/\/ text\n    ctx.save();\n    ctx.translate(cx, cy);\n    ctx.rotate(start + arc \/ 2);\n    ctx.textAlign = 'right';\n    ctx.fillStyle = prizes[i].text;\n    ctx.font = 'bold 18px \"DM Sans\", sans-serif';\n\n    const lines = prizes[i].label.split('\\n');\n    const lh = 22;\n    const totalH = (lines.length - 1) * lh;\n    lines.forEach((line, li) => {\n      ctx.fillText(line, R - 18, -totalH \/ 2 + li * lh + 6);\n    });\n    ctx.restore();\n  }\n\n  \/\/ center hub\n  const hubR = 36;\n  ctx.beginPath();\n  ctx.arc(cx, cy, hubR, 0, 2 * Math.PI);\n  ctx.fillStyle = '#fff';\n  ctx.fill();\n  ctx.strokeStyle = 'rgba(0,0,0,0.15)';\n  ctx.lineWidth = 3;\n  ctx.stroke();\n\n  \/\/ center star\n  ctx.save();\n  ctx.translate(cx, cy);\n  drawStar(ctx, 0, 0, 5, 14, 7);\n  ctx.fillStyle = '#F40000';\n  ctx.fill();\n  ctx.restore();\n}\n\nfunction drawStar(ctx, cx, cy, spikes, outerR, innerR) {\n  let rot = (Math.PI \/ 2) * 3;\n  const step = Math.PI \/ spikes;\n  ctx.beginPath();\n  ctx.moveTo(cx, cy - outerR);\n  for (let i = 0; i < spikes; i++) {\n    ctx.lineTo(cx + Math.cos(rot) * outerR, cy + Math.sin(rot) * outerR);\n    rot += step;\n    ctx.lineTo(cx + Math.cos(rot) * innerR, cy + Math.sin(rot) * innerR);\n    rot += step;\n  }\n  ctx.lineTo(cx, cy - outerR);\n  ctx.closePath();\n}\n\ndrawWheel(currentAngle);\n\nfunction easeOut(t) {\n  return 1 - Math.pow(1 - t, 5);\n}\n\nfunction spin() {\n  if (spinning) return;\n  spinning = true;\n  document.getElementById('spin-btn').disabled = true;\n\n  \/\/ UI: mostrar spinning\n  document.getElementById('result-idle').style.display = 'none';\n  document.getElementById('result-label').style.display = 'none';\n  document.getElementById('result-prize').style.display = 'none';\n  document.getElementById('result-spinning').style.display = 'flex';\n  document.getElementById('result-box').classList.remove('winner');\n\n  const winner = Math.floor(Math.random() * N);\n\n  \/\/ \u00c1ngulo objetivo: pointer apunta al sector ganador\n  \/\/ El pointer est\u00e1 arriba (\u2212\u03c0\/2). Cada sector ocupa `arc` radianes.\n  \/\/ Queremos que el centro del sector `winner` quede en \u2212\u03c0\/2.\n  const winnerMidAngle = winner * arc;\n  const targetOffset = -Math.PI \/ 2 - winnerMidAngle - arc \/ 2;\n  const fullSpins = (6 + Math.random() * 4) * 2 * Math.PI;\n  const start = currentAngle;\n  const normalizedStart = ((start % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI);\n  const target = start + fullSpins + ((targetOffset - normalizedStart + 4 * Math.PI) % (2 * Math.PI));\n\n  const duration = 5000 + Math.random() * 1500;\n  const startTime = performance.now();\n\n  function animate(now) {\n    const elapsed = now - startTime;\n    const t = Math.min(elapsed \/ duration, 1);\n    currentAngle = start + (target - start) * easeOut(t);\n    drawWheel(currentAngle);\n\n    if (t < 1) {\n      requestAnimationFrame(animate);\n    } else {\n      currentAngle = target;\n      spinning = false;\n      document.getElementById('spin-btn').disabled = false;\n\n      document.getElementById('result-spinning').style.display = 'none';\n      document.getElementById('result-label').style.display = 'block';\n      document.getElementById('result-prize').style.display = 'block';\n      document.getElementById('result-prize').textContent = prizes[winner].label.replace('\\n', ' ');\n      document.getElementById('result-box').classList.add('winner');\n    }\n  }\n\n  requestAnimationFrame(animate);\n}\n\ndocument.getElementById('spin-btn').addEventListener('click', spin);\n\n\/\/ Teclado: Enter, Espacio, OK (tecla 13\/32) y tambi\u00e9n \"5\" del control remoto\ndocument.addEventListener('keydown', function(e) {\n  if (e.key === 'Enter' || e.key === ' ' || e.key === '5' || e.keyCode === 13 || e.keyCode === 32) {\n    e.preventDefault();\n    spin();\n  }\n});\n<\/script>\n<\/body>\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Ruleta de Premios &#8211; El Palacio El Palacio de la Oportunidad Gir\u00e1y gan\u00e1 \u00a1Prob\u00e1 tu suerte con la ruleta! Toc\u00e1 el bot\u00f3n para girar \u00a1TU PREMIO! \u00a1 GIRAR ! V\u00e1lido para clientes en local \u00b7 Sujeto a disponibilidad<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-103","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/elpalaciodelaoportunidad.com\/palacio\/wp-json\/wp\/v2\/pages\/103","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/elpalaciodelaoportunidad.com\/palacio\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/elpalaciodelaoportunidad.com\/palacio\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/elpalaciodelaoportunidad.com\/palacio\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/elpalaciodelaoportunidad.com\/palacio\/wp-json\/wp\/v2\/comments?post=103"}],"version-history":[{"count":8,"href":"https:\/\/elpalaciodelaoportunidad.com\/palacio\/wp-json\/wp\/v2\/pages\/103\/revisions"}],"predecessor-version":[{"id":136,"href":"https:\/\/elpalaciodelaoportunidad.com\/palacio\/wp-json\/wp\/v2\/pages\/103\/revisions\/136"}],"wp:attachment":[{"href":"https:\/\/elpalaciodelaoportunidad.com\/palacio\/wp-json\/wp\/v2\/media?parent=103"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}