619 行
23 KiB
HTML
619 行
23 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Minecraft Code Editor</title>
|
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/remixicon/4.6.0/remixicon.min.css" rel="stylesheet">
|
|
<style>
|
|
@font-face {
|
|
font-family: 'DelaGothicOne';
|
|
src: url('https://assets-persist.lovart.ai/agent-static-assets/DelaGothicOne-Regular.ttf');
|
|
}
|
|
@font-face {
|
|
font-family: 'MiSans';
|
|
src: url('https://assets-persist.lovart.ai/agent-static-assets/MiSans-Regular.ttf');
|
|
}
|
|
@font-face {
|
|
font-family: 'PixelCode';
|
|
src: local('Courier New'), monospace; /* Fallback for code */
|
|
}
|
|
|
|
:root {
|
|
--mc-wood-light: #A07F53;
|
|
--mc-wood-dark: #765637;
|
|
--mc-stone: #757575;
|
|
--mc-stone-dark: #3b3b3b;
|
|
--mc-obsidian: #18181F;
|
|
--mc-grass: #7CB342;
|
|
--mc-grass-dark: #558B2F;
|
|
--mc-gold: #FFB300;
|
|
--mc-gold-dark: #FF8F00;
|
|
--mc-diamond: #00BCD4;
|
|
--mc-redstone: #F44336;
|
|
--mc-text-shadow: 2px 2px 0px #000;
|
|
--mc-border-light: rgba(255, 255, 255, 0.4);
|
|
--mc-border-dark: rgba(0, 0, 0, 0.4);
|
|
}
|
|
|
|
* {
|
|
box-sizing: border-box;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
body {
|
|
width: 1920px;
|
|
height: 1080px; /* Fixed height for preview, though body usually auto */
|
|
background-color: #121212;
|
|
font-family: 'MiSans', sans-serif;
|
|
color: white;
|
|
overflow: hidden;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
/* Minecraft Texture Classes */
|
|
.bg-wood {
|
|
background-color: var(--mc-wood-dark);
|
|
background-image:
|
|
linear-gradient(90deg, rgba(0,0,0,0.1) 50%, transparent 50%),
|
|
linear-gradient(rgba(0,0,0,0.1) 50%, transparent 50%);
|
|
background-size: 4px 4px;
|
|
box-shadow: inset 0 0 40px rgba(0,0,0,0.5);
|
|
}
|
|
|
|
.bg-stone {
|
|
background-color: var(--mc-stone);
|
|
background-image:
|
|
radial-gradient(circle at 2px 2px, rgba(255,255,255,0.1) 1px, transparent 1px),
|
|
radial-gradient(circle at 10px 10px, rgba(0,0,0,0.1) 2px, transparent 2px);
|
|
background-size: 20px 20px;
|
|
}
|
|
|
|
.bg-obsidian {
|
|
background-color: #1a1a24;
|
|
background-image:
|
|
repeating-linear-gradient(45deg, rgba(255,255,255,0.02) 0px, rgba(255,255,255,0.02) 1px, transparent 1px, transparent 10px),
|
|
repeating-linear-gradient(-45deg, rgba(255,255,255,0.02) 0px, rgba(255,255,255,0.02) 1px, transparent 1px, transparent 10px);
|
|
}
|
|
|
|
/* Typography */
|
|
h1, h2, h3, .mc-font {
|
|
font-family: 'DelaGothicOne', cursive;
|
|
letter-spacing: 1px;
|
|
text-shadow: 2px 2px 0 rgba(0,0,0,0.5);
|
|
}
|
|
|
|
/* 3D Button Style */
|
|
.mc-btn {
|
|
border: 4px solid #000;
|
|
border-top-color: rgba(255,255,255,0.5);
|
|
border-left-color: rgba(255,255,255,0.5);
|
|
border-bottom-color: rgba(0,0,0,0.5);
|
|
border-right-color: rgba(0,0,0,0.5);
|
|
padding: 8px 16px;
|
|
font-family: 'DelaGothicOne', cursive;
|
|
cursor: pointer;
|
|
text-transform: uppercase;
|
|
font-size: 14px;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
transition: transform 0.1s;
|
|
image-rendering: pixelated;
|
|
}
|
|
|
|
.mc-btn:active {
|
|
border-top-color: rgba(0,0,0,0.5);
|
|
border-left-color: rgba(0,0,0,0.5);
|
|
border-bottom-color: rgba(255,255,255,0.5);
|
|
border-right-color: rgba(255,255,255,0.5);
|
|
transform: translateY(2px);
|
|
}
|
|
|
|
.btn-green { background-color: var(--mc-grass); color: white; text-shadow: 1px 1px 0 #000; }
|
|
.btn-gold { background-color: var(--mc-gold); color: #3e2723; text-shadow: none; }
|
|
.btn-stone { background-color: var(--mc-stone); color: white; }
|
|
.btn-icon { padding: 8px; }
|
|
|
|
/* Scrollbar */
|
|
::-webkit-scrollbar { width: 12px; height: 12px; }
|
|
::-webkit-scrollbar-track { background: #2b2b2b; }
|
|
::-webkit-scrollbar-thumb {
|
|
background: #555;
|
|
border: 2px solid #2b2b2b;
|
|
border-top-color: #777;
|
|
border-left-color: #777;
|
|
}
|
|
|
|
/* Navigation */
|
|
.navbar {
|
|
height: 60px;
|
|
background-color: #212121;
|
|
border-bottom: 4px solid #000;
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 0 24px;
|
|
gap: 20px;
|
|
position: relative;
|
|
z-index: 10;
|
|
}
|
|
.nav-logo { font-size: 24px; color: var(--mc-grass); }
|
|
.nav-item { color: #aaa; text-decoration: none; font-family: 'DelaGothicOne'; font-size: 14px; }
|
|
.nav-item:hover { color: white; text-decoration: underline; }
|
|
|
|
/* Main Layout */
|
|
.main-container {
|
|
display: flex;
|
|
height: calc(100vh - 60px);
|
|
position: relative;
|
|
}
|
|
|
|
/* Left Panel */
|
|
.left-panel {
|
|
width: 40%;
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
border-right: 4px solid #000;
|
|
position: relative;
|
|
}
|
|
|
|
.problem-content {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 32px;
|
|
}
|
|
|
|
.paper-card {
|
|
background-color: #FDF5E6; /* Old Lace */
|
|
color: #333;
|
|
padding: 24px;
|
|
border: 4px solid #333;
|
|
box-shadow: 8px 8px 0 rgba(0,0,0,0.3);
|
|
margin-bottom: 24px;
|
|
position: relative;
|
|
}
|
|
|
|
.paper-card::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: -4px; left: -4px; right: -4px; bottom: -4px;
|
|
border: 2px solid #5d4037;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.difficulty-badge {
|
|
background-color: var(--mc-grass);
|
|
color: white;
|
|
padding: 4px 8px;
|
|
font-size: 12px;
|
|
border: 2px solid #33691E;
|
|
display: inline-block;
|
|
margin-left: 10px;
|
|
font-family: 'DelaGothicOne';
|
|
vertical-align: middle;
|
|
}
|
|
|
|
.code-block-display {
|
|
background-color: #263238;
|
|
color: #eceff1;
|
|
padding: 12px;
|
|
border-left: 4px solid var(--mc-grass);
|
|
font-family: 'PixelCode', monospace;
|
|
margin: 10px 0;
|
|
white-space: pre-wrap;
|
|
}
|
|
|
|
.panel-footer {
|
|
height: 70px;
|
|
background-color: rgba(0,0,0,0.3);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 0 24px;
|
|
border-top: 4px solid #3e2723;
|
|
}
|
|
|
|
/* Right Panel */
|
|
.right-panel {
|
|
width: 60%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
background-color: #1e1e1e;
|
|
}
|
|
|
|
.toolbar {
|
|
height: 56px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 0 16px;
|
|
border-bottom: 4px solid #000;
|
|
}
|
|
|
|
.toolbar-group {
|
|
display: flex;
|
|
gap: 12px;
|
|
align-items: center;
|
|
}
|
|
|
|
.code-editor-wrapper {
|
|
flex: 1;
|
|
display: flex;
|
|
overflow: hidden;
|
|
position: relative;
|
|
}
|
|
|
|
.line-numbers {
|
|
width: 48px;
|
|
background-color: #121217;
|
|
color: #546e7a;
|
|
text-align: right;
|
|
padding: 16px 8px;
|
|
font-family: 'PixelCode', monospace;
|
|
font-size: 16px;
|
|
line-height: 1.5;
|
|
user-select: none;
|
|
border-right: 2px solid #333;
|
|
}
|
|
|
|
.code-area {
|
|
flex: 1;
|
|
background-color: transparent;
|
|
color: #d4d4d4;
|
|
padding: 16px;
|
|
font-family: 'PixelCode', monospace;
|
|
font-size: 16px;
|
|
line-height: 1.5;
|
|
overflow: auto;
|
|
white-space: pre;
|
|
outline: none;
|
|
}
|
|
|
|
/* Syntax Highlighting Colors */
|
|
.token-keyword { color: #cc7832; font-weight: bold; }
|
|
.token-type { color: #e0c46c; }
|
|
.token-string { color: #6a8759; }
|
|
.token-comment { color: #808080; font-style: italic; }
|
|
.token-number { color: #6897bb; }
|
|
|
|
.status-bar {
|
|
height: 32px;
|
|
background-color: #2d2d2d;
|
|
border-top: 2px solid #444;
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 0 16px;
|
|
font-size: 12px;
|
|
gap: 20px;
|
|
color: #aaa;
|
|
font-family: 'PixelCode', monospace;
|
|
}
|
|
|
|
.combo-counter {
|
|
color: var(--mc-gold);
|
|
font-weight: bold;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
}
|
|
|
|
/* Test Panel */
|
|
.test-panel {
|
|
height: 220px;
|
|
border-top: 4px solid #000;
|
|
display: flex;
|
|
flex-direction: column;
|
|
transition: height 0.3s;
|
|
}
|
|
.test-panel.collapsed { height: 40px; }
|
|
|
|
.test-header {
|
|
height: 40px;
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 0 16px;
|
|
background-color: rgba(0,0,0,0.2);
|
|
border-bottom: 2px solid #444;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.tab-btn {
|
|
padding: 6px 16px;
|
|
background: none;
|
|
border: none;
|
|
color: #aaa;
|
|
cursor: pointer;
|
|
font-family: 'DelaGothicOne';
|
|
font-size: 12px;
|
|
}
|
|
.tab-btn.active { color: white; border-bottom: 2px solid var(--mc-grass); }
|
|
|
|
.test-content {
|
|
flex: 1;
|
|
padding: 16px;
|
|
display: flex;
|
|
gap: 16px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.test-case-item {
|
|
flex: 1;
|
|
background-color: rgba(0,0,0,0.3);
|
|
border: 2px solid #444;
|
|
padding: 12px;
|
|
font-family: 'PixelCode', monospace;
|
|
font-size: 14px;
|
|
}
|
|
.test-case-status { display: flex; justify-content: space-between; margin-bottom: 8px; font-weight: bold; }
|
|
.status-pass { color: var(--mc-grass); }
|
|
.status-fail { color: var(--mc-redstone); }
|
|
|
|
/* XP Overlay */
|
|
.xp-overlay {
|
|
position: absolute;
|
|
top: 50%; left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
font-size: 64px;
|
|
color: #B9F6CA;
|
|
text-shadow: 4px 4px 0 #1B5E20;
|
|
font-family: 'DelaGothicOne';
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
z-index: 100;
|
|
}
|
|
|
|
@keyframes xpFloat {
|
|
0% { opacity: 0; transform: translate(-50%, -20%); }
|
|
20% { opacity: 1; transform: translate(-50%, -50%); }
|
|
80% { opacity: 1; transform: translate(-50%, -60%); }
|
|
100% { opacity: 0; transform: translate(-50%, -100%); }
|
|
}
|
|
|
|
.animate-xp { animation: xpFloat 2s ease-out forwards; }
|
|
|
|
/* Confetti */
|
|
.confetti {
|
|
position: absolute;
|
|
width: 8px; height: 8px;
|
|
background: var(--mc-diamond);
|
|
animation: fall 3s linear forwards;
|
|
z-index: 99;
|
|
}
|
|
@keyframes fall {
|
|
to { transform: translateY(100vh) rotate(720deg); }
|
|
}
|
|
|
|
/* Select styling */
|
|
.mc-select {
|
|
background: var(--mc-stone-dark);
|
|
border: 2px solid #000;
|
|
color: white;
|
|
padding: 4px 8px;
|
|
font-family: 'PixelCode', monospace;
|
|
cursor: pointer;
|
|
outline: none;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<!-- Top Navigation -->
|
|
<nav class="navbar bg-stone">
|
|
<div class="nav-logo mc-font"><i class="ri-box-3-fill"></i> MINECODE</div>
|
|
<a href="#" class="nav-item">Problems</a>
|
|
<a href="#" class="nav-item">Contest</a>
|
|
<a href="#" class="nav-item">Discuss</a>
|
|
<div style="flex:1"></div>
|
|
<div class="nav-item" style="color:var(--mc-gold)">LVL 24</div>
|
|
<img src="https://api.dicebear.com/7.x/pixel-art/svg?seed=Steve" alt="User" style="width: 32px; height: 32px; border: 2px solid white;">
|
|
</nav>
|
|
|
|
<div class="main-container">
|
|
|
|
<!-- Left Panel: Problem -->
|
|
<aside class="left-panel bg-wood">
|
|
<div class="problem-content">
|
|
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom: 20px;">
|
|
<h1 style="font-size: 28px; color: #3E2723;">1. Two Sum</h1>
|
|
<span class="difficulty-badge">EASY</span>
|
|
</div>
|
|
|
|
<div class="paper-card">
|
|
<p style="margin-bottom: 16px; line-height: 1.6;">
|
|
Given an array of integers <code>nums</code> and an integer <code>target</code>, return <i>indices</i> of the two numbers such that they add up to <code>target</code>.
|
|
</p>
|
|
<p style="line-height: 1.6;">
|
|
You may assume that each input would have <strong>exactly one solution</strong>, and you may not use the same element twice.
|
|
</p>
|
|
</div>
|
|
|
|
<div style="margin-bottom: 24px;">
|
|
<h3 style="color:#3E2723; margin-bottom:10px;">Example 1:</h3>
|
|
<div class="code-block-display">Input: nums = [2,7,11,15], target = 9
|
|
Output: [0,1]
|
|
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].</div>
|
|
</div>
|
|
|
|
<div style="margin-bottom: 24px;">
|
|
<h3 style="color:#3E2723; margin-bottom:10px;">Example 2:</h3>
|
|
<div class="code-block-display">Input: nums = [3,2,4], target = 6
|
|
Output: [1,2]</div>
|
|
</div>
|
|
|
|
<div style="margin-bottom: 24px;">
|
|
<h3 style="color:#3E2723; margin-bottom:10px; display:flex; align-items:center;">
|
|
<i class="ri-book-mark-fill" style="margin-right:8px;"></i> Hints
|
|
</h3>
|
|
<div style="background: rgba(0,0,0,0.1); padding: 10px; border: 2px dashed #5D4037; color: #3E2723;">
|
|
Try using a Hash Map to store visited numbers.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="panel-footer">
|
|
<button class="mc-btn btn-stone"><i class="ri-star-fill"></i> Bookmark</button>
|
|
<div style="display: flex; gap: 10px;">
|
|
<button class="mc-btn btn-stone btn-icon"><i class="ri-share-forward-fill"></i></button>
|
|
<button class="mc-btn btn-stone btn-icon"><i class="ri-file-list-3-fill"></i></button>
|
|
</div>
|
|
</div>
|
|
</aside>
|
|
|
|
<!-- Right Panel: Editor -->
|
|
<main class="right-panel">
|
|
<!-- Toolbar -->
|
|
<div class="toolbar bg-stone">
|
|
<div class="toolbar-group">
|
|
<select class="mc-select">
|
|
<option>C++</option>
|
|
<option>Java</option>
|
|
<option>Python</option>
|
|
</select>
|
|
<button class="mc-btn btn-stone btn-icon" style="padding:4px 8px;"><i class="ri-settings-3-fill"></i></button>
|
|
<div style="color:#bbb; font-size:12px;">Size: 14px</div>
|
|
</div>
|
|
<div class="toolbar-group">
|
|
<button class="mc-btn btn-green" onclick="runCode()"><i class="ri-play-fill"></i> Run</button>
|
|
<button class="mc-btn btn-gold" onclick="submitCode()"><i class="ri-upload-cloud-2-fill"></i> Submit</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Code Editor -->
|
|
<div class="code-editor-wrapper bg-obsidian">
|
|
<div class="line-numbers">
|
|
1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11
|
|
</div>
|
|
<div class="code-area" contenteditable="true" spellcheck="false">
|
|
<span class="token-keyword">class</span> Solution {
|
|
<span class="token-keyword">public</span>:
|
|
<span class="token-type">vector</span><<span class="token-type">int</span>> twoSum(<span class="token-type">vector</span><<span class="token-type">int</span>>& nums, <span class="token-type">int</span> target) {
|
|
<span class="token-type">unordered_map</span><<span class="token-type">int</span>, <span class="token-type">int</span>> hash;
|
|
|
|
<span class="token-keyword">for</span> (<span class="token-type">int</span> i = <span class="token-number">0</span>; i < nums.size(); i++) {
|
|
<span class="token-type">int</span> complement = target - nums[i];
|
|
|
|
<span class="token-keyword">if</span> (hash.find(complement) != hash.end()) {
|
|
<span class="token-keyword">return</span> {hash[complement], i};
|
|
}
|
|
hash[nums[i]] = i;
|
|
}
|
|
<span class="token-keyword">return</span> {};
|
|
}
|
|
};</div>
|
|
</div>
|
|
|
|
<!-- Status Bar -->
|
|
<div class="status-bar">
|
|
<span>Ready</span>
|
|
<span style="border-left: 1px solid #555; height: 16px;"></span>
|
|
<span><i class="ri-time-fill"></i> 0ms</span>
|
|
<span><i class="ri-sd-card-mini-fill"></i> 0KB</span>
|
|
<div style="flex:1"></div>
|
|
<div class="combo-counter"><i class="ri-fire-fill"></i> COMBO x5</div>
|
|
</div>
|
|
|
|
<!-- Test Panel -->
|
|
<div class="test-panel bg-stone" id="testPanel">
|
|
<div class="test-header" onclick="toggleTestPanel()">
|
|
<i class="ri-terminal-box-fill" style="margin-right: 10px; color: #ccc;"></i>
|
|
<span class="mc-font" style="font-size: 14px; color: #eee; flex:1">Test Console</span>
|
|
<i class="ri-arrow-up-s-line" id="toggleIcon"></i>
|
|
</div>
|
|
<div style="background: rgba(0,0,0,0.4); padding: 0 16px; display: flex; border-bottom: 2px solid #444;">
|
|
<button class="tab-btn active">Test Cases</button>
|
|
<button class="tab-btn">Result</button>
|
|
</div>
|
|
<div class="test-content">
|
|
<div class="test-case-item">
|
|
<div class="test-case-status">Case 1 <i class="ri-checkbox-circle-fill status-pass"></i></div>
|
|
<div style="color: #888; font-size: 12px; margin-bottom: 4px;">Input</div>
|
|
<div style="color: #fff; margin-bottom: 8px;">nums = [2,7,11,15], target = 9</div>
|
|
<div style="color: #888; font-size: 12px; margin-bottom: 4px;">Expected</div>
|
|
<div style="color: #fff;">[0,1]</div>
|
|
</div>
|
|
<div class="test-case-item">
|
|
<div class="test-case-status">Case 2 <i class="ri-checkbox-circle-fill status-pass"></i></div>
|
|
<div style="color: #888; font-size: 12px; margin-bottom: 4px;">Input</div>
|
|
<div style="color: #fff; margin-bottom: 8px;">nums = [3,2,4], target = 6</div>
|
|
<div style="color: #888; font-size: 12px; margin-bottom: 4px;">Expected</div>
|
|
<div style="color: #fff;">[1,2]</div>
|
|
</div>
|
|
<div class="test-case-item" style="border-color: #F44336; opacity: 0.8;">
|
|
<div class="test-case-status">Case 3 <i class="ri-close-circle-fill status-fail"></i></div>
|
|
<div style="color: #888; font-size: 12px; margin-bottom: 4px;">Input</div>
|
|
<div style="color: #fff; margin-bottom: 8px;">nums = [3,3], target = 6</div>
|
|
<div style="color: #888; font-size: 12px; margin-bottom: 4px;">Expected</div>
|
|
<div style="color: #fff;">[0,1]</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
|
|
<!-- XP Animation Overlay -->
|
|
<div id="xpDisplay" class="xp-overlay">+50 XP</div>
|
|
|
|
<script>
|
|
function toggleTestPanel() {
|
|
const panel = document.getElementById('testPanel');
|
|
const icon = document.getElementById('toggleIcon');
|
|
panel.classList.toggle('collapsed');
|
|
|
|
if(panel.classList.contains('collapsed')) {
|
|
icon.classList.remove('ri-arrow-down-s-line');
|
|
icon.classList.add('ri-arrow-up-s-line');
|
|
} else {
|
|
icon.classList.remove('ri-arrow-up-s-line');
|
|
icon.classList.add('ri-arrow-down-s-line');
|
|
}
|
|
}
|
|
|
|
function runCode() {
|
|
// Simulate running code
|
|
const btn = document.querySelector('.btn-green');
|
|
btn.innerHTML = '<i class="ri-loader-4-line ri-spin"></i> Running...';
|
|
setTimeout(() => {
|
|
btn.innerHTML = '<i class="ri-play-fill"></i> Run';
|
|
document.getElementById('testPanel').classList.remove('collapsed');
|
|
}, 1000);
|
|
}
|
|
|
|
function submitCode() {
|
|
const btn = document.querySelector('.btn-gold');
|
|
const originalContent = btn.innerHTML;
|
|
btn.innerHTML = '<i class="ri-loader-4-line ri-spin"></i> ...';
|
|
|
|
setTimeout(() => {
|
|
btn.innerHTML = originalContent;
|
|
showXP();
|
|
createConfetti();
|
|
}, 1500);
|
|
}
|
|
|
|
function showXP() {
|
|
const xp = document.getElementById('xpDisplay');
|
|
xp.classList.remove('animate-xp');
|
|
void xp.offsetWidth; // trigger reflow
|
|
xp.classList.add('animate-xp');
|
|
}
|
|
|
|
function createConfetti() {
|
|
const colors = ['#F44336', '#2196F3', '#FFEB3B', '#4CAF50', '#FF9800'];
|
|
for(let i=0; i<50; i++) {
|
|
const conf = document.createElement('div');
|
|
conf.className = 'confetti';
|
|
conf.style.left = Math.random() * 100 + 'vw';
|
|
conf.style.top = '-10px';
|
|
conf.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
|
|
conf.style.animationDuration = (Math.random() * 2 + 2) + 's';
|
|
document.body.appendChild(conf);
|
|
|
|
setTimeout(() => conf.remove(), 4000);
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |