Thought it might be fun to dust this section off a bit. Not sure if anybody is actually interested in this and I did a lot of learning as I went, so I can't explain it well, but figured it could be interesting to share. I mentioned all my resources in my (you need an account to see links), the links there would probably be a better source of information than I am, and then you can also judge for yourself how frankensteined this is.
server.js
Code:
const express = require("express");
const fs = require("fs");
const app = express();
app.use(express.static("views"));
// listen for requests :)
let server = app.listen(process.env.PORT, function() {
console.log("Your app is listening on port " + server.address().port);
});
const io = require("socket.io")(server);
io.sockets.on('connection', newConnection);
function newConnection(socket){
console.log("socket: ", socket.id);
let loadedPixels = JSON.parse(fs.readFileSync("pixels.json", 'utf8'));
let loadedColors = JSON.parse(fs.readFileSync("colorList.json", 'utf8'));
let pixelData = {currentPixels : loadedPixels, currentColors : loadedColors}
socket.emit('init', pixelData);
socket.on('mouseClicked', mouseMsg);
function mouseMsg(data) {
data.pixels[data.xpos][data.ypos] = data.currColor;
let buf = new Buffer(data.imgData, 'base64');
fs.writeFileSync("tmp/image.png", buf, 'utf8', { flag: 'w' });
fs.writeFileSync("pixels.json", JSON.stringify(data.pixels), 'utf8', { flag: 'w' });
fs.writeFileSync("colorList.json", JSON.stringify(data.colorList), 'utf8', { flag: 'w' });
// socket.broadcast.emit('mouseClicked', data);
io.sockets.emit('mouseClicked', data);
}
}
views/sketch.js*
Code:
let colPic;
let colorList;
let colorDict;
let pixels = [];
let w;
let h;
const socket = io.connect();
socket.on('init',loadPixels);
function loadPixels(data){
pixels = data.currentPixels;
console.log(pixels[0][0])
}
socket.on('mouseClicked', newPixels);
function newPixels (data) {
let xp = data.xpos;
let yp = data.ypos;
let cc = data.currColor;
pixels[xp][yp] = cc;
}
// var scale = 10;
function init() {}
function setup() {
var c;
w = 1580;
h = 200;
c = createCanvas(w, h);
for (let x = 0; x < w / 10; x++) {
pixels.push([]);
for (let y = 0; y < h / 10; y++) {
pixels[x].push([255, 255, 255]);
}
}
c.parent("sketch");
strokeWeight(10);
colPic = createColorPicker("black");
colPic.position(200, 320);
colPic.size(100, 100);
colorList = [];
colorDict = {};
}
function draw() {
strokeWeight(1);
stroke(255);
if (colorList.length > 255) {
var lastCol = colorList.pop();
delete colorDict[lastCol];
}
for (let x = 0; x < w / 10; x++) {
for (let y = 0; y < h / 10; y++) {
let xpos = x * 10 ;
let ypos = y * 10 ;
fill(pixels[x][y][0], pixels[x][y][1], pixels[x][y][2]);
rect(xpos, ypos, 10, 10);
}
}
}
function mouseClicked() {
let xpos = Math.floor(mouseX / 10);
let ypos = Math.floor(mouseY / 10);
let currColor = colPic.color().levels;
if (
colorList.find(
el =>
el[0] == currColor[0] && el[1] == currColor[1] && el[2] == currColor[2]
)
) {
} else {
colorList.push(currColor);
}
if (colorList.length > 255) {
let byebitch = colorList.shift();
for (let x = 0; x < w / 10; x++) {
pixels.push([]);
for (let y = 0; y < h / 10; y++) {
if (
pixels[x][y][0] == byebitch[0] &&
pixels[x][y][1] == byebitch[1] &&
pixels[x][y][2] == byebitch[2]
) {
pixels[x][y] = [255, 255, 255];
}
}
}
}
let img = canvas.toDataURL();
let imgData = img.replace(/^data:image\/\w+;base64,/, "");
let data = {
pixels : pixels,
xpos: xpos,
ypos: ypos,
currColor : currColor,
colorList : colorList,
imgData : imgData
}
socket.emit('mouseClicked', data);
}
package.json
Code:
{
"name": "p5-js",
"version": "0.0.1",
"description": "p5.js Demo",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.17.1",
"socket.io": "^3.1.0",
"express-fileupload": "^1.2.1"
},
"engines": {
"node": "14.x"
},
"keywords": [
"node",
"express"
],
"license": "LGPL-2.1"
}
views/index.html
Code:
<!DOCTYPE html>
<html>
<head>
<title>ryuuuuuuuuuu</title>
<link rel="stylesheet" type="text/css" href="style.css" />
<meta charset="utf-8" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.0.5/socket.io.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/addons/p5.sound.min.js"></script>
<script
src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
integrity="sha256-4+XzXVhsDmqanXGHaHvgh1gMQKX40OUvDEBTu8JcmNs="
crossorigin="anonymous"></script>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.1.9/p5.js"></script> -->
<script src="/sketch.js" defer></script>
</head>
<body style="background-color: #111;">
<header>
<h1 style="color: #4405a1;">
~~ let's all make a ryu scene together ~~
</h1>
</header>
<!-- <img src="https://cdn.glitch.com/4e186ba1-294e-41c8-8ead-e5ae4e16233e%2Fimage.png"> -->
<div id="sketch"></div>
<!-- <div class="glitchButton" style="position:fixed;top:20px;right:20px;"></div> -->
<script
src="https://button.glitch.me/button.js"
data-style="glitch"
>
</script>
<script>
</script>
</body>
</html>
I didn't include any of the other JSON because it's just RGB values for pixels upon pixels, but this is the bulk of what makes it work.
If for any reason you want to look at the whole thing, I have a remix of it you're welcome to look at, just let me know a ck-friendly glitch account and I'll invite you to view/edit it.
*I don't know why sketch.js was in `/views/` but I forked a sample project with p5js set up in glitch and that's how it was and I never bothered to move it even though that's not how I would personally have set it up.