Hey,
Sorry this took me a shockingly long time to reply to. Yes, with some help I managed to get it working. Here is my code from the JS file:
//This section sets up mifir land sketch and Uma people sketch
//"Terrain" and "g̛li̸tch͏" have been modified and converted into instance (or namespace) mode, and wrapped in functions which are then called in passages with 'window.setup'
//dotGUI allows the audience to interact with and configure the properties of the land sketch, further exploring the piece's themes of performative identity
//Mifir land sketch: "Terrain" by Tiagohttp://www.openprocessing.org/sketch/729536Licensed under Creative Commons Attribution ShareAlikehttps://creativecommons.org/licenses/by-sa/3.0https://creativecommons.org/licenses/GPL/2.0/
//Uma people sketch: "g̛li̸tch͏" by Andor Sagahttp://www.openprocessing.org/sketch/725478Licensed under Creative Commons Attribution ShareAlikehttps://creativecommons.org/licenses/by-sa/3.0https://creativecommons.org/licenses/GPL/2.0/
window.setup = window.setup || {};
window.setup.p5Loaded = false;
window.setup.dotGUILoaded = false;
//This wraps it up into a function
(function(){
var p5 = document.createElement("script");
var dotGUI = document.createElement("script");
p5.type ="text/javascript";
dotGUI.type = "text/javascript";
p5.src = "https://cdn.jsdelivr.net/npm/p5@0.8.0/lib/p5.js";
dotGUI.src = "https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.5/dat.gui.min.js";
p5.onload = function() {
window.setup.p5Loaded = true;
};
dotGUI.onload = function() {
window.setup.dotGUILoaded = true;
};
document.head.appendChild(p5);
document.head.appendChild(dotGUI);
}());
//This creates a constant for the UMA sketch
const UMA = function(imgPath){
return function(p){
//Variables
p.img;
p.segments = [];
p.segmentLength;
p.segmentSpacing;
p.numSegments = 60;
p.segmentResolution = 400;
p.heightScale = 150;
p.fadeIn = 0;
p.speed = 0.51;
p.mp = false;
p.mouseIsDown = false;
p.loaded = false;
p.tt = 0;
p.glitchFreq = 0.5;
p.now = 0;
p.lastTime = 0;
p.id = 0;
//This initiates preload function and loads images from the web-server
p.preload = function(){
p.loadImage(imgPath, function(_img) {
p.img = _img;
p.img.loadPixels();
p.loaded = true;
p.segmentSpacing = (p.img.height / p.numSegments);
p.segmentLength = p.img.width;
for (let i = 0; i < p.numSegments; i++) {
p.segments.push(new p.Segment({
pos: { x: 0, y: i },
len: p.segmentLength
}));
}
});
}
p.setup = function(){
p.createCanvas(p.windowWidth, p.windowHeight/1.5);
}
p.update = function(dt){
p.segments.forEach(
s => {
s.update(dt)
}
);
}
p.mousePressed = function(){
p.mouseIsDown = true;
p.glitchFreq = 0.3;
}
p.mouseReleased = ()=>{
p.mouseIsDown = false;
p.glitchFreq = 0.5;
}
p.draw = function(){
if(!p.loaded)
return;
let dt = (p.millis() - p.lastTime) / 1000;
p.lastTime = p.millis();
p.tt += dt;
p.update(dt);
p.fill(0, 250);
p.noStroke();
p.rect(0,0, p.windowWidth, p.windowHeight);
let gridHeight = p.numSegments * p.segmentSpacing;
p.push();
p.heightScale = 60 + (p.sin(p.millis()/1000) / p.TAU) * 50;
p.translate(p.windowWidth / 2 - p.img.width, p.windowHeight / 2 - p.img.height / 2 - 100);
p.scale(2, 1.25);
if(p.mouseIsDown){
p.tint(156,190,48);
p.image(p.img, 0, 0);
}
else{
p.tint(255);
}
let trans = false;
let ss = 0;
p.segments.forEach(s => {
ss++;
let n = 0;
if (ss > 30) {
n = p.noise(p.millis() / 200);
}
s.draw();
});
if (trans) {
p.pop();
}
p.pop();
}
//This creates a class that sets the sketch's visual properties
p.Segment = class Segment {
constructor(cfg) {
Object.assign(this, cfg);
this.t = 0;
this.dist = 0;
this.id = p.id++;
this.nextNoise = 0;
// [x,y, x,y, ...]
// add 2 for a point starting at the very start of the viewport and one of the end.
this.vertices = new Float32Array(p.segmentResolution * 2 + 2);
this.update(0);
}
update(dt) {
this.t += dt * 1;
p.fadeIn += dt * .008;
p.fadeIn = p.constrain(p.fadeIn, 0, 1);
let xSpacing = this.len / p.segmentResolution;
this.pos.y -= dt * p.speed;
this.dist += dt * p.speed;
//if (this.pos.y > img.height / segmentSpacing) {
// this.pos.y -= img.height / segmentSpacing;
//}
if (this.pos.y < 0) {
this.pos.y += p.img.height / p.segmentSpacing;
}
for (let i = 0; i < this.vertices.length; i += 2) {
let x = (i / 2) * xSpacing;
let y = this.pos.y * p.segmentSpacing;
if (p.mp) {
let d = dist(x, y, (p.mouseX - p.windowWidth / 2 + p.windowWidth / 4 + 50) / 2, (p.mouseY - p.windowHeight / 2 + p.windowHeight / 4 + 250) / 2);
if (d < 40) {
let a = (8 / d) * 8;
y += (a > 50) ? 50 : a;
}
}
let col = p.img.get(x, y);
let intensity = col[0] / 255;
this.vertices[i + 0] = x;
this.vertices[i + 1] = y - (intensity) * p.heightScale;
}
}
draw() {
p.strokeWeight(1);
let waves = (p.sin(this.pos.y / 2.0 + this.t ) / p.PI) + 0.5;
let vignette = p.sin(this.pos.y * p.segmentSpacing / p.img.height * p.PI);
p.stroke(255, 255 * p.fadeIn * waves * vignette + 50 * vignette);
// fill(0);
p.noFill();
p.beginShape();
for (let i = 0; i < this.vertices.length; i += 2) {
if (i === 0) {
p.vertex(-1000, this.vertices[i + 1]);
} else if (i + 2 === this.vertices.length) {
p.vertex(10000, this.vertices[i + 1]);
} else {
p.vertex(this.vertices[i + 0], this.vertices[i + 1]);
if (this.id < p.numSegments - 1) {
let s = p.segments[p.id + 1];
p.vertex(this.vertices[i + 0], this.vertices[i + 1]);
}
}
}
p.endShape();
}
}
}
}
//This creates a constant for the Mifir land sketch and declares the variables required
const Mifir = function(p){
p.scale = 20;
p.cols;
p.rows;
p.w = 1400;
p.h = 1000;
p.flightPos = 0;
// let flightSpeed = 0.08;
// let noiseDelta = 0.16;
p.terrain = [];
// let terrainHeight = 112;
p.Controls = function() {
this.flightSpeed = 0.06;
this.noiseDelta = 0.16;
this.terrainHeight = 112;
};
p.controls = new p.Controls();
p.setup =function() {
// createCanvas(displayWidth, displayHeight, WEBGL);
p.createCanvas(p.windowWidth, 720,p.WEBGL);
let gui = new dat.GUI({width: 295});
gui.close();
gui.add(p.controls, 'flightSpeed', 0, 0.4).name("Flight speed").step(0.02);
gui.add(p.controls, 'noiseDelta', 0.05, 0.4).name("Noise delta").step(0.01);
gui.add(p.controls, 'terrainHeight', 0, 200).name("Terrain height").step(1);
p.cols = p.w / p.scale;
p.rows = p.h / p.scale;
for (let x = 0; x < p.cols; ++x) {
p.terrain[x] = [];
}
}
p.draw = function() {
p.flightPos -= p.controls.flightSpeed;
p.shiftNoiseSpace();
p.background(0);
p.stroke(255);
p.noFill();
p.rotateX(p.PI / 3);
p.translate((-p.w / 2) + 1, (-p.h / 2) + 30);
for (let y = 0; y < p.rows - 1; ++y) {
p.beginShape(p.TRIANGLE_STRIP);
for (let x = 0; x < p.cols; ++x) {
p.vertex(x * p.scale, y * p.scale, p.terrain[x][y]);
p.vertex(x * p.scale, (y + 1) * p.scale, p.terrain[x][y + 1]);
}
p.endShape();
}
}
p.shiftNoiseSpace = function(){
let yOffset = p.flightPos;
for (let y = 0; y < p.rows; ++y) {
let xOffset = 0;
for (let x = 0; x < p.cols; ++x) {
p.terrain[x][y] = p.map(p.noise(xOffset, yOffset), 0, 1, -p.controls.terrainHeight, p.controls.terrainHeight);
xOffset += p.controls.noiseDelta;
}
yOffset += p.controls.noiseDelta;
}
}
}
let sketches = new Map();
function GenerateSketch(imgPath,canvasID, sketchType)
{
let sketch = GetSketch(imgPath,sketchType)
let newSketch = new p5(sketch,canvasID);
sketches.set(canvasID,newSketch);
return newSketch;
}
function GetSketch(ImgPath, SketchType)
{
switch (SketchType) {
case "UMA":
return UMA(ImgPath);
break;
case "Mifir":
return Mifir;
}
}
function CheckDependeciesStatus()
{
if(!window.setup.p5Loaded || typeof p5 !== 'function' || !window.setup.dotGUILoaded || typeof dat.GUI !== 'function')
return false;
else
return true;
}
let ProcessDependecies = function(callback)
{
console.log("Starting to create sketch!");
if(CheckDependeciesStatus())
{
callback();
return;
}
console.log("Dependecies are not loaded, waiting for them to laod...");
let waitForDependecies = setInterval(() => {
if(CheckDependeciesStatus())
{
console.log("Dependecies are loaded, creating sketch");
clearInterval(waitForDependecies);
callback();
}
}, 100);
}
//When the audience visits a new passage that calls an image and maps graphics onto it to create a sketch in the user's browser, this section deletes the previous one to prevent it running in the background, taking up valuable memory, and causing the game-play to lag
window.setup.DeleteAllSketches = ()=>{
for (let value of sketches.values()){
value.remove();
}
sketches.clear();
}
window.setup.RemoveSketch = (id)=>
{
if(!sketches.has(id))
return;
sketches[id].remove();
sketches.delete(id);
}
window.setup.CreateSketch = {
UMA: (imgPath, canvasID) => ProcessDependecies(()=> {
GenerateSketch(imgPath,canvasID,"UMA");
}),
Mifir: (canvasID) => ProcessDependecies(()=> {
GenerateSketch(null,canvasID,"Mifir");
}),
}
This is the code I would put in passages in which I wanted to execute the ‘Uma People’ sketch properties.
<div id="faceTheGuards"></div><script>window.setup.DeleteAllSketches();window.setup.CreateSketch.UMA("https://racompteur.com/public/images/guards.jpg", "faceTheGuards");</script>
Note: the passage name would need to be “faceTheGuards” and no two passages could have the same name. You’d also need to host images on a server and change the names accordingly.
And this is how I would display the ‘Mifir Land’ sketch:
<div id="powerfulEnemy"></div>
<script>
window.setup.DeleteAllSketches();
window.setup.CreateSketch.Mifir("powerfulEnemy");
</script>
Again, call your passage your equivalent of ‘powerfulEnemy’ here.
Hope this helps someone.