openfree commited on
Commit
3278d19
ยท
verified ยท
1 Parent(s): 6618e95

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +98 -21
index.html CHANGED
@@ -3,26 +3,73 @@
3
  <head>
4
  <meta charset="UTF-8" />
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Pulsar Mini โ€“ ํ’€์Šคํฌ๋ฆฐ ์ปฌ๋Ÿฌ</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <style>
9
  /* ๊ธฐ๋ณธ ๋ ˆ์ด์•„์›ƒ */
10
- body {@apply m-0 overflow-hidden bg-black text-gray-200 font-sans;}
11
- canvas {width:100vw;height:100vh;display:block;image-rendering:pixelated;cursor:crosshair;}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  /* ์˜ค๋ฒ„๋ ˆ์ด UI */
13
- #ui {@apply absolute top-3 left-1/2 -translate-x-1/2 flex gap-2 z-50 select-none;}
14
- #ui button {@apply px-4 py-1.5 rounded text-sm font-semibold shadow bg-gray-800/70 backdrop-blur hover:bg-gray-700;}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  </style>
16
  </head>
17
  <body>
18
- <!-- ํ’€์Šคํฌ๋ฆฐ ์บ”๋ฒ„์Šค -->
19
- <canvas id="canvas"></canvas>
 
20
 
21
- <!-- UI ์˜ค๋ฒ„๋ ˆ์ด -->
22
- <div id="ui">
23
- <button id="play">โ–ถ ์žฌ์ƒ</button>
24
- <button id="pause" class="hidden">โšโš ์ผ์‹œ์ •์ง€</button>
25
- <button id="random">๐ŸŽฒ ๋žœ๋ค</button>
 
26
  </div>
27
 
28
  <script>
@@ -33,6 +80,9 @@ const playBtn = document.getElementById('play');
33
  const pauseBtn = document.getElementById('pause');
34
  const rndBtn = document.getElementById('random');
35
 
 
 
 
36
  // ๋‹ค์–‘ํ•œ ์ˆ˜ํ•™ ๊ณต์‹์„ ํ™œ์šฉํ•œ ์ปฌ๋Ÿฌ ํŒจํ„ด ํ…œํ”Œ๋ฆฟ (R,G,B ๊ฐ๊ฐ์˜ ์‹)
