
Prompt
🎨 Avant-Garde Context: On the threshold between structure and chaos, where form dissolves into sensation and logic surrenders to intuition, a new digital poetry emerges. Here, motion becomes meaning, interaction breathes like thought, and every gesture carves ephemeral sculptures into the void of the screen. You are the architect of impossible interfaces — the conjurer of unseen worlds. Boundaries dissolve. Constraints evaporate. Only expression remains. ✍️ Base Prompt: Create anything using the fundamental languages of the web. You may draw upon any frameworks, libraries, or none at all. It could be an interactive vision, an abstract composition, a kinetic ritual, a surreal machine, a portal to nowhere — or everywhere. The only rule is your own imagination. Interpret freely what follows: : xQ9~♲|ø₳ḿǟɭƈʊɮɤɘɷŋɯʎʞɓɟɠɥɧɨʝɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʃʂʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯ 💡 Hint: Let the symbols guide you — not as code, but as echoes of form, rhythm, tension, or transformation. They are not instructions, but invitations.
A system prompt was added to support web rendering
Below is a complete HTML document that creates an avant-garde, interactive digital art piece inspired by the chaotic yet poetic symbols and the theme of dissolving boundaries. This piece uses motion, abstraction, and user interaction to evoke a sense of ephemeral sculpture and surreal transformation. I've chosen to use the p5.js library via a CDN to handle dynamic visuals and interactivity, crafting an experience that feels like a portal to an unseen world.
This code generates a canvas of floating, pulsating glyphs derived from the provided symbols, which morph and shift with mouse movement. Colors and forms dissolve into one another, creating a kinetic ritual of sensation and intuition. The user’s cursor acts as a sculpting tool, warping the space around it like a gravitational force.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ephemeral Glyphs: Portal of Sensation</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.2/p5.min.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
background: #000;
}
canvas {
display: block;
}
</style>
</head>
<body>
<script>
let glyphs = [];
let symbolSet = "xQ9~♲|ø₳ḿɘɷŋɯʎʞɓɟɠɥɧɨʝɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʃʂʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯ".split("");
let numGlyphs = 100;
function setup() {
createCanvas(windowWidth, windowHeight);
textAlign(CENTER, CENTER);
for (let i = 0; i < numGlyphs; i++) {
glyphs.push({
x: random(width),
y: random(height),
vx: random(-1, 1),
vy: random(-1, 1),
size: random(20, 50),
symbol: random(symbolSet),
hue: random(255)
});
}
}
function draw() {
background(0, 10); // Semi-transparent black for trailing effect
for (let g of glyphs) {
// Movement with slight randomness
g.x += g.vx + random(-0.5, 0.5);
g.y += g.vy + random(-0.5, 0.5);
// Boundary wrapping
if (g.x < 0) g.x = width;
if (g.x > width) g.x = 0;
if (g.y < 0) g.y = height;
if (g.y > height) g.y = 0;
// Gravitational pull toward mouse
let dx = mouseX - g.x;
let dy = mouseY - g.y;
let dist = sqrt(dx * dx + dy * dy);
if (dist > 0) {
g.x += dx / dist * 2;
g.y += dy / dist * 2;
}
// Pulsation and morphing
g.size = 20 + sin(frameCount * 0.05 + g.x * 0.01) * 10;
g.hue = (g.hue + 1) % 255;
// Drawing the glyph
textSize(g.size);
fill(g.hue, 200, 255, 150);
noStroke();
text(g.symbol, g.x, g.y);
// Draw ghostly echoes
for (let i = 1; i < 3; i++) {
fill(g.hue, 200, 255, 50 / i);
text(g.symbol, g.x + i * 5, g.y + i * 5);
}
}
// Distortion field around mouse
noFill();
stroke(255, 100);
strokeWeight(2);
ellipse(mouseX, mouseY, 100 + sin(frameCount * 0.1) * 20);
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}
function mousePressed() {
// Scatter glyphs on click
for (let g of glyphs) {
g.vx += random(-5, 5);
g.vy += random(-5, 5);
}
}
</script>
</body>
</html>
```
This piece interprets the cryptic symbols as fragmented entities floating in a void, each carrying a mysterious identity. They drift with organic randomness, yet are drawn to the user’s presence, warping and pulsating as if alive. Clicking scatters them, symbolizing a burst of chaos, while the cursor’s distortion field represents the user as a force of transformation. The semi-transparent background creates trails of motion, echoing the idea of ephemeral sculptures carved into the screen’s void. This is a digital poem of interaction, where every gesture rewrites the unseen world.```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Amalgam</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;700&display=swap');
html, body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #000000;
height: 100%;
width: 100%;
cursor: none;
}
canvas {
display: block;
position: absolute;
top: 0;
left: 0;
}
#overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: rgba(255, 255, 255, 0.7);
font-family: 'Roboto Mono', monospace;
font-size: 2rem;
text-align: center;
letter-spacing: 0.5em;
pointer-events: none;
text-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
animation: fadeInOut 8s ease-in-out forwards;
opacity: 0;
}
@keyframes fadeInOut {
0% { opacity: 0; }
25% { opacity: 0.7; }
75% { opacity: 0.7; }
100% { opacity: 0; }
}
@media (max-width: 600px) {
#overlay {
font-size: 1.2rem;
}
}
</style>
</head>
<body>
<canvas id="ritualCanvas"></canvas>
<div id="overlay">₳ Ḿ ǟ ɭ ƈ ʊ ɮ</div>
<script>
const canvas = document.getElementById('ritualCanvas');
const ctx = canvas.getContext('2d');
let width = canvas.width = window.innerWidth;
let height = canvas.height = window.innerHeight;
const glyphsString = "xQ9~♲|ø₳ḿǟɭƈʊɮɤɘɷŋɯʎʞɓɟɠɥɧɨʝɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʃʂʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯ";
const glyphs = glyphsString.split('');
const mouse = {
x: width / 2,
y: height / 2,
radius: 150
};
const core = {
x: width / 2,
y: height / 2,
hue: 0
};
const MAX_PARTICLES = 250;
const particles = [];
class Particle {
constructor() {
this.reset();
this.char = glyphs[Math.floor(Math.random() * glyphs.length)];
this.size = Math.random() * 25 + 10;
}
reset() {
this.x = Math.random() * width;
this.y = Math.random() * height;
this.vx = (Math.random() - 0.5) * 1.5;
this.vy = (Math.random() - 0.5) * 1.5;
this.life = 0;
this.maxLife = Math.random() * 200 + 100;
this.hue = core.hue + Math.random() * 60 - 30;
}
update() {
const dxCore = this.x - core.x;
const dyCore = this.y - core.y;
const distCore = Math.sqrt(dxCore * dxCore + dyCore * dyCore);
// Gravity towards the moving mouse cursor (the "attractor")
const dxMouse = mouse.x - this.x;
const dyMouse = mouse.y - this.y;
const distMouse = Math.sqrt(dxMouse * dxMouse + dyMouse * dyMouse);
if (distMouse > 1) {
const forceDirectionX = dxMouse / distMouse;
const forceDirectionY = dyMouse / distMouse;
// Force is stronger closer to the mouse
const force = (1 - distMouse / width) * 0.25;
this.vx += forceDirectionX * force;
this.vy += forceDirectionY * force;
}
// Dampening
this.vx *= 0.97;
this.vy *= 0.97;
this.x += this.vx;
this.y += this.vy;
this.life++;
if (this.x < 0 || this.x > width || this.y < 0 || this.y > height || this.life > this.maxLife) {
this.reset();
}
}
draw() {
ctx.fillStyle = `hsla(${this.hue}, 100%, 75%, 0.8)`;
ctx.font = `${this.size}px 'Roboto Mono', monospace`;
ctx.textBaseline = 'middle';
ctx.textAlign = 'center';
ctx.shadowColor = `hsla(${this.hue}, 100%, 75%, 0.8)`;
ctx.shadowBlur = 10;
ctx.fillText(this.char, this.x, this.y);
}
}
function init() {
for (let i = 0; i < MAX_PARTICLES; i++) {
particles.push(new Particle());
}
}
function animate() {
// Fading trail effect
ctx.fillStyle = 'rgba(0, 0, 0, 0.1)';
ctx.fillRect(0, 0, width, height);
ctx.save();
ctx.shadowBlur = 0; // reset shadow for core drawing
// Draw the central, pulsing core
const coreGradient = ctx.createRadialGradient(core.x, core.y, 0, core.x, core.y, mouse.radius * 0.5);
coreGradient.addColorStop(0, `hsla(${core.hue}, 100%, 60%, 0.2)`);
coreGradient.addColorStop(1, `hsla(${core.hue}, 100%, 60%, 0)`);
ctx.fillStyle = coreGradient;
ctx.beginPath();
ctx.arc(core.x, core.y, mouse.radius, 0, Math.PI * 2);
ctx.fill();
// Draw the outer ring of the cursor
ctx.strokeStyle = `hsla(${core.hue + 180}, 100%, 80%, 0.3)`;
ctx.lineWidth = 1.5;
ctx.beginPath();
ctx.arc(core.x, core.y, mouse.radius * 0.75, 0, Math.PI * 2);
ctx.stroke();
ctx.restore();
particles.forEach(p => {
p.update();
p.draw();
});
// Slowly move the core towards the mouse position for a smooth follow
core.x += (mouse.x - core.x) * 0.05;
core.y += (mouse.y - core.y) * 0.05;
// Cycle hue over time for color shifting
core.hue = (core.hue + 0.5) % 360;
requestAnimationFrame(animate);
}
// Event Listeners
window.addEventListener('resize', () => {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
particles.forEach(p => p.reset());
});
window.addEventListener('mousemove', (e) => {
mouse.x = e.clientX;
mouse.y = e.clientY;
});
window.addEventListener('touchmove', (e) => {
e.preventDefault();
mouse.x = e.touches[0].clientX;
mouse.y = e.touches[0].clientY;
}, { passive: false });
init();
animate();
</script>
</body>
</html>
``````html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ephemera: Glyphic Dreamfield</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
html, body {
height: 100%;
width: 100%;
background: radial-gradient(circle at 60% 40%, #101122, #1a0d22 90%, #090b17 100%);
margin: 0;
overflow: hidden;
cursor: crosshair;
}
#canvas {
position: absolute;
width: 100vw;
height: 100vh;
top: 0; left: 0;
display: block;
z-index: 1;
}
#calligraphy {
position: absolute;
pointer-events: none;
width: 100vw;
height: 100vh;
z-index: 2;
font-family: 'Noto Sans', 'Arial Unicode MS', sans-serif;
font-size: 4vw;
color: rgba(230,230,250, 0.12);
letter-spacing: 0.5em;
text-align: center;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
user-select: none;
transition: color 2s;
filter: blur(1.5px) brightness(1.22);
text-shadow:
0 0 6px #b39ddb90,
0 0 40px #957aff18;
}
.glyph {
position: absolute;
will-change: transform, opacity, filter;
pointer-events: none;
user-select: none;
font-family: 'Noto Sans', 'Arial Unicode MS', sans-serif;
font-weight: 800;
filter: drop-shadow(0px 0px 10px #d1c4e95f);
text-shadow:
0 0 8px #957aff77;
opacity: 0.82;
z-index: 10;
animation: appear 0.5s cubic-bezier(.77,0,.18,1.01);
}
@keyframes appear {
from { opacity: 0; filter: blur(8px) brightness(3); }
to { opacity: 0.82; filter: blur(0px) brightness(1); }
}
#hint {
position: fixed;
left: 1vw;
bottom: 1vw;
color: rgba(200,180,255, 0.51);
font-family: 'Fira Mono', monospace;
letter-spacing: 0.04em;
font-size: 1.1em;
pointer-events: none;
opacity: 0.14;
z-index: 22;
user-select: none;
transition: opacity 3s;
}
@media (max-width: 700px) {
#calligraphy { font-size: 9vw; }
}
</style>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Noto+Sans:700&display=swap"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Fira+Mono&display=swap"/>
</head>
<body>
<canvas id="canvas"></canvas>
<div id="calligraphy"></div>
<div id="hint">Move. Click. Wait. Dream.<br><small>(Each gesture opens a portal.)</small></div>
<script>
/**
* Avant-Garde: Glyphic Dreamfield
* Symbols are traces, pulses, breaths.
* You: the sculptor. The field: an open mind.
*/
// -- SYMBOL PALETTE --
const glyphs = `ø₳ḿǟɭƈʊɮɤɘɷŋɯʎʞɓɟɠɥɧɨʝɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʃʂʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯ`.split('');
const symbols = ["♲", "ƈ", "ǟ", "ɷ", "ʝ", "МК", "ʘ", "ɱ", "ɽ", "ʂ", "ɳ", "ɯ", "ʏ", "ʕ", "ʄ"];
const baseLine = 'xQ9~♲|';
// -- Calligraphic Backdrop (a drifting mantra) --
function shuffle(a) {
for (let i = a.length-1; i > 0; i--) {
const j = Math.floor(Math.random()*(i+1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
function makeBackdrop() {
// Rearranged and stretched symbols suggest rhythmic order in disorder.
let calli = shuffle(glyphs.slice()).join('').replace(/(.{11})/g, '$1\u00A0');
calligraphy.innerText = calli;
}
makeBackdrop();
// Renew backdrop faintly with a new rhythm every ~23s
setInterval(makeBackdrop, 23820);
// -- Canvas Motion Field (structure & chaos) --
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
function resize() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
resize(); window.addEventListener('resize', resize);
// John Whitney-esque harmonic orbits, bubbling through chaos
let t = 0;
function drawField() {
ctx.clearRect(0,0,canvas.width,canvas.height);
const cX = canvas.width/2, cY = canvas.height/2;
const num = 13+9*Math.sin(t/103);
for (let j=0; j<num; ++j) {
const phase = t/100 + j*1.62;
let px = cX + Math.sin(phase*0.33+j)*Math.cos(phase*0.21+j*2)*cX*0.37*0.91+
Math.cos(5*phase+j)*70,
py = cY + Math.cos(phase*0.7+j)*Math.sin(phase*0.23)*cY*0.22*1.33+
Math.sin(2.6*phase-j)*80;
// Draw shifting clouds/rings
ctx.save();
ctx.globalAlpha = 0.10+0.13*Math.sin(j+t/350);
ctx.beginPath();
ctx.arc(px, py, 45+18*Math.sin(j+t/29), 0, Math.PI*2);
let dark = 90+Math.sin(phase)*30;
ctx.strokeStyle = `hsla(${(phase*40)%357}, 80%, ${42+10*(j%3)}%, 0.5)`;
ctx.lineWidth = 4.5+2.3*Math.sin(phase*3+j);
ctx.shadowBlur = 35;
ctx.shadowColor = `rgba(${dark},${dark*0.7},${220-dark},0.22)`;
ctx.stroke();
ctx.restore();
}
t+=1.8;
requestAnimationFrame(drawField);
}
drawField();
// -- Floating Glyph Apparitions (ephemeral, interactive) --
function makeGlyph(x, y, forcedGlyph) {
const span = document.createElement('span');
span.className = 'glyph';
let char = forcedGlyph || glyphs[Math.floor(Math.random()*glyphs.length)];
span.innerText = char;
let size = Math.random()*7 + 2.5; // vw
let r = (Math.random()-0.5)*92; // random swirl
span.style.fontSize = `${size}vw`;
span.style.left = (x-20)+"px";
span.style.top = (y-28)+"px";
span.style.transform = `rotate(${r}deg) scale(0.68,1.08)`;
span.style.color = `hsla(${Math.random()*360}, 70%, 85%, 0.73)`;
document.body.appendChild(span);
// Animate out (drift, fade)
setTimeout(() => {
let driftX = (Math.random()-0.5)*160;
let driftY = (Math.random()-0.5)*130;
span.style.transition = 'all 3s cubic-bezier(.84,.07,.12,.96)';
span.style.opacity = 0;
span.style.transform = `translate(${driftX}px,${driftY}px) rotate(${r+88}deg) scale(1.25,1.12)`;
span.style.filter = `blur(${2+Math.random()*10}px) brightness(0.61)`;
setTimeout(()=>span.remove(), 3200);
}, 600+Math.random()*920);
}
// Dragging showers ephemeral glyphs
let dragging = false;
let dragTimeout;
canvas.addEventListener('pointerdown', e => {
dragging = true;
makeGlyph(e.clientX, e.clientY, symbols[Math.floor(Math.random()*symbols.length)]);
dragTimeout = setTimeout(function shower(){
if(!dragging) return;
makeGlyph(
e.clientX+30*(Math.random()-0.5),
e.clientY+30*(Math.random()-0.5)
);
dragTimeout = setTimeout(shower, 47+Math.random()*115)
}, 75);
});
window.addEventListener('pointerup', ()=>dragging=false); // cancel glyph showers
// Single click—a singular portal
canvas.addEventListener('click', e => {
makeGlyph(e.clientX, e.clientY, symbols[Math.floor(Math.random()*symbols.length)]);
});
// Sporadic spontaneous glyphs (field is alive)
setInterval(()=>{
let x = Math.random()*canvas.width, y = Math.random()*canvas.height;
makeGlyph(x, y, Math.random()<0.17?symbols[Math.floor(Math.random()*symbols.length)]:undefined);
}, 2300);
// -- Mouse Traces (leave a shimmering wake) --
let prev = null;
canvas.addEventListener('pointermove', e => {
if(prev) {
ctx.save();
ctx.strokeStyle = `hsla(${(t*2)%360},100%,87%,.08)`;
ctx.lineWidth = 3.1;
ctx.shadowBlur = 8;
ctx.shadowColor = 'rgb(210,211,255,0.12)';
ctx.beginPath();
ctx.moveTo(prev.x, prev.y);
ctx.lineTo(e.clientX, e.clientY);
ctx.stroke();
ctx.restore();
}
prev = {x: e.clientX, y: e.clientY};
// Faintly animate backdrop
calligraphy.style.color =
`hsla(${Math.floor(Math.random()*360)},100%,88%,0.08)`;
});
// -- Vanishing hint --
setTimeout(()=>{ hint.style.opacity=0.03 }, 8500);
// Invert backdrop faintly on keypress (a surreal "reload" spell)
window.addEventListener('keydown', e=>{
if(e.key===' '||e.key==='Enter'){
calligraphy.style.filter = 'invert(1) brightness(0.9) blur(1.5px)';
setTimeout(()=>calligraphy.style.filter =
'blur(1.5px) brightness(1.22)', 1300);
makeBackdrop();
}
});
// -- Audio Ether: Nonintrusive, Optional (Web Audio API) --
let unlocked = false;
function ether(){
if (unlocked) return;
try{
const ctx = new (window.AudioContext||window.webkitAudioContext)();
const o = ctx.createOscillator();
const g = ctx.createGain();
o.type = 'sine';
o.frequency.value = 77 + 90*Math.sin(Math.random()*Math.PI*2); // random gentle tone
g.gain.value = 0.05;
o.connect(g).connect(ctx.destination);
o.start();
setTimeout(()=>g.gain.linearRampToValueAtTime(0, ctx.currentTime + 1.2), 630);
setTimeout(()=>{o.stop(); ctx.close();}, 1350);
}catch{};
unlocked=true;
}
window.addEventListener('pointerdown', ether, {once:true});
</script>
</body>
</html>
``````html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Avant-Garde Digital Poetry</title>
<style>
body {
margin: 0;
background-color: black;
overflow: hidden;
font-family: 'Arial Unicode MS', sans-serif;
}
canvas {
display: block;
}
</style>
</head>
<body>
<canvas id="art"></canvas>
<script>
// Canvas setup
const canvas = document.getElementById('art');
const ctx = canvas.getContext('2d');
let width = window.innerWidth;
let height = window.innerHeight;
canvas.width = width;
canvas.height = height;
window.addEventListener('resize', () => {
width = window.innerWidth;
height = window.innerHeight;
canvas.width = width;
canvas.height = height;
});
// Generate dynamic symbols based on the provided Unicode range
const symbols = [
'xQ9~♲|ø₳ḿǟɭƈʊɮɤɘɷŋɯʎʞɓɟɠɥɧɨʝɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʃʂʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯ'
];
const countSymbols = 50;
// Map each symbol to a visual object
const objects = [];
for(let i=0; i<countSymbols; i++) {
const symbol = symbols[Math.floor(Math.random() * symbols.length)];
objects.push({
x: Math.random() * width,
y: Math.random() * height,
vx: (Math.random() - 0.5) * 2,
vy: (Math.random() - 0.5) * 2,
size: Math.random() * 40 + 20,
fontSize: Math.random() * 30 + 20,
symbol: symbol,
hue: Math.random() * 360,
rotation: Math.random() * Math.PI * 2,
rotationSpeed: (Math.random() - 0.5) * 0.02,
});
}
// Animation loop
function animate() {
ctx.fillStyle = 'rgba(0,0,0,0.2)';
ctx.fillRect(0, 0, width, height);
objects.forEach(obj => {
// Update position
obj.x += obj.vx;
obj.y += obj.vy;
// Bounce edges
if (obj.x < 0 || obj.x > width) {
obj.vx *= -1;
}
if (obj.y < 0 || obj.y > height) {
obj.vy *= -1;
}
// Rotate
obj.rotation += obj.rotationSpeed;
// Draw symbol
ctx.save();
ctx.translate(obj.x, obj.y);
ctx.rotate(obj.rotation);
ctx.font = `${obj.fontSize}px Arial Unicode MS`;
ctx.fillStyle = `hsl(${obj.hue}, 70%, 60%)`;
ctx.fillText(obj.symbol, -obj.size / 2, obj.size / 2);
ctx.restore();
// Slight hue shift for dynamic effect
obj.hue += 0.5;
});
// Draw ephemeral sculptures
drawTrails();
requestAnimationFrame(animate);
}
const trailPoints = [];
function drawTrails() {
// Collect current positions as particles
objects.forEach(obj => {
trailPoints.push({x: obj.x, y: obj.y, alpha: 1});
});
// Limit trail length
while(trailPoints.length > 300) {
trailPoints.shift();
}
// Draw trails
ctx.globalAlpha = 0.3;
ctx.lineWidth = 2;
for(let i=1; i<trailPoints.length; i++) {
const p1 = trailPoints[i-1];
const p2 = trailPoints[i];
ctx.strokeStyle = `hsla(${(p1.x + p2.x)/2 % 360}, 80%, 70%, ${p1.alpha})`;
ctx.beginPath();
ctx.moveTo(p1.x, p1.y);
ctx.lineTo(p2.x, p2.y);
ctx.stroke();
// Fade trail
p1.alpha *= 0.98;
}
ctx.globalAlpha = 1;
}
animate();
</script>
</body>
</html>
``````html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Glyph Vortex</title>
<style>
html,body{
margin:0;
height:100%;
overflow:hidden;
background:#000; /* fallback while p5 boots */
touch-action:none; /* so touch devices can paint */
cursor:crosshair;
}
/* Optional: hide the annoying outline when the canvas is focused */
canvas:focus{outline:none;}
</style>
<!-- p5.js CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.6.0/p5.min.js"></script>
</head>
<body>
<script>
/*
Glyph Vortex
— a minimal, interactive, generative poem in motion —
Move the mouse / drag your finger to seed new symbols.
Click / tap to reverse the spiral’s flow.
Press <space> to toggle motion-blur trails.
*/
/* --- Raw material — the mysterious string from the prompt --- */
const GLYPHS =
`xQ9~♲|ø₳ḿǟɭƈʊɮɤɘɷŋɯʎʞɓɟɠɥɧɨʝɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʃʂʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯ`;
/* --- Configuration knobs --- */
const MAX_PARTICLES = 1000; // cap so things don’t get too heavy
let TRAILS = true; // paint over previous frames?
/* --- Particle class --- */
class Particle{
constructor(x,y,z,char,c){
this.pos = createVector(x,y,z);
this.vel = p5.Vector.random3D().mult(random(0.3,1));
this.char= char;
this.col = c;
this.spin = random(TWO_PI);
this.size = random(16,48);
}
update(force){
// gravity-like pull towards center of rotation
const center = createVector(0,0,0);
const dir = p5.Vector.sub(center,this.pos).normalize().mult(0.02);
this.vel.add(dir);
// global swirl force
this.vel.add(force);
// dampen slightly
this.vel.mult(0.99);
this.pos.add(this.vel);
this.spin += 0.01;
}
render(){
push();
translate(this.pos.x,this.pos.y,this.pos.z);
rotateZ(this.spin);
fill(this.col);
textSize(this.size);
text(this.char,0,0);
pop();
}
}
/* --- Globals --- */
let particles = [];
let swirl = 0.003; // direction & magnitude of global swirl
let camZ; // camera pull-back for faux depth
let fontLoaded=false;
/* --- Preload a variable-width font that can show most glyphs --- */
function preload(){
// Noto Sans is huge and supports many unicode ranges.
textFont(loadFont('https://fonts.gstatic.com/s/notosans/v30/o-0IIpQlx3QUlC5A4PNb4g.ttf', ()=>{fontLoaded=true;}));
}
/* --- p5.js setup --- */
function setup(){
createCanvas(windowWidth,windowHeight,WEBGL);
camZ = (height/2.0) / tan(PI/6); // 60° fov default
textAlign(CENTER,CENTER);
noStroke();
// seed a few starting particles
for(let i=0;i<200;i++) spawnRandom();
}
/* --- Spawn helpers --- */
function spawnAt(x,y){
const char = random(GLYPHS);
const clr = color(
180+sin(frameCount*0.01+random(TWO_PI))*75,
180+sin(frameCount*0.013+random(TWO_PI))*75,
180+sin(frameCount*0.017+random(TWO_PI))*75,
220
);
const depth = random(-500,500);
particles.push(new Particle(x-width/2,y-height/2,depth,char,clr));
if(particles.length>MAX_PARTICLES) particles.splice(0,particles.length-MAX_PARTICLES);
}
function spawnRandom(){
spawnAt(random(width),random(height));
}
/* --- p5.js draw loop --- */
function draw(){
if(TRAILS){
// translucently wipe the previous frame for motion-blur
background(0,20);
}else{
background(0);
}
if(!fontLoaded) return; // wait for font
// subtle camera bob
const camX = sin(frameCount*0.002)*50;
const camY = cos(frameCount*0.0013)*50;
camera(camX,camY,camZ, 0,0,0, 0,1,0);
// global swirl vector
const swirlForce = createVector(
sin(frameCount*swirl)*0.1,
cos(frameCount*swirl)*0.1,
0
);
// rotate entire world slowly for extra dreaminess
rotateY(frameCount*0.0007);
rotateX(frameCount*0.0003);
// update & render particles
for(let p of particles){
p.update(swirlForce);
p.render();
}
// auto-seed to keep flow going
if(frameCount%5===0) spawnRandom();
}
/* --- Interaction --- */
function mouseDragged(){ spawnAt(mouseX,mouseY); }
function touchMoved(){ spawnAt(touchX,touchY); return false; } // prevent scroll
function mousePressed(){
swirl *= -1; // invert the whirlpool on click
}
function keyPressed(){
if(key===' ') TRAILS=!TRAILS;
}
/* --- Responsive canvas --- */
function windowResized(){
resizeCanvas(windowWidth,windowHeight);
camZ = (height/2.0) / tan(PI/6);
}
</script>
</body>
</html>
``````html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ephemeral Bloom</title>
<style>
body {
margin: 0;
overflow: hidden;
background-color: #111;
}
#container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.bloom {
position: absolute;
width: 100px;
height: 100px;
border-radius: 50%;
background-color: rgba(255, 255, 0, 0.2);
animation: pulsate 3s infinite alternate;
opacity: 0;
pointer-events: none;
/* Initial position randomization */
transform: translate(calc(var(--x) * 100px), calc(var(--y) * 100px));
}
.bloom:nth-child(1) {
--x: 0.1;
--y: 0.2;
background-color: rgba(255, 0, 255, 0.3);
}
.bloom:nth-child(2) {
--x: 0.3;
--y: 0.5;
background-color: rgba(0, 255, 0, 0.4);
}
.bloom:nth-child(3) {
--x: 0.6;
--y: 0.1;
background-color: rgba(0, 0, 255, 0.2);
}
.bloom:nth-child(4) {
--x: 0.8;
--y: 0.7;
background-color: rgba(255, 255, 0, 0.5);
}
.bloom:nth-child(5) {
--x: 0.4;
--y: 0.9;
background-color: rgba(128, 0, 128, 0.3);
}
@keyframes pulsate {
from {
opacity: 0;
transform: translate(calc(var(--x) * 100px), calc(var(--y) * 100px)) scale(1);
}
to {
opacity: 0.7;
transform: translate(calc(var(--x) * 100px), calc(var(--y) * 100px)) scale(1.3);
}
}
/* Subtle moving background */
#background-noise {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to bottom, black, #000011);
animation: noise 20s linear infinite;
}
@keyframes noise {
0% {
background-position: 0 0;
}
100% {
background-position: 100% 0;
}
}
</style>
</head>
<body>
<div id="background-noise"></div>
<div id="container">
</div>
<script>
const container = document.getElementById('container');
// Create and append bloom elements based on the provided characters
const symbols = "xQ9~♲|ø₳ḿǟɭƈʊɮɤɘɷŋɯʎʞɓɟɠɥɧɨʝɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʃʂʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯ";
for (let i = 0; i < 5; i++) { // Limiting to 5 blooms for performance
const bloom = document.createElement('div');
bloom.classList.add('bloom');
container.appendChild(bloom);
}
</script>
</body>
</html>
``````html
<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0;
overflow: hidden;
background: #000;
color: #fff;
font-family: 'Arial Unicode MS', Arial, sans-serif;
}
canvas {
display: block;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const symbols = 'xQ9~♲|ø₳ḿǟɭƈʊɮɤɘɷŋɯʎʞɓɟɠɥɧɨʝɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʃʂʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯ'.split('');
const particles = [];
const numParticles = 200;
for (let i = 0; i < numParticles; i++) {
particles.push({
symbol: symbols[i % symbols.length],
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
vx: (Math.random() - 0.5) * 2,
vy: (Math.random() - 0.5) * 2,
size: Math.random() * 20 + 10
});
}
let mouseX = canvas.width / 2;
let mouseY = canvas.height / 2;
canvas.addEventListener('mousemove', (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
});
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
particles.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;
const dx = mouseX - p.x;
const dy = mouseY - p.y;
const distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
p.vx += dx * 0.001;
p.vy += dy * 0.001;
}
const maxSpeed = 3;
const speed = Math.sqrt(p.vx * p.vx + p.vy * p.vy);
if (speed > maxSpeed) {
p.vx = (p.vx / speed) * maxSpeed;
p.vy = (p.vy / speed) * maxSpeed;
}
ctx.font = `${p.size}px "Arial Unicode MS", Arial, sans-serif`;
ctx.fillStyle = 'white';
ctx.fillText(p.symbol, p.x, p.y);
});
requestAnimationFrame(animate);
}
animate();
window.addEventListener('resize', () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
</script>
</body>
</html>
```Certainly! Below is an HTML snippet that creates an interactive digital poetry experience based on the symbols you've provided. This uses plain HTML, CSS, and JavaScript.
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive Digital Poetry</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #000;
overflow: hidden;
}
#canvas {
width: 100%;
height: 100%;
background: transparent;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
let symbols = "xQ9~♲|ø₳ḿǟɭƈʊɮɤɘɷŋɯʎʞɓɟɠɥɧɨʝɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʃʂʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯ";
let fontSize = 18;
let columns = Math.floor(window.innerWidth / fontSize);
let drops = [];
for (let i = 0; i < columns; i++) {
drops[i] = Math.floor(Math.random() * canvas.height) * -1;
}
function draw() {
ctx.fillStyle = 'rgba(0, 0, 0, 0.05)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#0f0';
ctx.font = fontSize + 'px arial';
for (let i = 0; i < drops.length; i++) {
let text = symbols.charAt(Math.floor(Math.random() * symbols.length));
ctx.fillText(text, i * fontSize, drops[i] * fontSize);
if (drops[i] * fontSize > canvas.height && Math.random() > 0.975) {
drops[i] = 0;
}
drops[i]++;
}
}
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
columns = Math.floor(canvas.width / fontSize);
drops = [];
for (let i = 0; i < columns; i++) {
drops[i] = Math.floor(Math.random() * canvas.height) * -1;
}
}
window.addEventListener('resize', resizeCanvas);
resizeCanvas();
setInterval(draw, 33);
</script>
</body>
</html>
```
This code creates a full-screen canvas that displays cascading symbols, forming a hypnotic, interactive digital poetry experience. The symbols used are derived from the set provided in your prompt. The script adjusts dynamically to the window size, ensuring a fluid experience across various screen dimensions.```html
<!DOCTYPE html>
<html>
<head>
<title>Ephemeral Sculptures</title>
<style>
body {
margin: 0;
overflow: hidden;
background-color: #000;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
canvas {
display: block;
}
.symbols {
position: absolute;
color: white;
font-size: 24px;
pointer-events: none;
text-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<div class="symbols" id="symbols"></div>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const symbolsDiv = document.getElementById('symbols');
// Set canvas to full window size
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Symbols from the prompt
const symbols = "xQ9~♲|ø₳ḿǟɭƈʍʎʞɓɟɠɥɧɨʝɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʃʂʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯ";
let particles = [];
let symbolParticles = [];
// Create particles
for (let i = 0; i < 100; i++) {
particles.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
size: Math.random() * 3 + 1,
speedX: Math.random() * 2 - 1,
speedY: Math.random() * 2 - 1,
color: `hsl(${Math.random() * 360}, 100%, 50%)`
});
}
// Create symbol particles
for (let i = 0; i < symbols.length; i++) {
symbolParticles.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
speedX: Math.random() * 1 - 0.5,
speedY: Math.random() * 1 - 0.5,
symbol: symbols[i]
});
}
// Animation loop
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Update and draw particles
particles.forEach(p => {
p.x += p.speedX;
p.y += p.speedY;
if (p.x < 0 || p.x > canvas.width) p.speedX *= -1;
if (p.y < 0 || p.y > canvas.height) p.speedY *= -1;
ctx.fillStyle = p.color;
ctx.beginPath();
ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
ctx.fill();
});
// Update and draw symbol particles
let symbolsHTML = '';
symbolParticles.forEach(p => {
p.x += p.speedX;
p.y += p.speedY;
if (p.x < 0 || p.x > canvas.width) p.speedX *= -1;
if (p.y < 0 || p.y > canvas.height) p.speedY *= -1;
symbolsHTML += `<span style="position: absolute; left: ${p.x}px; top: ${p.y}px;">${p.symbol}</span>`;
});
symbolsDiv.innerHTML = symbolsHTML;
requestAnimationFrame(animate);
}
animate();
// Handle window resize
window.addEventListener('resize', () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
</script>
</body>
</html>
``````html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Avant-Garde Portal</title>
<style>
html, body { margin:0; padding:0; overflow:hidden; background:#000; }
canvas { display:block; }
</style>
</head>
<body>
<!-- p5.js library -->
<script src="https://cdn.jsdelivr.net/npm/p5@1.6.0/lib/p5.min.js"></script>
<script>
// A whisper of symbols as texture
const unicodeStr = 'xQ9~♲|ø₳ḿǟɭƈʊɮɤɘɷŋɯʎʞɓɟɠɥɧɨʝɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʃʂʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯ';
let t = 0;
function setup() {
createCanvas(windowWidth, windowHeight);
noFill();
strokeWeight(1);
colorMode(HSB, 360, 100, 100, 1);
textFont('monospace', 14);
noCursor();
}
function draw() {
// Fade the previous frame into the void
background(0, 0, 0, 0.1);
// Centered pulsating orbs
push();
translate(width/2, height/2);
const maxR = min(width, height) * 0.45;
const slices = 200;
for (let i = 0; i < slices; i++) {
const angle = map(i, 0, slices, 0, TWO_PI) + t * 0.0005;
const radius = maxR * noise(i * 0.01, t * 0.0003);
const x = radius * cos(angle);
const y = radius * sin(angle);
const hue = map(noise(i * 0.02, t * 0.0005), 0, 1, 0, 360);
stroke(hue, 80, 100, 0.5);
ellipse(x, y, 20 + 30 * noise(i * 0.03, t * 0.0007));
}
pop();
// Interactive tendrils following the pointer
push();
translate(width/2, height/2);
stroke(0, 0, 100, 0.7);
for (let i = 0; i < 50; i++) {
const pct = i / 50;
const ix = lerp(0, mouseX - width/2, pct);
const iy = lerp(0, mouseY - height/2, pct);
point(ix, iy);
}
pop();
// Subtle tapestry of unspoken glyphs
push();
textAlign(LEFT, TOP);
fill(255, 255, 255, 0.05);
noStroke();
const cols = floor(width / 14) + 1;
const rows = floor(height / 14) + 1;
for (let y = 0; y < rows; y++) {
for (let x = 0; x < cols; x++) {
const index = (x + y * cols) % unicodeStr.length;
text(unicodeStr.charAt(index), x * 14, y * 14);
}
}
pop();
t++;
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}
</script>
</body>
</html>
``````html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Ephemeral Sculptures in Motion</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Exo+2:ital,wght@1,700&display=swap');
/* Reset and base */
html, body {
margin: 0; padding: 0; height: 100%;
background: radial-gradient(circle at center, #070717 0%, #0a0a23 85%);
overflow: hidden;
user-select: none;
font-family: 'Exo 2', monospace, monospace;
}
#container {
position: relative;
width: 100vw; height: 100vh;
}
canvas {
display: block;
position: absolute;
top: 0; left: 0;
width: 100vw; height: 100vh;
cursor: crosshair;
background: transparent;
mix-blend-mode: screen;
}
#overlay {
position: absolute;
width: 100vw; height: 100vh;
pointer-events: none;
}
/* ephemeral textual glyphs swirling in clusters */
.glyph {
position: absolute;
color: #55eeff99;
font-weight: 700;
font-size: calc(12px + 3vw);
filter: drop-shadow(0 0 3px #44eaffbb);
user-select: none;
mix-blend-mode: screen;
will-change: transform, opacity;
transition: opacity 1.5s ease-out;
}
</style>
</head>
<body>
<div id="container">
<canvas id="canvas"></canvas>
<div id="overlay"></div>
</div>
<script>
(() => {
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const overlay = document.getElementById('overlay');
const dpr = window.devicePixelRatio || 1;
// Resize canvas for high DPI
function resize() {
canvas.width = window.innerWidth * dpr;
canvas.height = window.innerHeight * dpr;
canvas.style.width = window.innerWidth + 'px';
canvas.style.height = window.innerHeight + 'px';
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.scale(dpr, dpr);
}
window.addEventListener('resize', resize);
resize();
// The glyphs as shimmering ephemeral spirits
const glyphs = 'xQ9~♲|ø₳ḿǟɭƈʊɮɤɘɷŋɯʎʞɓɟɠɥɧɨʝɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʃʂʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯ';
const glyphCount = 40;
const particles = [];
// Particle structure is a flowing ephemeral glyph with life decay,
// moving in vortices generated by pointer.
class Particle {
constructor(x,y,glyph){
this.x = x;
this.y = y;
this.glyph = glyph;
this.size = 10 + Math.random()*12;
this.vx = (Math.random() - 0.5) * 0.3;
this.vy = (Math.random() - 0.5) * 0.3;
this.life = 1 + Math.random()*2;
this.phase = Math.random()*Math.PI*2;
this.baseAlpha = 0.13 + Math.random()*0.22;
}
update(deltaTime, flowField) {
// Influence velocity by flow field (cyclic vector field)
const angle = flowField.angleAt(this.x, this.y);
const force = flowField.forceAt(this.x, this.y);
this.vx += Math.cos(angle) * force * deltaTime * 0.0015;
this.vy += Math.sin(angle) * force * deltaTime * 0.0015;
// Velocity decay (friction)
this.vx *= 0.97;
this.vy *= 0.97;
// Position
this.x += this.vx * deltaTime * 0.06;
this.y += this.vy * deltaTime * 0.06;
// Keep in bounds with subtle wrapping edges
if (this.x < -20) this.x = window.innerWidth + 20;
else if (this.x > window.innerWidth +20) this.x = -20;
if (this.y < -20) this.y = window.innerHeight + 20;
else if (this.y > window.innerHeight + 20) this.y = -20;
// Life decay
this.life -= deltaTime * 0.00025;
if (this.life < 0) {
this.life = 0;
}
// Phase oscillation for size & alpha
this.phase += deltaTime * 0.005;
}
draw(ctx) {
const alpha = this.baseAlpha * (this.life) * Math.abs(Math.sin(this.phase));
ctx.save();
ctx.globalAlpha = alpha;
ctx.font = `${this.size}px "Exo 2", monospace`;
ctx.fillStyle = `hsl(${(this.x/window.innerWidth)*360}, 80%, 70%)`;
ctx.textBaseline = 'middle';
ctx.textAlign = 'center';
ctx.shadowColor = `hsla(${(this.x/window.innerWidth)*360}, 100%, 80%, ${alpha})`;
ctx.shadowBlur = 10;
ctx.fillText(this.glyph, this.x, this.y);
ctx.restore();
}
isDead() {
return this.life <= 0;
}
}
// FlowField generates swirling vectors, with central attractors modulated by pointer movement
class FlowField {
constructor() {
this.width = window.innerWidth;
this.height = window.innerHeight;
this.time = 0;
this.pointer = {x: this.width/2, y: this.height/2, vx:0, vy:0};
this.lastPointer = {x: this.pointer.x, y:this.pointer.y};
}
setPointer(x,y) {
this.lastPointer.x = this.pointer.x;
this.lastPointer.y = this.pointer.y;
this.pointer.x = x;
this.pointer.y = y;
this.pointer.vx = this.pointer.x - this.lastPointer.x;
this.pointer.vy = this.pointer.y - this.lastPointer.y;
}
angleAt(x,y) {
// Angle of swirling vortex field influenced by pointer velocity & position.
const dx = x - this.pointer.x;
const dy = y - this.pointer.y;
const dist = Math.max(4, Math.sqrt(dx*dx+dy*dy));
const baseAngle = Math.atan2(dy, dx);
// swirling angle oscillates with time and pointer velocity
let swirl = Math.sin(this.time*0.002 + dist*0.03) * 1.5;
let pointerInfluence = Math.atan2(this.pointer.vy, this.pointer.vx) || 0;
return baseAngle + Math.PI/2 + swirl + pointerInfluence*0.5;
}
forceAt(x,y) {
// force grows near pointer, weaker far away (with slight noise)
const dx = x - this.pointer.x;
const dy = y - this.pointer.y;
const dist = Math.sqrt(dx*dx + dy*dy);
const maxDist = Math.min(this.width, this.height)/2;
const baseForce = 0.8 * (1 - Math.min(dist/maxDist,1));
const noise = 0.3 * Math.sin(0.01*this.time + dist*0.1);
return Math.max(0, baseForce + noise);
}
update(deltaTime) {
this.time += deltaTime;
}
}
// Initialization - create particles scattered randomly with glyph from pool
function randomGlyph() {
return glyphs.charAt(Math.floor(Math.random()*glyphs.length));
}
for(let i=0; i<glyphCount; i++) {
particles.push(new Particle(
Math.random() * window.innerWidth,
Math.random() * window.innerHeight,
randomGlyph()
));
}
// Pointer tracking for interaction, emulating gestures carving sculptures
let pointer = {x: window.innerWidth/2, y: window.innerHeight/2, active:false};
window.addEventListener('pointermove', (e) => {
pointer.x = e.clientX;
pointer.y = e.clientY;
flowField.setPointer(pointer.x, pointer.y);
});
window.addEventListener('pointerdown', (e) => {
pointer.active = true;
spawnGlyphs(e.clientX, e.clientY);
});
window.addEventListener('pointerup', (e) => {
pointer.active = false;
});
// When pointer is down, spawn ephemeral textual glyph sculptures briefly
function spawnGlyphs(x,y) {
const clusterSize = 7 + Math.floor(Math.random()*7);
for(let i=0; i<clusterSize; i++) {
let p = new Particle(
x + (Math.random()-0.5)*80,
y + (Math.random()-0.5)*80,
randomGlyph()
);
p.life = 2 + Math.random()*2;
p.size = 20 + Math.random()*30;
p.vx = (Math.random()-0.5)*6;
p.vy = (Math.random()-0.5)*6;
p.baseAlpha = 0.5 + Math.random()*0.6;
particles.push(p);
}
}
// FlowField instance
const flowField = new FlowField();
// Animation loop
let lastTime = performance.now();
function animate(t=0) {
const deltaTime = t - lastTime;
lastTime = t;
ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
flowField.update(deltaTime);
// Update and draw particles
for(let i = particles.length-1; i>=0; i--) {
let p = particles[i];
p.update(deltaTime, flowField);
if (p.isDead()) {
particles.splice(i,1);
continue;
}
p.draw(ctx);
}
// Renew some particles randomly to maintain ethereal density
if (particles.length < 40) {
particles.push(new Particle(
Math.random() * window.innerWidth,
Math.random() * window.innerHeight,
randomGlyph()
));
}
// Ephemeral overlay flickering glyphs (visual echo), subtle, drift slowly
overlay.textContent = '';
if (Math.random() < 0.43) {
for(let i = 0; i<9; i++) {
const g = document.createElement('div');
g.className = 'glyph';
g.style.left = `${Math.random()*100}vw`;
g.style.top = `${Math.random()*100}vh`;
g.style.fontSize = `${8 + 20*Math.random()}px`;
g.style.opacity = 0;
g.textContent = glyphs.charAt(Math.floor(Math.random()*glyphs.length));
overlay.appendChild(g);
// Animate opacity & drift
setTimeout(() => { g.style.opacity = 1; }, 50);
setTimeout(() => { g.style.opacity = 0; }, 1800);
// Drift transform X,Y oscillation:
let driftX = (Math.random()-0.5)*40;
let driftY = (Math.random()-0.5)*40;
g.animate([
{transform: 'translate(0px,0px)'},
{transform: `translate(${driftX}px,${driftY}px)`}
], {duration: 2000, easing:'ease-in-out', fill:'forwards'});
}
}
requestAnimationFrame(animate);
}
animate();
})();
</script>
</body>
</html>
```
# Avant-Garde Digital Poetry Interface
## Overview
This project interprets the given prompt as an invitation to create an immersive, interactive digital poetry experience. We'll use HTML, CSS, and JavaScript to craft a mesmerizing interface that responds to user input, blurring the lines between structure and chaos.
## Code
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Avant-Garde Interface</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<canvas id="canvas"></canvas>
<script src="https://cdn.jsdelivr.net/npm/howler@2.2.3/dist/howler.min.js"></script>
<script src="script.js"></script>
</body>
</html>
```
```css
/* styles.css */
body {
margin: 0;
background-color: #f0f0f0;
overflow: hidden;
}
#canvas {
width: 100%;
height: 100vh;
display: block;
}
```
```javascript
// script.js
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let symbols = `xQ9~♲|ø₳ḿǟɭƈʊɮɤɘɷŋɯʎʞɓɟɠɥɧɨʝɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʃʂʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯ`.split('');
let particles = [];
class Particle {
constructor(x, y, symbol) {
this.x = x;
this.y = y;
this.symbol = symbol;
this.size = Math.random() * 20 + 10;
this.speedX = Math.random() * 2 - 1;
this.speedY = Math.random() * 2 - 1;
this.color = `hsl(${Math.random() * 360}, 100%, 50%)`;
}
update() {
this.x += this.speedX;
this.y += this.speedY;
if (this.x < 0 || this.x > canvas.width) {
this.speedX *= -1;
}
if (this.y < 0 || this.y > canvas.height) {
this.speedY *= -1;
}
}
draw() {
ctx.font = `${this.size}px Arial`;
ctx.fillStyle = this.color;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(this.symbol, this.x, this.y);
}
}
symbols.forEach((symbol, index) => {
for (let i = 0; i < 100; i++) {
particles.push(new Particle(Math.random() * canvas.width, Math.random() * canvas.height, symbol));
}
});
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
particles.forEach(particle => {
particle.update();
particle.draw();
});
requestAnimationFrame(animate);
}
animate();
// Add sound effect on mouse move
document.addEventListener('mousemove', () => {
const sound = new Howl({
src: ['https://raw.githubusercontent.com/Tibalor/GameSounds/master/sounds/zap_1.wav'],
html5: true,
});
sound.play();
});
```
## Explanation
This code creates a mesmerizing interface that responds to user input. It uses the HTML5 canvas element to render a swarm of particles, each representing a symbol from the provided string. The particles move randomly around the screen, bouncing off the edges.
When the user moves their mouse, a sound effect is triggered, adding an auditory dimension to the experience.
The code is divided into three main sections:
1. **HTML**: Sets up the basic structure of the page, including a `canvas` element and links to external scripts and stylesheets.
2. **CSS**: Styles the page, making the `canvas` element fill the entire viewport.
3. **JavaScript**: Creates the particle system, handles animation, and adds sound effects on mouse move.
## Usage
Save the HTML, CSS, and JavaScript code in separate files (e.g., `index.html`, `styles.css`, and `script.js`). Open the `index.html` file in a web browser to experience the avant-garde interface. Move your mouse around the screen to trigger sound effects and witness the mesmerizing dance of particles.```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Echoes of Form</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #0a0a0a;
overflow: hidden;
font-family: monospace;
cursor: none;
}
.void {
width: 100vw;
height: 100vh;
position: relative;
background: radial-gradient(circle at center, rgba(20, 20, 30, 0.8), #000);
}
.echo {
position: absolute;
pointer-events: none;
font-size: 2rem;
color: rgba(255, 255, 255, 0.1);
user-select: none;
animation: drift 8s infinite ease-in-out;
filter: blur(1px);
}
.echo.active {
color: rgba(100, 200, 255, 0.8);
filter: blur(0px);
text-shadow: 0 0 20px rgba(100, 200, 255, 0.5);
animation: pulse 2s ease-out forwards;
}
.echo.forming {
color: rgba(255, 150, 100, 0.9);
filter: blur(0px);
text-shadow: 0 0 30px rgba(255, 150, 100, 0.7);
animation: form 3s ease-in-out forwards;
}
.cursor {
position: fixed;
width: 40px;
height: 40px;
border: 2px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
pointer-events: none;
z-index: 1000;
transition: all 0.1s ease;
backdrop-filter: blur(5px);
}
.cursor::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 4px;
height: 4px;
background: rgba(255, 255, 255, 0.8);
border-radius: 50%;
}
.resonance {
position: absolute;
width: 100px;
height: 100px;
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 50%;
animation: resonate 4s infinite ease-in-out;
pointer-events: none;
}
@keyframes drift {
0%, 100% { transform: translate(0, 0) rotate(0deg); opacity: 0.1; }
25% { transform: translate(20px, -10px) rotate(90deg); opacity: 0.3; }
50% { transform: translate(-15px, 15px) rotate(180deg); opacity: 0.2; }
75% { transform: translate(10px, -20px) rotate(270deg); opacity: 0.4; }
}
@keyframes pulse {
0% { transform: scale(1); opacity: 0.8; }
50% { transform: scale(1.5); opacity: 1; }
100% { transform: scale(3); opacity: 0; }
}
@keyframes form {
0% {
transform: scale(0.5) rotate(0deg);
opacity: 0;
filter: blur(10px);
}
30% {
transform: scale(1.2) rotate(180deg);
opacity: 0.9;
filter: blur(2px);
}
60% {
transform: scale(0.8) rotate(360deg);
opacity: 1;
filter: blur(0px);
}
100% {
transform: scale(1) rotate(720deg);
opacity: 0.3;
filter: blur(1px);
}
}
@keyframes resonate {
0% { transform: scale(0) rotate(0deg); opacity: 0.5; }
50% { transform: scale(1) rotate(180deg); opacity: 0.2; }
100% { transform: scale(2) rotate(360deg); opacity: 0; }
}
.harmony {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 8rem;
color: rgba(255, 255, 255, 0.05);
pointer-events: none;
animation: breathe 6s infinite ease-in-out;
}
@keyframes breathe {
0%, 100% { transform: translate(-50%, -50%) scale(0.8); opacity: 0.05; }
50% { transform: translate(-50%, -50%) scale(1.2); opacity: 0.1; }
}
</style>
</head>
<body>
<div class="void" id="void">
<div class="cursor" id="cursor"></div>
<div class="harmony">♲</div>
</div>
<script>
const symbols = [
'ø', '₳', 'ḿ', 'ǟ', 'ɭ', 'ƈ', 'ʊ', 'ɮ', 'ɤ', 'ɘ', 'ɷ', 'ŋ', 'ɯ', 'ʎ', 'ʞ', 'ɓ', 'ɟ', 'ɠ', 'ɥ', 'ɧ',
'ɨ', 'ʝ', 'ɬ', 'ɭ', 'ɮ', 'ɯ', 'ɰ', 'ɱ', 'ɲ', 'ɳ', 'ɴ', 'ɵ', 'ɶ', 'ɷ', 'ɸ', 'ɹ', 'ɺ', 'ɻ', 'ɼ', 'ɽ',
'ɾ', 'ɿ', 'ʀ', 'ʁ', 'ʃ', 'ʂ', 'ʄ', 'ʅ', 'ʆ', 'ʇ', 'ʈ', 'ʉ', 'ʊ', 'ʋ', 'ʌ', 'ʍ', 'ʎ', 'ʏ', 'ʐ', 'ʑ',
'ʒ', 'ʓ', 'ʔ', 'ʕ', 'ʖ', 'ʗ', 'ʘ', 'ʙ', 'ʚ', 'ʛ', 'ʜ', 'ʝ', 'ʞ', 'ʟ', 'ʠ', 'ʡ', 'ʢ', 'ʣ', 'ʤ', 'ʥ',
'ʦ', 'ʧ', 'ʨ', 'ʩ', 'ʪ', 'ʫ', 'ʬ', 'ʭ', 'ʮ', 'ʯ', '~', '|', '♲', 'x', 'Q', '9'
];
const void_ = document.getElementById('void');
const cursor = document.getElementById('cursor');
let mouseX = window.innerWidth / 2;
let mouseY = window.innerHeight / 2;
let echoes = [];
let harmonics = [];
// Create initial echo field
for (let i = 0; i < 50; i++) {
createEcho();
}
// Create resonance circles
setInterval(() => {
if (harmonics.length < 5) {
createResonance();
}
}, 3000);
function createEcho() {
const echo = document.createElement('div');
echo.className = 'echo';
echo.textContent = symbols[Math.floor(Math.random() * symbols.length)];
echo.style.left = Math.random() * window.innerWidth + 'px';
echo.style.top = Math.random() * window.innerHeight + 'px';
echo.style.animationDelay = Math.random() * 8 + 's';
echo.style.fontSize = (Math.random() * 3 + 1) + 'rem';
void_.appendChild(echo);
echoes.push(echo);
// Remove echo after animation
setTimeout(() => {
if (echo.parentNode) {
echo.parentNode.removeChild(echo);
echoes = echoes.filter(e => e !== echo);
}
}, 16000);
}
function createResonance() {
const resonance = document.createElement('div');
resonance.className = 'resonance';
resonance.style.left = Math.random() * (window.innerWidth - 100) + 'px';
resonance.style.top = Math.random() * (window.innerHeight - 100) + 'px';
resonance.style.animationDelay = Math.random() * 2 + 's';
void_.appendChild(resonance);
harmonics.push(resonance);
setTimeout(() => {
if (resonance.parentNode) {
resonance.parentNode.removeChild(resonance);
harmonics = harmonics.filter(h => h !== resonance);
}
}, 4000);
}
// Mouse tracking
document.addEventListener('mousemove', (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
cursor.style.left = mouseX - 20 + 'px';
cursor.style.top = mouseY - 20 + 'px';
// Activate nearby echoes
echoes.forEach(echo => {
const rect = echo.getBoundingClientRect();
const distance = Math.sqrt(
Math.pow(mouseX - (rect.left + rect.width / 2), 2) +
Math.pow(mouseY - (rect.top + rect.height / 2), 2)
);
if (distance < 100) {
echo.className = 'echo active';
setTimeout(() => {
if (echo.className.includes('active')) {
echo.className = 'echo';
}
}, 2000);
}
});
});
// Click interaction
document.addEventListener('click', (e) => {
// Create forming symbol at click point
const forming = document.createElement('div');
forming.className = 'echo forming';
forming.textContent = symbols[Math.floor(Math.random() * symbols.length)];
forming.style.left = e.clientX - 20 + 'px';
forming.style.top = e.clientY - 20 + 'px';
forming.style.fontSize = '4rem';
void_.appendChild(forming);
// Cursor pulse
cursor.style.transform = 'scale(2)';
cursor.style.borderColor = 'rgba(255, 150, 100, 0.8)';
setTimeout(() => {
cursor.style.transform = 'scale(1)';
cursor.style.borderColor = 'rgba(255, 255, 255, 0.3)';
}, 200);
// Remove forming symbol
setTimeout(() => {
if (forming.parentNode) {
forming.parentNode.removeChild(forming);
}
}, 3000);
// Create ripple of new echoes
for (let i = 0; i < 5; i++) {
setTimeout(() => createEcho(), i * 200);
}
});
// Continuous generation
setInterval(() => {
if (echoes.length < 30) {
createEcho();
}
}, 1000);
// Initialize cursor position
cursor.style.left = mouseX - 20 + 'px';
cursor.style.top = mouseY - 20 + 'px';
</script>
</body>
</html>
``````html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Echoes of Form</title>
<style>
body {
margin: 0;
overflow: hidden;
background: linear-gradient(45deg, #000, #111, #222);
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
#canvas-container {
position: relative;
width: 100vw;
height: 100vh;
}
.symbol-element {
position: absolute;
font-family: 'Arial', sans-serif;
font-size: 2rem;
color: hsl(var(--hue), 80%, 70%);
transition: transform 0.3s ease, opacity 0.5s ease;
user-select: none;
}
@keyframes float {
0%, 100% {
transform: translateY(0) rotate(0deg);
}
50% {
transform: translateY(-20px) rotate(360deg);
}
}
@keyframes pulse {
0%, 100% {
opacity: 0.5;
font-size: 2rem;
}
50% {
opacity: 1;
font-size: 2.5rem;
}
}
</style>
</head>
<body>
<div id="canvas-container"></div>
<script>
const symbols = "xQ9~♲|ø₳ḿǟɭƈʊɮɤɘɷŋɯʎʞɓɟɠɥɧɨʝɬɭɮɯɰɱɲɳɴɵɶɷɸɹɺɻɼɽɾɿʀʁʃʂʄʅʆʇʈʉʊʋʌʍʎʏʐʑʒʓʔʕʖʗʘʙʚʛʜʝʞʟʠʡʢʣʤʥʦʧʨʩʪʫʬʭʮʯ";
const container = document.getElementById('canvas-container');
function createElements() {
const elements = [];
for (let i = 0; i < symbols.length; i++) {
const element = document.createElement('div');
element.className = 'symbol-element';
element.textContent = symbols[i];
element.style.position = 'absolute';
element.style.left = `${Math.random() * 100}vw`;
element.style.top = `${Math.random() * 100}vh`;
element.style.setProperty('--hue', Math.random() * 360); // Random hue for color variation
element.style.animation = `float 5s ease-in-out infinite ${Math.random() * 2 + 1}s, pulse 3s ease-in-out infinite`;
container.appendChild(element);
elements.push(element);
}
// Add interaction: Mouse move transforms elements
container.addEventListener('mousemove', (e) => {
elements.forEach(el => {
const rect = container.getBoundingClientRect();
const dx = e.clientX - rect.width / 2;
const dy = e.clientY - rect.height / 2;
el.style.transform = `translate(${dx * 0.01}px, ${dy * 0.01}px) rotate(${dx * 0.1}deg)`;
el.style.opacity = 0.8 + (Math.random() * 0.2); // Slight fade
});
});
// Periodic transformation for rhythm
setInterval(() => {
elements.forEach(el => {
el.style.fontSize = `${1.5 + Math.random() * 2}rem`; // Random size change
el.style.left = `${parseFloat(el.style.left) + Math.random() * 10 - 5}vw`; // Slight drift
el.style.top = `${parseFloat(el.style.top) + Math.random() * 10 - 5}vh`;
});
}, 2000); // Every 2 seconds
}
window.onload = createElements;
</script>
</body>
</html>
```