Spaces:
Running
Running
Update index.html
Browse files- index.html +6 -188
index.html
CHANGED
|
@@ -3,7 +3,7 @@
|
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8" />
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
| 6 |
-
<title>Dot Labs</title>
|
| 7 |
<style>
|
| 8 |
* { box-sizing: border-box; }
|
| 9 |
body {
|
|
@@ -31,7 +31,8 @@
|
|
| 31 |
border: 1px solid #1c1c1e;
|
| 32 |
border-radius: 28px;
|
| 33 |
}
|
| 34 |
-
|
|
|
|
| 35 |
position: absolute;
|
| 36 |
inset: 0;
|
| 37 |
width: 100%;
|
|
@@ -40,7 +41,7 @@
|
|
| 40 |
pointer-events: none;
|
| 41 |
display: block;
|
| 42 |
}
|
| 43 |
-
.card > :not(
|
| 44 |
.logo { font-size: 15px; font-weight: 600; letter-spacing: -0.02em; }
|
| 45 |
main { max-width: 580px; }
|
| 46 |
h1 {
|
|
@@ -162,7 +163,7 @@
|
|
| 162 |
</head>
|
| 163 |
<body>
|
| 164 |
<section class="card">
|
| 165 |
-
<
|
| 166 |
<div class="logo">D●t Labs</div>
|
| 167 |
<main>
|
| 168 |
<h1>Intelligence<br>from the byte up.</h1>
|
|
@@ -199,189 +200,6 @@
|
|
| 199 |
<div class="disclaimer">Dot Labs™ is not related in any way to OpenAI's Dot product nor SpaceXAI web domain.</div>
|
| 200 |
</footer>
|
| 201 |
</section>
|
| 202 |
-
<script>
|
| 203 |
-
(() => {
|
| 204 |
-
// Feel free to tune these; everything is native Canvas, no dependencies.
|
| 205 |
-
const SETTINGS = {
|
| 206 |
-
style: 'drift',
|
| 207 |
-
seed: 137,
|
| 208 |
-
opacity: 1.0, // Grain visibility
|
| 209 |
-
size: 1.0, // Overall dot size
|
| 210 |
-
speed: 1.0 // Animation speed; 0 = frozen
|
| 211 |
-
};
|
| 212 |
-
const card = document.querySelector('.card');
|
| 213 |
-
const canvas = document.querySelector('canvas.grain');
|
| 214 |
-
const ctx = canvas.getContext('2d', { alpha: true });
|
| 215 |
-
if (!ctx) return;
|
| 216 |
-
const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
|
| 217 |
-
const PI2 = Math.PI * 2;
|
| 218 |
-
const gaussian = (x) => Math.exp(-x*x * .5);
|
| 219 |
-
const clamp = (x, a=0, b=1) => Math.max(a, Math.min(b, x));
|
| 220 |
-
const fract = x => x - Math.floor(x);
|
| 221 |
-
let particles = [], width=0, height=0, dpr=1, frame=0, then=0, elapsed=0, active=true;
|
| 222 |
-
|
| 223 |
-
function rng(seed) {
|
| 224 |
-
return () => {
|
| 225 |
-
let t = seed += 0x6D2B79F5;
|
| 226 |
-
t = Math.imul(t ^ t >>> 15, t | 1);
|
| 227 |
-
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
|
| 228 |
-
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
| 229 |
-
};
|
| 230 |
-
}
|
| 231 |
-
|
| 232 |
-
function concentration(x, y) {
|
| 233 |
-
if (SETTINGS.style === 'drift') {
|
| 234 |
-
return clamp(.28 + .34*x + .22*gaussian((x-.78)/.28)*gaussian((y-.43)/.47));
|
| 235 |
-
}
|
| 236 |
-
if (SETTINGS.style === 'nebula') {
|
| 237 |
-
const cloud = gaussian((x-.72)/.23)*gaussian((y-.41-.09*Math.sin(x*7))/.21);
|
| 238 |
-
const plume = gaussian((x-.53)/.29)*gaussian((y-.72)/.16);
|
| 239 |
-
return clamp(.055 + .88*cloud + .34*plume);
|
| 240 |
-
}
|
| 241 |
-
if (SETTINGS.style === 'eclipse') {
|
| 242 |
-
const r = Math.hypot((x-.72)/.43, (y-.48)/.60);
|
| 243 |
-
return clamp(.045 + .88*gaussian((r-.77)/.19));
|
| 244 |
-
}
|
| 245 |
-
const path = .80 - .53*x + .046*Math.sin(9*x);
|
| 246 |
-
return clamp(.07 + .89*gaussian((y-path)/.125) * (.35+.65*x));
|
| 247 |
-
}
|
| 248 |
-
|
| 249 |
-
// Larger dots progressively emerge across each pattern, without any
|
| 250 |
-
// solid gray gradient. Only individual particles carry color.
|
| 251 |
-
function sizeProgress(x, y) {
|
| 252 |
-
if (SETTINGS.style === 'eclipse') {
|
| 253 |
-
return clamp(.07 + .93*x);
|
| 254 |
-
}
|
| 255 |
-
if (SETTINGS.style === 'nebula') {
|
| 256 |
-
return clamp(.06 + .78*x + .17*y);
|
| 257 |
-
}
|
| 258 |
-
return clamp(.04 + .96*x);
|
| 259 |
-
}
|
| 260 |
-
|
| 261 |
-
function rebuild() {
|
| 262 |
-
const rect = card.getBoundingClientRect();
|
| 263 |
-
width = rect.width;
|
| 264 |
-
height = rect.height;
|
| 265 |
-
if (!width || !height) return;
|
| 266 |
-
dpr = Math.min(window.devicePixelRatio || 1, 2);
|
| 267 |
-
canvas.width = Math.round(width*dpr);
|
| 268 |
-
canvas.height = Math.round(height*dpr);
|
| 269 |
-
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
| 270 |
-
const random = rng(SETTINGS.seed);
|
| 271 |
-
const area = width*height;
|
| 272 |
-
particles = [];
|
| 273 |
-
const count = Math.floor(area / (SETTINGS.style === 'nebula' ? 13 : 15));
|
| 274 |
-
for (let i=0; i<count; i++) {
|
| 275 |
-
const x=random(), y=random();
|
| 276 |
-
const c = concentration(x,y);
|
| 277 |
-
if (random()>c) continue;
|
| 278 |
-
const growth = sizeProgress(x,y);
|
| 279 |
-
const isFine = random() < .76;
|
| 280 |
-
let radius;
|
| 281 |
-
let alpha;
|
| 282 |
-
if (isFine) {
|
| 283 |
-
radius=(.13 + .15*random() + .12*growth)*SETTINGS.size;
|
| 284 |
-
alpha=(.17 + .34*random()) * (.71+.29*c);
|
| 285 |
-
} else {
|
| 286 |
-
// A few larger grains emerge gently, but all remain subpixel-to-1px dust.
|
| 287 |
-
radius=(.19 + .66*Math.pow(growth,1.9)) * (.47+.53*random())*SETTINGS.size;
|
| 288 |
-
alpha=(.18 + .42*random())*(.70+.30*c);
|
| 289 |
-
}
|
| 290 |
-
// Occasional slightly larger isolated grains in the denser region.
|
| 291 |
-
if (random()<.008 && growth>.60) radius*=1.18;
|
| 292 |
-
const shade = Math.floor(139 + random()*75);
|
| 293 |
-
particles.push({x,y,radius,alpha,shade,phase:random()*PI2,
|
| 294 |
-
velocity:.42+random()*1.25,depth:random(),offset:0});
|
| 295 |
-
}
|
| 296 |
-
// The quiet microdust layer fills dark negative space at tiny sizes.
|
| 297 |
-
const fineCount = Math.floor(area / 21);
|
| 298 |
-
for (let i=0; i<fineCount; i++) {
|
| 299 |
-
const x=random(), y=random();
|
| 300 |
-
const density = concentration(x,y);
|
| 301 |
-
if (random() > .42+.36*density) continue;
|
| 302 |
-
const shade=Math.floor(140+random()*73);
|
| 303 |
-
particles.push({x,y,radius:(.12+.16*random())*SETTINGS.size,
|
| 304 |
-
alpha:(.16+.19*random())* (.67+.33*density),
|
| 305 |
-
shade,phase:random()*PI2,velocity:.24+random()*.75,
|
| 306 |
-
depth:random(),offset:0});
|
| 307 |
-
}
|
| 308 |
-
draw(0);
|
| 309 |
-
}
|
| 310 |
-
|
| 311 |
-
function position(p, t) {
|
| 312 |
-
const x=p.x, y=p.y;
|
| 313 |
-
if (SETTINGS.style === 'drift') {
|
| 314 |
-
// Low, steady breeze; different velocity at every dust depth.
|
| 315 |
-
return [fract(x+t*(3.5+4.2*p.velocity)/width),
|
| 316 |
-
y + 1.6*Math.sin(t*.49+p.phase)/height];
|
| 317 |
-
}
|
| 318 |
-
if (SETTINGS.style === 'nebula') {
|
| 319 |
-
// A barely rotating, breathing cloud of gray points.
|
| 320 |
-
const dx=(x-.68)*width, dy=(y-.48)*height;
|
| 321 |
-
const theta=t*(.003+.006*p.velocity);
|
| 322 |
-
const cos=Math.cos(theta), sin=Math.sin(theta);
|
| 323 |
-
return [.68 + (dx*cos-dy*sin+2.1*Math.sin(t*.31+p.phase))/width,
|
| 324 |
-
.48 + (dx*sin+dy*cos+2.0*Math.cos(t*.33+p.phase))/height];
|
| 325 |
-
}
|
| 326 |
-
if (SETTINGS.style === 'eclipse') {
|
| 327 |
-
// Subtle orbital travel around the ring; no fog or glow.
|
| 328 |
-
const dx=(x-.72)*width, dy=(y-.48)*height;
|
| 329 |
-
const angle=t*(.009+.006*p.velocity);
|
| 330 |
-
const rx=Math.cos(angle)*dx-Math.sin(angle)*dy*.78;
|
| 331 |
-
const ry=Math.sin(angle)*dx/ .78+Math.cos(angle)*dy;
|
| 332 |
-
return [.72+rx/width,.48+ry/height];
|
| 333 |
-
}
|
| 334 |
-
// Stream moves diagonally upward along a curved path.
|
| 335 |
-
const nx=fract(x+t*(4.0+5.5*p.velocity)/width);
|
| 336 |
-
const oldPath=.80-.53*x+.046*Math.sin(9*x);
|
| 337 |
-
const newPath=.80-.53*nx+.046*Math.sin(9*nx);
|
| 338 |
-
return [nx, newPath + (y-oldPath) + 1.8*Math.sin(t*.50+p.phase)/height];
|
| 339 |
-
}
|
| 340 |
-
|
| 341 |
-
function draw(t) {
|
| 342 |
-
ctx.clearRect(0,0,width,height);
|
| 343 |
-
for (const p of particles) {
|
| 344 |
-
const [nx,ny]=position(p,t);
|
| 345 |
-
if (nx<0 || nx>1 || ny<0 || ny>1) continue;
|
| 346 |
-
const shimmer=.91+.09*Math.sin(t*.67+p.phase);
|
| 347 |
-
const a=clamp(p.alpha*shimmer*SETTINGS.opacity);
|
| 348 |
-
ctx.fillStyle=`rgba(${p.shade},${p.shade},${p.shade},${a})`;
|
| 349 |
-
ctx.beginPath();
|
| 350 |
-
ctx.arc(nx*width,ny*height,p.radius,0,PI2);
|
| 351 |
-
ctx.fill();
|
| 352 |
-
}
|
| 353 |
-
}
|
| 354 |
|
| 355 |
-
function stop() {
|
| 356 |
-
cancelAnimationFrame(frame);
|
| 357 |
-
frame=0;
|
| 358 |
-
then=0;
|
| 359 |
-
}
|
| 360 |
-
function tick(now) {
|
| 361 |
-
if (!active || reducedMotion.matches) { stop(); return; }
|
| 362 |
-
if (then) elapsed+=Math.min((now-then)/1000,.05)*SETTINGS.speed;
|
| 363 |
-
then=now;
|
| 364 |
-
// Max ~25fps to keep the denser microdust field lightweight.
|
| 365 |
-
if (!tick.drawn || now-tick.drawn>=40) {
|
| 366 |
-
draw(elapsed);
|
| 367 |
-
tick.drawn=now;
|
| 368 |
-
}
|
| 369 |
-
frame=requestAnimationFrame(tick);
|
| 370 |
-
}
|
| 371 |
-
function updateRunning() {
|
| 372 |
-
stop();
|
| 373 |
-
if (active && !reducedMotion.matches) frame=requestAnimationFrame(tick);
|
| 374 |
-
else draw(elapsed);
|
| 375 |
-
}
|
| 376 |
-
document.addEventListener('visibilitychange',()=> {
|
| 377 |
-
active=!document.hidden;
|
| 378 |
-
updateRunning();
|
| 379 |
-
});
|
| 380 |
-
reducedMotion.addEventListener('change', updateRunning);
|
| 381 |
-
new ResizeObserver(rebuild).observe(card);
|
| 382 |
-
rebuild();
|
| 383 |
-
updateRunning();
|
| 384 |
-
})();
|
| 385 |
-
</script>
|
| 386 |
</body>
|
| 387 |
-
</html>
|
|
|
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8" />
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
| 6 |
+
<title>Dot Labs | HF-compatible animated dust</title>
|
| 7 |
<style>
|
| 8 |
* { box-sizing: border-box; }
|
| 9 |
body {
|
|
|
|
| 31 |
border: 1px solid #1c1c1e;
|
| 32 |
border-radius: 28px;
|
| 33 |
}
|
| 34 |
+
img.grain {
|
| 35 |
+
object-fit: cover;
|
| 36 |
position: absolute;
|
| 37 |
inset: 0;
|
| 38 |
width: 100%;
|
|
|
|
| 41 |
pointer-events: none;
|
| 42 |
display: block;
|
| 43 |
}
|
| 44 |
+
.card > :not(img.grain) { position: relative; z-index: 1; }
|
| 45 |
.logo { font-size: 15px; font-weight: 600; letter-spacing: -0.02em; }
|
| 46 |
main { max-width: 580px; }
|
| 47 |
h1 {
|
|
|
|
| 163 |
</head>
|
| 164 |
<body>
|
| 165 |
<section class="card">
|
| 166 |
+
<img class="grain" src="dotlabs-animated-dust.gif" alt="" aria-hidden="true">
|
| 167 |
<div class="logo">D●t Labs</div>
|
| 168 |
<main>
|
| 169 |
<h1>Intelligence<br>from the byte up.</h1>
|
|
|
|
| 200 |
<div class="disclaimer">Dot Labs™ is not related in any way to OpenAI's Dot product nor SpaceXAI web domain.</div>
|
| 201 |
</footer>
|
| 202 |
</section>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 203 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 204 |
</body>
|
| 205 |
+
</html>
|