微件:GGLScratchGame

来自Limbo Wiki Mirror
Gaoice留言 | 贡献2026年2月1日 (日) 18:59的版本
 <img class="ggl-bg"
      src="180px-%E5%9B%BE%E7%89%871.png">
(^▽^)
   <button id="ggl-scan">扫描结果</button>

<style> .ggl-root {

 position: relative;
 width: 375px;
 margin: auto;
 aspect-ratio: 1075 / 1911;
 font-family: sans-serif;

}

.ggl-bg {

 width: 100%;
 display: block;

}

.ggl-scratch-area {

 position: absolute;
 left: 10%;
 top: 35%;
 width: 80%;
 height: 53%;

}

.ggl-grid {

 display: grid;
 grid-template-columns: repeat(5, 1fr);
 grid-template-rows: repeat(6, 1fr);
 gap: 6px;
 width: 100%;
 height: 100%;

}

.ggl-cell {

 position: relative;
 overflow: hidden;

}

.ggl-cell img, .ggl-cell canvas {

 position: absolute;
 inset: 0;
 width: 100%;
 height: 100%;

}

.ggl-mascot {

 position: absolute;
 left: 6%;
 top: 110%;
 bottom: 8%;
 font-size: 22px;

}

.ggl-bubble {

 position: absolute;
 left: 6%;
 top: 100%;
 bottom: 13%;
 width: 60%;
 min-height: 40px;
 background: rgba(255,255,255,.9);
 padding: 6px;
 font-size: 14px;

}

.ggl-controls {

 position: absolute;
 right: 6%;
 bottom: 8%;

}

  1. ggl-scan {
 opacity: .3;
 top: 110%;

}

  1. ggl-scan.active {
 opacity: 1;

} </style>

<script> (function () {

 const grid = document.querySelector('.ggl-grid');
 const bubble = document.querySelector('.ggl-bubble');
 const mascot = document.querySelector('.ggl-mascot');
 const scanBtn = document.getElementById('ggl-scan');
 let currentTicket = 0;
 let revealedCount = 0;
 let ticketsLeft = 3;
 let dataCount = 0;
 const TICKETS = [
   { mascot:"", intro:"点击中间按钮,来一张彩票。" },
   { mascot:"(^▽^)", intro:"第一次总是 Data。" },
   { mascot:"(・∀・)", intro:"连着刮,会有不一样的结果哦。" },
   { mascot:"(ノ◕ヮ◕)ノ", intro:"中奖了!Data 2MB!" },
   { mascot:"(・_・)", intro:"……刚才不该那样刮的。" },
   { mascot:"(;゚Д゚)", intro:"好像哪里不对。" },
   { mascot:"", intro:"什么都没有。" },
   { mascot:"...", intro:"���▒▒▒▒▒▒" },
   { mascot:"", intro:"哦、嗯、嘿、哈。" },
   { mascot:"", intro:"停下来。" },
   { mascot:"平安喜乐", intro:"你知道的太多了。" }
 ];
 function initTicket() {
   grid.innerHTML = "";
   revealedCount = 0;
   scanBtn.classList.remove("active");
   const ticket = TICKETS[currentTicket];
   mascot.textContent = ticket.mascot || "";
   bubble.textContent = ticket.intro || "";
   for (let i = 0; i < 30; i++) {
     const cell = document.createElement('div');
     cell.className = 'ggl-cell';
     cell.innerHTML = `
       <img src="180px-%E5%88%AE%E5%BC%80%E5%90%8E.jpg">
       <canvas></canvas>
     `;
     grid.appendChild(cell);
     initScratch(cell);
   }
 }
 function initScratch(cell) {
   const canvas = cell.querySelector('canvas');
   const ctx = canvas.getContext('2d');
   requestAnimationFrame(() => {
     canvas.width = cell.clientWidth;
     canvas.height = cell.clientHeight;
     const cover = new Image();
     cover.src = "180px-%E5%88%AE%E5%BC%80%E5%89%8D.png";
     cover.onload = () => ctx.drawImage(cover, 0, 0, canvas.width, canvas.height);
   });
   let down = false;
   canvas.addEventListener('pointerdown', () => down = true);
   canvas.addEventListener('pointerup', () => down = false);
   canvas.addEventListener('pointerleave', () => down = false);
   canvas.addEventListener('pointermove', e => {
     if (!down) return;
     const r = canvas.getBoundingClientRect();
     ctx.globalCompositeOperation = 'destination-out';
     ctx.beginPath();
     ctx.arc(e.clientX - r.left, e.clientY - r.top, 18, 0, Math.PI * 2);
     ctx.fill();
   });
   canvas.addEventListener('pointerup', () => {
     if (cell.dataset.revealed) return;
     cell.dataset.revealed = 1;
     revealedCount++;
     if (revealedCount === 30) {
       scanBtn.classList.add("active");
       bubble.textContent = "刮完了,可以扫描了。";
     }
   });
 }
 scanBtn.addEventListener('click', () => {
   if (!scanBtn.classList.contains('active')) {
     bubble.textContent = "还没刮完。";
     return;
   }
   if (currentTicket === 9) {
     bubble.textContent = "停下来。";
     currentTicket++;
     initTicket();
     return;
   }
   if (currentTicket === 10) {
     document.body.style.filter = "invert(1)";
     bubble.textContent = "你知道的太多了。";
     setTimeout(() => {
       location.href = "/index.php?title=六世恶言之一";
     }, 1200);
     return;
   }
   currentTicket++;
   initTicket();
 });
 initTicket();

})(); </script>