匿名
未登录
中文(中国大陆)
登录
Limbo Wiki Mirror
搜索
查看“︁微件:GGLScratchGame”︁的源代码
来自Limbo Wiki Mirror
命名空间
微件
讨论
更多
更多
页面操作
阅读
查看源代码
历史
←
微件:GGLScratchGame
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您没有权限编辑
微件
命名空间内的页面。
您可以查看和复制此页面的源代码。
<div class="scratch-lottery-root" data-config=""> <div class="sl-debug"></div> <div class="sl-header"> <div class="sl-info"> <span class="sl-ticket-count"></span> <span class="sl-ticket-index"></span> </div> <button class="sl-open-btn">来一张彩票</button> </div> <div class="sl-stage"> <div class="sl-canvas"> <img class="sl-bg" /> <div class="sl-area"></div> </div> </div> <div class="sl-controls"> <button class="sl-mascot">(◕‿◕) …</button> <button class="sl-scan">扫描结果</button> </div> </div> <style> .scratch-lottery-root { max-width: 520px; margin: 2em auto; font-family: system-ui, sans-serif; user-select: none; } .sl-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: .5em; } .sl-open-btn { padding: .4em .8em; } .sl-stage { position: relative; } .sl-canvas { position: relative; width: 100%; } .sl-bg { width: 100%; display: block; } .sl-area { position: absolute; } .sl-tile { position: absolute; width: 169px; height: 169px; cursor: pointer; outline: none; } .sl-cover img, .sl-reveal img { width: 100%; height: 100%; object-fit: cover; } .sl-bubble { position: absolute; background: #fff; border: 1px solid #000; padding: .4em .6em; font-size: 13px; z-index: 50; } .sl-controls { display: flex; margin-top: .5em; } .sl-controls button { flex: 1; padding: .6em; } .sl-scan.highlight { background: #ffe600; animation: pulse 1s infinite; } @keyframes pulse { from { box-shadow: 0 0 0 rgba(255,230,0,.8); } to { box-shadow: 0 0 12px rgba(255,230,0,0); } } .sl-invert { filter: invert(1) hue-rotate(180deg); } .sl-debug { font-size: 11px; color: #666; margin-bottom: .5em; } </style> <script> (function () { const root = document.currentScript.parentElement; const cfg = JSON.parse(root.dataset.config || '{}'); const bg = root.querySelector('.sl-bg'); const area = root.querySelector('.sl-area'); const mascot = root.querySelector('.sl-mascot'); const scanBtn = root.querySelector('.sl-scan'); const openBtn = root.querySelector('.sl-open-btn'); const debugBox = root.querySelector('.sl-debug'); const tickets = cfg.tickets || []; const states = cfg.states || {}; let ticketIndex = 0; let playerTickets = cfg.initialTickets || 3; let currentTicket = null; let revealed = new Set(); bg.src = cfg.config.bg; function layout() { const scale = bg.clientWidth / 1075; area.style.left = (cfg.config.area.x * scale) + 'px'; area.style.top = (cfg.config.area.y * scale) + 'px'; area.style.width = (cfg.config.area.width * scale) + 'px'; area.style.height = (cfg.config.area.height * scale) + 'px'; } bg.onload = layout; window.addEventListener('resize', layout); function updateInfo() { root.querySelector('.sl-ticket-count').textContent = '🎟️ 票数:' + playerTickets; root.querySelector('.sl-ticket-index').textContent = currentTicket ? '当前票:' + currentTicket.id : '当前票:-'; if (cfg.debug) { debugBox.textContent = 'ticketIndex=' + ticketIndex + ' revealed=' + revealed.size + ' playerTickets=' + playerTickets; } } function openTicket() { if (playerTickets <= 0 || ticketIndex >= tickets.length) return; currentTicket = tickets[ticketIndex++]; playerTickets--; revealed.clear(); scanBtn.classList.remove('highlight'); mascot.style.visibility = 'visible'; renderTiles(); updateInfo(); } function renderTiles() { area.innerHTML = ''; currentTicket.outcomes.forEach((stateId, i) => { const tile = document.createElement('div'); tile.className = 'sl-tile'; tile.tabIndex = 0; tile.setAttribute('aria-label', '刮奖格子 ' + (i + 1)); const col = i % cfg.config.cols; const row = Math.floor(i / cfg.config.cols); tile.style.left = (col * cfg.config.tileSize) + 'px'; tile.style.top = (row * cfg.config.tileSize) + 'px'; const cover = document.createElement('div'); cover.className = 'sl-cover'; const coverImg = document.createElement('img'); coverImg.src = cfg.config.cover; cover.appendChild(coverImg); tile.appendChild(cover); tile.onclick = () => revealTile(i, tile); tile.onkeydown = e => { if (e.key === 'Enter' || e.key === ' ') revealTile(i, tile); }; area.appendChild(tile); }); } function revealTile(i, tile) { if (revealed.has(i)) return; revealed.add(i); tile.innerHTML = ''; const reveal = document.createElement('div'); reveal.className = 'sl-reveal'; const img = document.createElement('img'); img.src = cfg.config.reveal; reveal.appendChild(img); tile.appendChild(reveal); const state = states[currentTicket.outcomes[i]]; showBubble(tile, state?.text || ''); handleState(currentTicket.outcomes[i]); checkCompletion(); } function showBubble(tile, text) { if (!text) return; const bubble = document.createElement('div'); bubble.className = 'sl-bubble'; bubble.textContent = text; tile.appendChild(bubble); const rect = tile.getBoundingClientRect(); bubble.style.top = rect.bottom > window.innerHeight - 80 ? '-2.4em' : '100%'; bubble.style.left = '0'; setTimeout(() => bubble.remove(), 3000); } function handleState(id) { const s = states[id]; if (!s) return; if (s.type === 'emoji') mascot.textContent = s.text; if (id === 6) mascot.style.visibility = 'hidden'; if (id === 10) scanBtn.classList.add('highlight'); if (id === 11) endGame(); } function checkCompletion() { if (revealed.size === 30 && currentTicket.id === 10) { scanBtn.classList.add('highlight'); } } function endGame() { root.classList.add('sl-invert'); setTimeout(() => { root.style.display = 'none'; location.hash = '#词条正文'; }, 1500); } openBtn.onclick = openTicket; scanBtn.onclick = () => { if (currentTicket && currentTicket.id === 10) openTicket(); }; updateInfo(); })(); </script>
返回
微件:GGLScratchGame
。
导航
导航
首页
最近更改
随机页面
操作申请
帮助
入门指南
编辑指南
写作指南
随机
官方
碎数研
谜题保管所
wiki工具
wiki工具
特殊页面
页面工具
页面工具
用户页面工具
更多
链入页面
相关更改
页面信息
页面日志