{"product_id":"3d-stamp-generator","title":"3D 立體字印章產生器","description":"\u003ciframe srcdoc=\"\u0026lt;!DOCTYPE html\u0026gt;\n\u0026lt;html lang=\u0026quot;zh-Hant\u0026quot;\u0026gt;\n\u0026lt;head\u0026gt;\n\u0026lt;meta charset=\u0026quot;UTF-8\u0026quot;\u0026gt;\n\u0026lt;meta name=\u0026quot;viewport\u0026quot; content=\u0026quot;width=device-width, initial-scale=1.0\u0026quot;\u0026gt;\n\u0026lt;link rel=\u0026quot;preconnect\u0026quot; href=\u0026quot;https:\/\/fonts.googleapis.com\u0026quot;\u0026gt;\n\u0026lt;link rel=\u0026quot;preconnect\u0026quot; href=\u0026quot;https:\/\/fonts.gstatic.com\u0026quot; crossorigin\u0026gt;\n\u0026lt;link href=\u0026quot;https:\/\/fonts.googleapis.com\/css2?family=Ma+Shan+Zheng\u0026amp;family=Noto+Serif+SC:wght@700\u0026amp;display=swap\u0026quot; rel=\u0026quot;stylesheet\u0026quot;\u0026gt;\n\u0026lt;style\u0026gt;\n  @font-face {\n    font-family: 'ChongXiSeal';\n    src: url('https:\/\/cdn.jsdelivr.net\/gh\/gb5hk5swkx-collab\/WKidea@main\/chongxi_seal.otf') format('opentype');\n    font-display: swap;\n  }\n  * { box-sizing: border-box; margin: 0; padding: 0; }\n  body { font-family: \u0026quot;PingFang TC\u0026quot;, \u0026quot;Microsoft JhengHei\u0026quot;, sans-serif; background: #f5f0ea; color: #2d2016; }\n  #app { width: 100%; max-width: 640px; margin: 0 auto; padding: 28px 24px 32px; }\n  .wk-header { text-align: center; margin-bottom: 24px; padding-bottom: 20px; border-bottom: 1px solid #e0d4c4; }\n  .wk-header h2 { font-size: 22px; font-weight: 700; color: #2d2016; letter-spacing: 2px; margin-bottom: 6px; }\n  .wk-header p { font-size: 13px; color: #9a8b7d; letter-spacing: 1px; }\n  .wk-section { background: #fff; border-radius: 12px; padding: 20px; margin-bottom: 14px; box-shadow: 0 2px 10px rgba(45,32,22,0.06); }\n  .wk-group { margin-bottom: 14px; }\n  .wk-group:last-child { margin-bottom: 0; }\n  .wk-group label { display: block; font-size: 12px; font-weight: 700; letter-spacing: 1.5px; color: #9a8b7d; text-transform: uppercase; margin-bottom: 8px; }\n  .wk-input, .wk-select { width: 100%; padding: 12px 14px; border: 1.5px solid #e0d4c4; border-radius: 8px; font-size: 16px; background: #faf8f5; color: #2d2016; outline: none; transition: border-color .2s; }\n  .wk-input:focus, .wk-select:focus { border-color: #b5341a; }\n  .wk-range { width: 100%; accent-color: #b5341a; margin-top: 4px; }\n  .wk-row { display: flex; gap: 12px; }\n  .wk-row .wk-group { flex: 1; }\n  .wk-seg { display: flex; border: 1.5px solid #e0d4c4; border-radius: 8px; overflow: hidden; background: #faf8f5; }\n  .wk-seg button { flex: 1; padding: 10px 6px; border: none; background: transparent; font-size: 13px; color: #9a8b7d; cursor: pointer; transition: all .2s; font-weight: 500; }\n  .wk-seg button.active { background: #b5341a; color: #fff; font-weight: 700; }\n  .wk-color-row { display: flex; gap: 10px; flex-wrap: wrap; }\n  .wk-color-btn { width: 32px; height: 32px; border-radius: 50%; border: 3px solid transparent; cursor: pointer; transition: border-color .2s; }\n  .wk-color-btn.active { border-color: #2d2016; }\n  #canvas-wrap { background: #fff; border-radius: 12px; padding: 24px; margin-bottom: 14px; box-shadow: 0 2px 10px rgba(45,32,22,0.06); display: flex; justify-content: center; align-items: center; min-height: 200px; }\n  #stampCanvas { max-width: 100%; height: auto; }\n  .wk-btn { background: #2d2016; color: #f5ede4; border: none; padding: 14px; font-size: 15px; font-weight: 700; letter-spacing: 1px; border-radius: 8px; cursor: pointer; width: 100%; transition: background .25s; margin-bottom: 8px; }\n  .wk-btn:hover { background: #1a1008; }\n  .wk-hint { font-size: 12px; color: #9a8b7d; text-align: center; min-height: 16px; margin-bottom: 4px; }\n  .wk-note { font-size: 11px; color: #b3a596; text-align: center; line-height: 1.6; padding: 0 8px; margin-bottom: 14px; }\n  .wk-cta { border-radius: 12px; background: linear-gradient(135deg, #2d2016 0%, #4a3020 100%); color: #f5ede4; padding: 24px 20px; text-align: center; }\n  .wk-cta-label { font-size: 11px; letter-spacing: 2px; color: #c47a2b; font-weight: 700; margin-bottom: 8px; text-transform: uppercase; }\n  .wk-cta-title { font-size: 18px; font-weight: 700; margin-bottom: 6px; letter-spacing: 1px; }\n  .wk-cta-sub { font-size: 13px; opacity: .8; margin-bottom: 18px; line-height: 1.6; }\n  .wk-cta-actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }\n  .wk-cta-btn { display: inline-block; background: #00b900; color: #fff; text-decoration: none; padding: 11px 22px; border-radius: 24px; font-weight: 700; font-size: 14px; transition: background .2s; }\n  .wk-cta-btn:hover { background: #009900; }\n  .wk-cta-btn.secondary { background: transparent; border: 1.5px solid rgba(245,237,228,0.5); color: #f5ede4; }\n  .wk-cta-btn.secondary:hover { background: rgba(255,255,255,0.1); }\n\u0026lt;\/style\u0026gt;\n\u0026lt;\/head\u0026gt;\n\u0026lt;body\u0026gt;\n\u0026lt;div id=\u0026quot;app\u0026quot;\u0026gt;\n  \u0026lt;div class=\u0026quot;wk-header\u0026quot;\u0026gt;\n    \u0026lt;h2\u0026gt;3D 立體字印章・即時預覽\u0026lt;\/h2\u0026gt;\n    \u0026lt;p\u0026gt;輸入文字，秒速生成浮雕立體印章效果\u0026lt;\/p\u0026gt;\n  \u0026lt;\/div\u0026gt;\n  \u0026lt;div class=\u0026quot;wk-section\u0026quot;\u0026gt;\n    \u0026lt;div class=\u0026quot;wk-group\u0026quot;\u0026gt;\n      \u0026lt;label for=\u0026quot;stampText\u0026quot;\u0026gt;印章文字（1～4 字）\u0026lt;\/label\u0026gt;\n      \u0026lt;input type=\u0026quot;text\u0026quot; id=\u0026quot;stampText\u0026quot; class=\u0026quot;wk-input\u0026quot; value=\u0026quot;王大明\u0026quot; maxlength=\u0026quot;4\u0026quot; placeholder=\u0026quot;輸入姓名或文字\u0026quot;\u0026gt;\n    \u0026lt;\/div\u0026gt;\n    \u0026lt;div class=\u0026quot;wk-row\u0026quot;\u0026gt;\n      \u0026lt;div class=\u0026quot;wk-group\u0026quot;\u0026gt;\n        \u0026lt;label for=\u0026quot;stampShape\u0026quot;\u0026gt;形狀\u0026lt;\/label\u0026gt;\n        \u0026lt;select id=\u0026quot;stampShape\u0026quot; class=\u0026quot;wk-select\u0026quot;\u0026gt;\n          \u0026lt;option value=\u0026quot;square\u0026quot;\u0026gt;方章\u0026lt;\/option\u0026gt;\n          \u0026lt;option value=\u0026quot;circle\u0026quot;\u0026gt;圓章\u0026lt;\/option\u0026gt;\n        \u0026lt;\/select\u0026gt;\n      \u0026lt;\/div\u0026gt;\n      \u0026lt;div class=\u0026quot;wk-group\u0026quot;\u0026gt;\n        \u0026lt;label for=\u0026quot;stampFont\u0026quot;\u0026gt;字體\u0026lt;\/label\u0026gt;\n        \u0026lt;select id=\u0026quot;stampFont\u0026quot; class=\u0026quot;wk-select\u0026quot;\u0026gt;\n          \u0026lt;option value=\u0026quot;seal\u0026quot;\u0026gt;篆書（崇羲）\u0026lt;\/option\u0026gt;\n          \u0026lt;option value=\u0026quot;kaishu\u0026quot;\u0026gt;毛筆楷書\u0026lt;\/option\u0026gt;\n          \u0026lt;option value=\u0026quot;mingti\u0026quot;\u0026gt;明體（正式）\u0026lt;\/option\u0026gt;\n        \u0026lt;\/select\u0026gt;\n      \u0026lt;\/div\u0026gt;\n    \u0026lt;\/div\u0026gt;\n    \u0026lt;div class=\u0026quot;wk-group\u0026quot;\u0026gt;\n      \u0026lt;label\u0026gt;印章顏色\u0026lt;\/label\u0026gt;\n      \u0026lt;div class=\u0026quot;wk-color-row\u0026quot; id=\u0026quot;colorPicker\u0026quot;\u0026gt;\n        \u0026lt;div class=\u0026quot;wk-color-btn active\u0026quot; data-color=\u0026quot;#b5341a\u0026quot; style=\u0026quot;background:#b5341a\u0026quot;\u0026gt;\u0026lt;\/div\u0026gt;\n        \u0026lt;div class=\u0026quot;wk-color-btn\u0026quot; data-color=\u0026quot;#2d2016\u0026quot; style=\u0026quot;background:#2d2016\u0026quot;\u0026gt;\u0026lt;\/div\u0026gt;\n        \u0026lt;div class=\u0026quot;wk-color-btn\u0026quot; data-color=\u0026quot;#1a4a2e\u0026quot; style=\u0026quot;background:#1a4a2e\u0026quot;\u0026gt;\u0026lt;\/div\u0026gt;\n        \u0026lt;div class=\u0026quot;wk-color-btn\u0026quot; data-color=\u0026quot;#1a2a4a\u0026quot; style=\u0026quot;background:#1a2a4a\u0026quot;\u0026gt;\u0026lt;\/div\u0026gt;\n        \u0026lt;div class=\u0026quot;wk-color-btn\u0026quot; data-color=\u0026quot;#8B4513\u0026quot; style=\u0026quot;background:#8B4513\u0026quot;\u0026gt;\u0026lt;\/div\u0026gt;\n        \u0026lt;div class=\u0026quot;wk-color-btn\u0026quot; data-color=\u0026quot;#4a4a4a\u0026quot; style=\u0026quot;background:#4a4a4a\u0026quot;\u0026gt;\u0026lt;\/div\u0026gt;\n      \u0026lt;\/div\u0026gt;\n    \u0026lt;\/div\u0026gt;\n    \u0026lt;div class=\u0026quot;wk-group\u0026quot;\u0026gt;\n      \u0026lt;label for=\u0026quot;depthSlider\u0026quot;\u0026gt;立體深度\u0026lt;\/label\u0026gt;\n      \u0026lt;input type=\u0026quot;range\u0026quot; id=\u0026quot;depthSlider\u0026quot; class=\u0026quot;wk-range\u0026quot; min=\u0026quot;2\u0026quot; max=\u0026quot;16\u0026quot; value=\u0026quot;8\u0026quot;\u0026gt;\n    \u0026lt;\/div\u0026gt;\n    \u0026lt;div class=\u0026quot;wk-group\u0026quot;\u0026gt;\n      \u0026lt;label for=\u0026quot;sizeSlider\u0026quot;\u0026gt;尺寸\u0026lt;\/label\u0026gt;\n      \u0026lt;input type=\u0026quot;range\u0026quot; id=\u0026quot;sizeSlider\u0026quot; class=\u0026quot;wk-range\u0026quot; min=\u0026quot;180\u0026quot; max=\u0026quot;300\u0026quot; value=\u0026quot;260\u0026quot;\u0026gt;\n    \u0026lt;\/div\u0026gt;\n    \u0026lt;div class=\u0026quot;wk-group\u0026quot;\u0026gt;\n      \u0026lt;label for=\u0026quot;borderWidth\u0026quot;\u0026gt;線框厚度\u0026lt;\/label\u0026gt;\n      \u0026lt;input type=\u0026quot;range\u0026quot; id=\u0026quot;borderWidth\u0026quot; class=\u0026quot;wk-range\u0026quot; min=\u0026quot;1\u0026quot; max=\u0026quot;20\u0026quot; value=\u0026quot;8\u0026quot;\u0026gt;\n    \u0026lt;\/div\u0026gt;\n    \u0026lt;div class=\u0026quot;wk-group\u0026quot;\u0026gt;\n      \u0026lt;label\u0026gt;背景\u0026lt;\/label\u0026gt;\n      \u0026lt;div class=\u0026quot;wk-seg\u0026quot; id=\u0026quot;segBg\u0026quot;\u0026gt;\n        \u0026lt;button data-v=\u0026quot;transparent\u0026quot; class=\u0026quot;active\u0026quot;\u0026gt;透明\u0026lt;\/button\u0026gt;\n        \u0026lt;button data-v=\u0026quot;white\u0026quot;\u0026gt;白底\u0026lt;\/button\u0026gt;\n        \u0026lt;button data-v=\u0026quot;cream\u0026quot;\u0026gt;奶油底\u0026lt;\/button\u0026gt;\n      \u0026lt;\/div\u0026gt;\n    \u0026lt;\/div\u0026gt;\n  \u0026lt;\/div\u0026gt;\n  \u0026lt;div id=\u0026quot;canvas-wrap\u0026quot;\u0026gt;\n    \u0026lt;canvas id=\u0026quot;stampCanvas\u0026quot; width=\u0026quot;400\u0026quot; height=\u0026quot;400\u0026quot;\u0026gt;\u0026lt;\/canvas\u0026gt;\n  \u0026lt;\/div\u0026gt;\n  \u0026lt;button class=\u0026quot;wk-btn\u0026quot; onclick=\u0026quot;downloadStamp()\u0026quot;\u0026gt;下載去背 PNG 圖檔\u0026lt;\/button\u0026gt;\n  \u0026lt;p class=\u0026quot;wk-hint\u0026quot; id=\u0026quot;wkHint\u0026quot;\u0026gt;\u0026lt;\/p\u0026gt;\n  \u0026lt;p class=\u0026quot;wk-note\u0026quot;\u0026gt;此工具為預覽用途，實際手工印章成品將由 WKidea 職人依材質特性調整。\u0026lt;\/p\u0026gt;\n  \u0026lt;div class=\u0026quot;wk-cta\u0026quot;\u0026gt;\n    \u0026lt;p class=\u0026quot;wk-cta-label\u0026quot;\u0026gt;WKidea 職人訂製\u0026lt;\/p\u0026gt;\n    \u0026lt;p class=\u0026quot;wk-cta-title\u0026quot;\u0026gt;想要一枚真正的 3D 立體印章？\u0026lt;\/p\u0026gt;\n    \u0026lt;p class=\u0026quot;wk-cta-sub\u0026quot;\u0026gt;由 WKidea 職人親手刻製，選用台灣原木・獨一無二的專屬印章\u0026lt;\/p\u0026gt;\n    \u0026lt;div class=\u0026quot;wk-cta-actions\u0026quot;\u0026gt;\n      \u0026lt;a class=\u0026quot;wk-cta-btn\u0026quot; href=\u0026quot;https:\/\/line.me\/R\/ti\/p\/@wkidea\u0026quot; target=\u0026quot;_blank\u0026quot; rel=\u0026quot;noopener\u0026quot;\u0026gt;立即諮詢訂製\u0026lt;\/a\u0026gt;\n      \u0026lt;a class=\u0026quot;wk-cta-btn secondary\u0026quot; href=\u0026quot;https:\/\/www.wkidea.com\u0026quot; target=\u0026quot;_blank\u0026quot; rel=\u0026quot;noopener\u0026quot;\u0026gt;探索更多木作\u0026lt;\/a\u0026gt;\n    \u0026lt;\/div\u0026gt;\n  \u0026lt;\/div\u0026gt;\n\u0026lt;\/div\u0026gt;\n\u0026lt;script\u0026gt;\n  const canvas = document.getElementById('stampCanvas');\n  const ctx = canvas.getContext('2d');\n  const textInput = document.getElementById('stampText');\n  const shapeInput = document.getElementById('stampShape');\n  const fontInput = document.getElementById('stampFont');\n  const depthInput = document.getElementById('depthSlider');\n  const sizeInput = document.getElementById('sizeSlider');\n  const borderInput = document.getElementById('borderWidth');\n  const hint = document.getElementById('wkHint');\n\n  const FONTS = {\n    seal: 'ChongXiSeal, serif',\n    kaishu: '\u0026quot;Ma Shan Zheng\u0026quot;, serif',\n    mingti: '\u0026quot;Noto Serif SC\u0026quot;, serif'\n  };\n\n  let stampColor = '#b5341a';\n  let bgMode = 'transparent';\n\n  \/\/ Color picker\n  document.getElementById('colorPicker').querySelectorAll('.wk-color-btn').forEach(btn =\u0026gt; {\n    btn.addEventListener('click', () =\u0026gt; {\n      document.querySelectorAll('.wk-color-btn').forEach(b =\u0026gt; b.classList.remove('active'));\n      btn.classList.add('active');\n      stampColor = btn.dataset.color;\n      drawStamp();\n    });\n  });\n\n  \/\/ Background seg\n  function bindSeg(id, cb) {\n    document.getElementById(id).querySelectorAll('button').forEach(btn =\u0026gt; {\n      btn.addEventListener('click', () =\u0026gt; {\n        document.getElementById(id).querySelectorAll('button').forEach(b =\u0026gt; b.classList.remove('active'));\n        btn.classList.add('active');\n        cb(btn.dataset.v);\n        drawStamp();\n      });\n    });\n  }\n  bindSeg('segBg', v =\u0026gt; bgMode = v);\n\n  textInput.addEventListener('input', drawStamp);\n  shapeInput.addEventListener('change', drawStamp);\n  fontInput.addEventListener('change', drawStamp);\n  depthInput.addEventListener('input', drawStamp);\n  sizeInput.addEventListener('input', drawStamp);\n  borderInput.addEventListener('input', drawStamp);\n\n  function hexToRgb(hex) {\n    const r = parseInt(hex.slice(1,3),16);\n    const g = parseInt(hex.slice(3,5),16);\n    const b = parseInt(hex.slice(5,7),16);\n    return {r,g,b};\n  }\n\n  function darken(hex, factor) {\n    const {r,g,b} = hexToRgb(hex);\n    return `rgb(${Math.floor(r*factor)},${Math.floor(g*factor)},${Math.floor(b*factor)})`;\n  }\n\n  function lighten(hex, factor) {\n    const {r,g,b} = hexToRgb(hex);\n    return `rgb(${Math.min(255,Math.floor(r+(255-r)*factor))},${Math.min(255,Math.floor(g+(255-g)*factor))},${Math.min(255,Math.floor(b+(255-b)*factor))})`;\n  }\n\n  function currentFont() { return FONTS[fontInput.value] || FONTS.seal; }\n\n  function layoutChars(chars, size, cx, cy, lw, drawFn) {\n    const n = chars.length;\n    const inner = (size - lw * 2) * 0.82;\n    ctx.textBaseline = 'middle';\n    ctx.textAlign = 'center';\n    if (n === 1) {\n      drawFn(chars[0], cx, cy, inner, inner);\n    } else if (n === 2) {\n      drawFn(chars[0], cx, cy - inner\/4, inner, inner\/2);\n      drawFn(chars[1], cx, cy + inner\/4, inner, inner\/2);\n    } else if (n === 3) {\n      const colW = inner\/2;\n      const rx = cx + colW\/2, lx = cx - colW\/2;\n      drawFn(chars[1], lx, cy - inner\/4, colW, inner\/2);\n      drawFn(chars[2], lx, cy + inner\/4, colW, inner\/2);\n      drawFn(chars[0], rx, cy, colW, inner * 0.95);\n    } else {\n      const colW = inner\/2, rowH = inner\/2;\n      const rx = cx + colW\/2, lx = cx - colW\/2;\n      drawFn(chars[0], rx, cy - rowH\/2, colW, rowH);\n      drawFn(chars[1], rx, cy + rowH\/2, colW, rowH);\n      drawFn(chars[2], lx, cy - rowH\/2, colW, rowH);\n      drawFn(chars[3], lx, cy + rowH\/2, colW, rowH);\n    }\n  }\n\n  function roundRectPath(x, y, w, h, r) {\n    ctx.beginPath();\n    ctx.moveTo(x+r,y);\n    ctx.arcTo(x+w,y,x+w,y+h,r);\n    ctx.arcTo(x+w,y+h,x,y+h,r);\n    ctx.arcTo(x,y+h,x,y,r);\n    ctx.arcTo(x,y,x+w,y,r);\n    ctx.closePath();\n  }\n\n  function drawStamp() {\n    const text = textInput.value || '印';\n    const chars = [...text].slice(0,4);\n    const shape = shapeInput.value;\n    const size = parseInt(sizeInput.value);\n    const depth = parseInt(depthInput.value);\n    const lw = parseInt(borderInput.value);\n    const cx = canvas.width\/2, cy = canvas.height\/2;\n\n    ctx.clearRect(0,0,canvas.width,canvas.height);\n\n    \/\/ Background\n    if (bgMode === 'white') {\n      ctx.fillStyle = '#ffffff';\n      ctx.fillRect(0,0,canvas.width,canvas.height);\n    } else if (bgMode === 'cream') {\n      ctx.fillStyle = '#f5ede4';\n      ctx.fillRect(0,0,canvas.width,canvas.height);\n    }\n\n    const shadowColor = darken(stampColor, 0.45);\n    const faceColor = stampColor;\n    const highlightColor = lighten(stampColor, 0.35);\n\n    \/\/ --- Draw 3D shadow layers (bottom-right offset) ---\n    for (let i = depth; i \u0026gt;= 1; i--) {\n      const alpha = 0.15 + (depth - i) * (0.55 \/ depth);\n      ctx.save();\n      ctx.globalAlpha = alpha;\n      ctx.strokeStyle = shadowColor;\n      ctx.fillStyle = shadowColor;\n      ctx.lineWidth = lw;\n      const ox = i * 1.2, oy = i * 1.2;\n      if (shape === 'circle') {\n        ctx.beginPath();\n        ctx.arc(cx + ox, cy + oy, size\/2 - lw\/2, 0, Math.PI*2);\n        ctx.stroke();\n      } else {\n        roundRectPath(cx - size\/2 + lw\/2 + ox, cy - size\/2 + lw\/2 + oy, size - lw, size - lw, 10);\n        ctx.stroke();\n      }\n      \/\/ Shadow text layers\n      layoutChars(chars, size, cx + ox, cy + oy, lw, (ch, gx, gy, cw, ch2) =\u0026gt; {\n        const fs = Math.min(ch2 * 0.9, cw * 1.25);\n        ctx.font = `bold ${fs}px ${currentFont()}`;\n        ctx.fillText(ch, gx, gy);\n      });\n      ctx.restore();\n    }\n\n    \/\/ --- Draw face border ---\n    ctx.save();\n    ctx.strokeStyle = faceColor;\n    ctx.lineWidth = lw;\n    if (shape === 'circle') {\n      ctx.beginPath();\n      ctx.arc(cx, cy, size\/2 - lw\/2, 0, Math.PI*2);\n      ctx.stroke();\n    } else {\n      roundRectPath(cx - size\/2 + lw\/2, cy - size\/2 + lw\/2, size - lw, size - lw, 10);\n      ctx.stroke();\n    }\n    ctx.restore();\n\n    \/\/ --- Draw face text with gradient ---\n    layoutChars(chars, size, cx, cy, lw, (ch, gx, gy, cw, ch2) =\u0026gt; {\n      const fs = Math.min(ch2 * 0.9, cw * 1.25);\n      ctx.save();\n      const grad = ctx.createLinearGradient(gx, gy - ch2\/2, gx, gy + ch2\/2);\n      grad.addColorStop(0, highlightColor);\n      grad.addColorStop(0.4, faceColor);\n      grad.addColorStop(1, darken(stampColor, 0.6));\n      ctx.fillStyle = grad;\n      ctx.font = `bold ${fs}px ${currentFont()}`;\n      ctx.fillText(ch, gx, gy);\n      ctx.restore();\n    });\n  }\n\n  function downloadStamp() {\n    const dataURL = canvas.toDataURL('image\/png');\n    const isIOS = \/iPad|iPhone|iPod\/.test(navigator.userAgent);\n    if (isIOS) {\n      const w = window.open();\n      if (w) {\n        w.document.write('\u0026lt;img src=\u0026quot;'+dataURL+'\u0026quot; style=\u0026quot;max-width:100%\u0026quot;\u0026gt;');\n        hint.textContent = '長按上方圖片即可儲存到相簿';\n      } else {\n        hint.textContent = '請允許彈出視窗，或長按預覽圖儲存';\n      }\n      return;\n    }\n    const link = document.createElement('a');\n    link.download = 'wkidea-3d-stamp-' + (textInput.value||'stamp') + '.png';\n    link.href = dataURL;\n    document.body.appendChild(link);\n    link.click();\n    document.body.removeChild(link);\n  }\n\n  if (document.fonts \u0026amp;\u0026amp; document.fonts.ready) {\n    document.fonts.ready.then(drawStamp);\n  }\n  window.addEventListener('load', drawStamp);\n  drawStamp();\n\u0026lt;\/script\u0026gt;\n\u0026lt;\/body\u0026gt;\n\u0026lt;\/html\u0026gt;\n\" style=\"width:100vw;max-width:100vw;margin-left:calc(50% - 50vw);height:1020px;border:none;display:block;\" loading=\"lazy\"\u003e\u003c\/iframe\u003e","brand":"WKidea","offers":[{"title":"Default Title","offer_id":50008666177813,"sku":null,"price":0.0,"currency_code":"TWD","in_stock":false}],"url":"https:\/\/wkidea.com\/products\/3d-stamp-generator","provider":"WKidea","version":"1.0","type":"link"}