37
  const BASE_PATTERNS = [
38
  // 1. ์‚ฌ์ธ/์ฝ”์‚ฌ์ธ ๊ฒฉ์ž
@@ -49,18 +99,33 @@ const BASE_PATTERNS = [
49
  '(x,y,t)=>{const a=Math.atan2(y-0.5,x-0.5);const k=$K;return[0.5+0.5*Math.sin(k*a+t),0.5+0.5*Math.sin(k*a+t+2*Math.PI/3),0.5+0.5*Math.sin(k*a+t+4*Math.PI/3)];}',
50
  // 7. ํŽ˜๋ฅด๋งˆ ๋‚˜์„  ๋…ธ์ด์ฆˆ
51
  '(x,y,t)=>{const r=Math.hypot(x-0.5,y-0.5);const phi=r*10+$F1;return[0.5+0.5*Math.sin(phi+t),0.5+0.5*Math.cos(phi*1.3-t),0.5+0.5*Math.sin(phi*0.7+t*0.5)];}',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  ];
53
 
54
  function rand(min,max){return Math.random()*(max-min)+min;}
55
  function pickRandomFormula(){
56
  const tmpl=BASE_PATTERNS[Math.floor(Math.random()*BASE_PATTERNS.length)];
57
  return tmpl
58
- .replaceAll('$F1',rand(5,30).toFixed(2))
59
- .replaceAll('$F2',rand(5,30).toFixed(2))
60
- .replaceAll('$F3',rand(5,30).toFixed(2))
61
  .replaceAll('$S1',Math.random().toFixed(2))
62
  .replaceAll('$S2',Math.random().toFixed(2))
63
- .replaceAll('$K',Math.floor(rand(3,9))); // ์ •์ˆ˜ ๊ฝƒ์žŽ ์ˆ˜
 
64
  }
65
 
66
  let formulaSrc = pickRandomFormula();
@@ -69,9 +134,21 @@ let playing = true;
69
  let start = performance.now();
70
 
71
  function resizeCanvas(){
72
- canvas.width = window.innerWidth * DPR;
73
- canvas.height = window.innerHeight * DPR;
74
- ctx.setTransform(DPR,0,0,DPR,0,0);
 
 
 
 
 
 
 
 
 
 
 
 
75
  }
76
  resizeCanvas();
77
  window.addEventListener('resize',resizeCanvas);
@@ -85,8 +162,8 @@ function clamp01(v){ return v<0?0:v>1?1:v; }
85
 
86
  function draw(time){
87
  const t = (time - start)/1000;
88
- const w = canvas.width/DPR;
89
- const h = canvas.height/DPR;
90
  const img = ctx.createImageData(w,h);
91
  const data = img.data;
92
  let idx=0;
 
3
  <head>
4
  <meta charset="UTF-8" />
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Pulsar Mini โ€“ 16x16 ๋„ํŠธ ์ปฌ๋Ÿฌ</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <style>
9
  /* ๊ธฐ๋ณธ ๋ ˆ์ด์•„์›ƒ */
10
+ body {
11
+ margin: 0;
12
+ display: flex;
13
+ align-items: center;
14
+ justify-content: center;
15
+ height: 100vh;
16
+ background-color: black;
17
+ color: #e5e7eb;
18
+ font-family: sans-serif;
19
+ overflow: hidden;
20
+ }
21
+ .canvas-container {
22
+ position: relative;
23
+ overflow: hidden;
24
+ border-radius: 0.5rem;
25
+ border: 1px solid #374151;
26
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
27
+ }
28
+ canvas {
29
+ display: block;
30
+ image-rendering: pixelated;
31
+ image-rendering: crisp-edges;
32
+ cursor: crosshair;
33
+ }
34
  /* ์˜ค๋ฒ„๋ ˆ์ด UI */
35
+ #ui {
36
+ position: absolute;
37
+ top: 0.75rem;
38
+ left: 50%;
39
+ transform: translateX(-50%);
40
+ display: flex;
41
+ gap: 0.5rem;
42
+ z-index: 50;
43
+ user-select: none;
44
+ }
45
+ #ui button {
46
+ padding: 0.375rem 1rem;
47
+ border-radius: 0.25rem;
48
+ font-size: 0.875rem;
49
+ font-weight: 600;
50
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
51
+ background-color: rgba(31, 41, 55, 0.7);
52
+ backdrop-filter: blur(4px);
53
+ }
54
+ #ui button:hover {
55
+ background-color: rgba(55, 65, 81, 0.7);
56
+ }
57
+ .hidden {
58
+ display: none;
59
+ }
60
  </style>
61
  </head>
62
  <body>
63
+ <!-- ์ค‘์•™ ๋ฐฐ์น˜๋œ ์บ”๋ฒ„์Šค ์ปจํ…Œ์ด๋„ˆ -->
64
+ <div class="canvas-container">
65
+ <canvas id="canvas"></canvas>
66
 
67
+ <!-- UI ์˜ค๋ฒ„๋ ˆ์ด -->
68
+ <div id="ui">
69
+ <button id="play">โ–ถ ์žฌ์ƒ</button>
70
+ <button id="pause" class="hidden">โšโš ์ผ์‹œ์ •์ง€</button>
71
+ <button id="random">๐ŸŽฒ ๋žœ๋ค</button>
72
+ </div>
73
  </div>
74
 
75
  <script>
 
80
  const pauseBtn = document.getElementById('pause');
81
  const rndBtn = document.getElementById('random');
82
 
