commit d89da60e2d662bb396706030fc6f4b6266fd9d66 Author: glazenbol <5520120+glazenbol@users.noreply.github.com> Date: Wed Mar 18 05:49:16 2026 +0100 init commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f09cd16 --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +# Dependencies +node_modules/ +npm-debug.log +yarn-error.log +package-lock.json +yarn.lock + +# Environment variables +.env +.env.local +.env.*.local + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ +.DS_Store + +# Build output +dist/ +build/ +out/ + +# Logs +logs/ +*.log + +# OS +Thumbs.db \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..ee95657 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# noise fields + +## Getting Started + +Open `index.html` in your web browser and start editing `sketch.js`. + +## Running Locally + +For projects with media files, use a local server: + +```bash +# Using Python +python -m http.server 8000 + +# Using Node.js +npx http-server + +# Using VS Code Live Server extension +# Right-click index.html -> "Open with Live Server" +``` + +## Resources + +- [p5.js 2.0](https://beta.p5js.org/) +- [p5.js Reference](https://p5js.org/reference/) diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 0000000..a0bc8cc --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,31 @@ +# Dependencies +node_modules/ +npm-debug.log* + +# Build output +dist/ +build/ +.next/ +out/ + +# Environment variables +.env +.env.local +.env.*.local + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ +.DS_Store + +# OS +Thumbs.db + +# Misc +.cache/ + +# big assets +assets/scans/ \ No newline at end of file diff --git a/frontend/control.html b/frontend/control.html new file mode 100644 index 0000000..0d3b81c --- /dev/null +++ b/frontend/control.html @@ -0,0 +1,12 @@ + + + + + + + nf control + + + + + diff --git a/frontend/css/style.css b/frontend/css/style.css new file mode 100644 index 0000000..bc6840f --- /dev/null +++ b/frontend/css/style.css @@ -0,0 +1,13 @@ +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + background: #f0f0f0; +} diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..34c7d09 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,12 @@ + + + + + + noise fields + + + + + + diff --git a/frontend/js/control.js b/frontend/js/control.js new file mode 100644 index 0000000..7ecb7e6 --- /dev/null +++ b/frontend/js/control.js @@ -0,0 +1,27 @@ +import { GUI } from "lil-gui"; +import io from "socket.io-client"; + +const socket = io("http://localhost:3000"); + +const gui = new GUI(); +const params = { + fps: 60, + zoom: 0.01, + backgroundTicks: 60, + textSpread: 0, + maxSpawns: 1, + textAlpha: 0.0, + textTicks: 1 +}; +gui.add(params, "fps", 0.1, 60); +gui.add(params, "zoom", 0.001, 0.5); +gui.add(params, "backgroundTicks", 1, 240).step(1); +const textFolder = gui.addFolder("Text"); +textFolder.add(params, "textSpread", 0, 200); +textFolder.add(params, "maxSpawns", 1, 20).step(1); +textFolder.add(params, "textAlpha", 0, 255).step(1); +textFolder.add(params, "textTicks", 1, 240).step(1); + +gui.onChange((e) => { + socket.emit("paramUpdate", { key: e.property, value: e.value }); +}); \ No newline at end of file diff --git a/frontend/js/sketch.js b/frontend/js/sketch.js new file mode 100644 index 0000000..eaa97e4 --- /dev/null +++ b/frontend/js/sketch.js @@ -0,0 +1,105 @@ +import p5 from "p5"; +import io from "socket.io-client"; +const socket = io("http://localhost:3000"); + +const params = { + fps: 60, + zoom: 0.01, + backgroundTicks: 60, + textSpread: 0, + maxSpawns: 1, + textAlpha: 0.0, + textTicks: 1, +}; + +socket.on("paramUpdate", ({ key, value }) => { + params[key] = value; + console.log(`Updated param ${key} to ${value}`); +}); + +let bg; +let cw = 1; +let ch = 1; + +const poem = + "everybody is pretty ugly \ +lover \ +you are my mirror \ +I can't judge this \ +predicament \ +autism alienation and sitting beach \ +this depression's a symptom but it's disease too \ +spaces \ +interiors in berlin city reach peach intention lover drag sleepless depth fear dirt lone"; +const realText = poem.split(" ").filter((t) => t.length > 0); + +const sketch = (p) => { + p.setup = async () => { + bg = await p.loadImage("assets/scans/1200dpi 16bit grayscale.png"); + console.log(bg); + p.createCanvas(p.windowWidth, p.windowHeight); + console.log("canvas created"); + // const stream = c.elt.captureStream(60); + }; + + let bgTick = 0; + let textTick = 0; + let sx, sy; + let word, bounds; + + p.draw = () => { + p.background(220); + // update scale + p.setFrameRate(params.fps); + + if (++bgTick >= params.backgroundTicks) { + cw = Math.floor(bg.width * params.zoom); + ch = Math.floor(bg.height * params.zoom); + + sx = Math.random(0) * (bg.width - cw); + sy = Math.random(0) * (bg.height - ch); + bgTick = 0; + } + if (++textTick >= params.textTicks) { + word, bounds = nextText(); + textTick = 0; + } + + p.image(bg, 0, 0, p.windowWidth, p.windowHeight, sx, sy, cw, ch); + drawText(); + }; + + function nextText() { + for (let i = 0; i < Math.random() * params.maxSpawns; i++) { + const word = realText[Math.floor(Math.random() * realText.length)]; + const wx = + p.windowWidth / 2 - + p.textWidth(word) / 2 + + p.random(-params.textSpread, params.textSpread); + const wy = + p.windowHeight / 2 - + p.textAscent() / 2 + + p.random(-params.textSpread, params.textSpread); + const bounds = p.textBounds(word, wx, wy); + return { word, bounds }; + } + } + + function drawText() { + const whitespace = 2; + p.stroke(0, 0, 0, params.textAlpha); + p.fill(255, 255, 255, params.textAlpha); + p.rect( + bounds.x - whitespace, + bounds.y - whitespace, + bounds.w + 2 * whitespace, + bounds.h + 2 * whitespace, + ); + + p.noStroke(); + p.fill(0, 0, 0, params.textAlpha); + p.text(word, wx, wy); + } +}; + +new p5(sketch); diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..73a3a99 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,16 @@ +{ + "name": "noise-fields-frontend", + "version": "1.0.0", + "main": "index.js", + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "p5": "^2.2.2", + "socket.io-client": "^4.8.3" + }, + "devDependencies": { + "lil-gui": "^0.21.0", + "vite": "^8.0.0" + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..698ebc0 --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "noise-fields", + "version": "1.0.0", + "main": "server.js", + "type": "module", + "scripts": { + "dev": "concurrently \"npm:dev:vite\" \"npm run dev:server\"", + "dev:vite": "cd frontend && npx vite", + "dev:server": "node server.js", + "build": "cd frontend && npx vite build", + "start": "node server.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "concurrently": "^9.2.1", + "express": "^5.2.1", + "socket.io": "^4.8.3" + } +} diff --git a/server.js b/server.js new file mode 100644 index 0000000..12f88e6 --- /dev/null +++ b/server.js @@ -0,0 +1,29 @@ + +import express from 'express'; +import http from 'http'; +import { Server } from 'socket.io'; + +const app = express(); +const server = http.createServer(app); +const io = new Server(server, { + cors: { + origin: "http://localhost:5173", // allow Vite frontend + methods: ["GET", "POST"] + } +}); + +// Socket.IO events +io.on("connection", (socket) => { + console.log("Client connected:", socket.id); + + socket.on("paramUpdate", (data) => { + socket.broadcast.emit("paramUpdate", data); + }); + + socket.on("disconnect", () => { + console.log("Client disconnected:", socket.id); + }); +}); + +app.use(express.static('frontend/dist')); +server.listen(3000, () => console.log('Server running on http://localhost')); \ No newline at end of file