83
+ // ๋„ํŠธ ๊ทธ๋ฆฌ๋“œ ์„ค์ •
84
+ const GRID_SIZE = 16; // 16x16 ๋„ํŠธ
85
+
86
  // ๋‹ค์–‘ํ•œ ์ˆ˜ํ•™ ๊ณต์‹์„ ํ™œ์šฉํ•œ ์ปฌ๋Ÿฌ ํŒจํ„ด ํ…œํ”Œ๋ฆฟ (R,G,B ๊ฐ๊ฐ์˜ ์‹)
87
  const BASE_PATTERNS = [
88
  // 1. ์‚ฌ์ธ/์ฝ”์‚ฌ์ธ ๊ฒฉ์ž
 
99
  '(x,y,t)=>{const a=Math.atan2(y-0.5,x-0.5);const k=$K;return[0.5+0.5*Math.sin(k*a+t),0.5+0.5*Math.sin(k*a+t+2*Math.PI/3),0.5+0.5*Math.sin(k*a+t+4*Math.PI/3)];}',
100
  // 7. ํŽ˜๋ฅด๋งˆ ๋‚˜์„  ๋…ธ์ด์ฆˆ
101
  '(x,y,t)=>{const r=Math.hypot(x-0.5,y-0.5);const phi=r*10+$F1;return[0.5+0.5*Math.sin(phi+t),0.5+0.5*Math.cos(phi*1.3-t),0.5+0.5*Math.sin(phi*0.7+t*0.5)];}',
102
+ // 8. ์ƒˆ๋กœ์šด ํŒจํ„ด: ๊ฒฉ์ž ๋…ธ์ด์ฆˆ
103
+ '(x,y,t)=>{const nx=Math.floor(x*$F1)/($F1/2);const ny=Math.floor(y*$F2)/($F2/2);return[0.5+0.5*Math.sin(nx*$F3+t),0.5+0.5*Math.cos(ny*$F3-t),0.5+0.5*Math.sin((nx+ny)*$F3+t*0.7)];}',
104
+ // 9. ์ƒˆ๋กœ์šด ํŒจํ„ด: ํ”„๋ž™ํƒˆ ๊ธฐ๋ฐ˜
105
+ '(x,y,t)=>{let zx=3*(x-0.5),zy=3*(y-0.5),i=0,max=$IT;while(i<max&&zx*zx+zy*zy<4){const tmp=zx*zx-zy*zy;zy=2*zx*zy+0.5*Math.sin(t);zx=tmp+0.5*Math.cos(t);i++;}return[i/max,0.5+0.5*Math.sin(i/max*Math.PI+t),0.5+0.5*Math.cos(i/max*Math.PI*2-t)];}',
106
+ // 10. ์ƒˆ๋กœ์šด ํŒจํ„ด: ์ฒด์ปค๋ณด๋“œ ๋ณ€ํ˜•
107
+ '(x,y,t)=>{const cx=Math.floor(x*$F1);const cy=Math.floor(y*$F1);const even=(cx+cy)%2===0;const r=0.5+0.5*Math.sin(cx*cy/($F2)+t);const g=0.5+0.5*Math.cos((cx-cy)*$F3-t);const b=even?0.2+0.8*Math.sin(t*0.5):0.2+0.8*Math.cos(t*0.7);return[r,g,b];}',
108
+ // 11. ์ƒˆ๋กœ์šด ํŒจํ„ด: ๋ชจ์•„๋ ˆ ํŒจํ„ด
109
+ '(x,y,t)=>{const p1=Math.sin(x*$F1+t);const p2=Math.sin(y*$F2-t*0.7);const p3=Math.sin((x+y)*$F3+t*0.3);const moire=Math.sin(p1*p2*p3*10);return[0.5+0.5*moire,0.5+0.5*Math.sin(moire*Math.PI+t),0.5+0.5*Math.cos(moire*Math.PI-t)];}',
110
+ // 12. ์ƒˆ๋กœ์šด ํŒจํ„ด: ์ง„๋™ ๋ฌผ๊ฒฐ
111
+ '(x,y,t)=>{const wave1=Math.sin(y*$F1+x*$F2+t);const wave2=Math.sin(x*$F3-y*$F1-t*1.5);return[0.5+0.5*wave1,0.5+0.5*wave2,0.5+0.5*Math.sin(wave1*wave2*3+t)];}',
112
+ // 13. ์ƒˆ๋กœ์šด ํŒจํ„ด: ๋…ธ์ด์ฆˆ ํผ๋ฎคํ…Œ์ด์…˜
113
+ '(x,y,t)=>{const p=(x*$F1+y*$F2)%1;const q=(y*$F3-x*$F2+t)%1;return[p,q,0.5+0.5*Math.sin(p*q*Math.PI*2+t)];}',
114
+ // 14. ์ƒˆ๋กœ์šด ํŒจํ„ด: ๋„ํŠธ ๊ทธ๋ฆฌ๋“œ
115
+ '(x,y,t)=>{const gx=Math.floor(x*4)/4;const gy=Math.floor(y*4)/4;const r=0.5+0.5*Math.sin(gx*$F1+gy*$F2+t);const g=0.5+0.5*Math.cos(gx*$F3-gy*$F1-t);const b=0.5+0.5*Math.sin((gx-gy)*$F3*2+t*1.5);return[r,g,b];}',
116
  ];
117
 
118
  function rand(min,max){return Math.random()*(max-min)+min;}
119
  function pickRandomFormula(){
120
  const tmpl=BASE_PATTERNS[Math.floor(Math.random()*BASE_PATTERNS.length)];
121
  return tmpl
122
+ .replaceAll('$F1',rand(5,40).toFixed(2))
123
+ .replaceAll('$F2',rand(5,40).toFixed(2))
124
+ .replaceAll('$F3',rand(5,40).toFixed(2))
125
  .replaceAll('$S1',Math.random().toFixed(2))
126
  .replaceAll('$S2',Math.random().toFixed(2))
127
+ .replaceAll('$K',Math.floor(rand(3,12))) // ์ •์ˆ˜ ๊ฝƒ์žŽ ์ˆ˜
128
+ .replaceAll('$IT',Math.floor(rand(10,30))); // ํ”„๋ž™ํƒˆ ๋ฐ˜๋ณต ํšŸ์ˆ˜
129
  }
130
 
131
  let formulaSrc = pickRandomFormula();
 
134
  let start = performance.now();
135
 
136
  function resizeCanvas(){
137
+ // ๋ทฐํฌํŠธ ํฌ๊ธฐ์˜ 70%๋ฅผ ์ฐจ์ง€ํ•˜๋Š” ์ •์‚ฌ๊ฐํ˜•์œผ๋กœ ์„ค์ •
138
+ const size = Math.min(window.innerWidth, window.innerHeight) * 0.7;
139
+
140
+ // ์บ”๋ฒ„์Šค์˜ ์‹ค์ œ ํ•ด์ƒ๋„๋Š” 16x16
141
+ canvas.width = GRID_SIZE;
142
+ canvas.height = GRID_SIZE;
143
+
144
+ // ์บ”๋ฒ„์Šค ํ‘œ์‹œ ํฌ๊ธฐ๋Š” ํ™”๋ฉด์˜ 70%
145
+ canvas.style.width = `${size}px`;
146
+ canvas.style.height = `${size}px`;
147
+
148
+ // ์บ”๋ฒ„์Šค ์ปจํ…Œ์ด๋„ˆ๋„ ๊ฐ™์€ ํฌ๊ธฐ๋กœ ์„ค์ •
149
+ const container = document.querySelector('.canvas-container');
150
+ container.style.width = `${size}px`;
151
+ container.style.height = `${size}px`;
152
  }
153
  resizeCanvas();
154
  window.addEventListener('resize',resizeCanvas);
 
162
 
163
  function draw(time){
164
  const t = (time - start)/1000;
165
+ const w = canvas.width;
166
+ const h = canvas.height;
167
  const img = ctx.createImageData(w,h);
168
  const data = img.data;
169
  let idx=0;