The technical strategies chapter for the visual narrative website includes utilizing personal & collaborative strength which includes audio, photography, and illustration, coding on the p5.js editor and the website, project resources, and a conclusion. This section focuses on the technical aspect of creating the visual narrative website. It gives you a brief demonstration of the techniques and tools I used.
I chose to incorporate illustrations since it is something I am very comfortable with. Although the process takes time, unlike coding it is something I can work on entirely by myself with confidence. I thought that including illustrated elements would bring further visual cohesion to the website as well as a sense of texture and authenticity.
I decided to collaborate with photographer and documentary artist Kestin Mica since I always knew that he enjoys working on creative and documentative photography projects. It is great to collaborate with other artists and create projects that are visually unique to that collaboration. With his collaboration, we were able to incorporate audio recordings and film photography.
The coding portion of the visual narrative website included using the p5.js editor and later moving them to a local development environment where I integrated the p5.js sketches onto a local website. The p5.js editor was used to create an audio visualizer, timed subtitles, and interactive images. I used GitHub to document changes and host the website. EventListener and namespacing were used to add further interactions between the JavaScript files and HTML files. I also used GitHub's Issue to post coding issues and contribute to open-source,
let myAudio, fft, img;
function preload() {
myAudio = loadSound("smells.mp3");
img = loadImage("hatsue-10.jpg");
}
function setup() {
createCanvas(400, 400);
fft = new p5.FFT(0.9, 64); //Create a new FFT analysis
myAudio.play();
}
function draw() {
background(255);
image(img, 0, 0);
let spectrum = fft.analyze(); //spectrum analysis
noStroke();
for (let i = 0; i < spectrum.length; i++) {
let x = map(i, 0, spectrum.length, 0, width);
fill(spectrum[i] * 1.5 + 50, 173, 159, 80);
rect(x, 0, width / spectrum.length, height);
}
}
index
. (To learn about arrays, see this tutorial by The Coding Train.)
let subtitleArray = [];
let index = 0;
function showText() {
subtitle.html(subtitleArray[index]);
}
function incertText() {
subtitleArray.push("So I’m very attached to smells", "and so there’s a
lot of specific smells", "that I associate with many different things.",
"Like the bathroom in the beginning",
"it kind of smelled like my grandma’s bathroom"...);
}
currentTime()
mouseclicked()
and
console.log()
to document the
timing of the subtitles while playing the audio. Use the variable
index
to view and switch the text.
// when the mouse is clicked, add 1 to the index and print the current time
// of the audio track in the console.
function mouseClicked() {
index = index + 1
console.log(myAudio.currentTime());
}
let subtitleCueArray = [];
function incertCue() {
subtitleCueArray.push(
0,
2.3684126984126985,
4.969047619047619,
7.865736961451248,
10.419931972789115,
12.718707482993198, ...)
}
index
each time the audio's
currentTime()
exceeds the corresponding documented time which is stored in the array. (To learn about for loops, see this tutorial by The Coding Train.)
function timeSubtitles() {
for (let i = 0; i < subtitleCueArray.length; i ++){
if (myAudio.currentTime()>=subtitleCueArray[i]){
index = i;
}
}
}
tint()
map()
and mouseX, mouseY
to change the opacity of the image based on the cursor position.
// create a tint value for each image that shows the image when the cursor
// is at one corner and hides the image as the cursor moves away.
tint2 = map((mouseX)*-1+mouseY, width-100, 0, 255, 0);
tint1 = map(mouseX+mouseY, 100, width, 255, 0);
tint3 = map(mouseX+(mouseY)*-1, width-100, 0, 255, 0);
tint4 = map(mouseY-(mouseX)*-1, width-100, 0, 255, 0);
tint(255,tint4);
image(img4, 0, 0, width, height);
tint(255, tint1);
image(img1, 0, 0, width, height);
tint(255, tint2);
image(img2, 0, 0, width, height);
tint(255,tint3);
image(img3, 0, 0, width, height);
mouseX, mouseY
to a tint value
between 0 and 255 was a bit tricky for me to understand. I ended up just
guessing and seeing what works.clickable-1
to the thumbnail element..getElementById
to select the id from the HTML document..addEventListener
to listen for when the id is clicked.showCanvas()
to make the p5.js canvas visible
when the canvas id is clicked. To do so, select the default canvas id name
defaultCanvas0
and style the CSS to be
visibility: visible;
function setup() {
...
document.getElementById("clickable-1")
.addEventListener("click", showAndSwitchElementsForSketch1);
document.getElementById("button-exit")
.addEventListener("click",hideCanvas);
}
function showCanvas(){
document.getElementById("defaultCanvas0").style.visibility="visible";
document.getElementById("container").style.visibility="visible";
}
function hideCanvas() {
pauseAnyAudio();
document.getElementById("defaultCanvas0").style.visibility="hidden";
document.getElementById("container").style.visibility="hidden";
}
function showAndSwitchElementsForSketch1() {
showCanvas();
display = 1;
elementsForSketchArray[0].controlButton1();
}
...
function draw() {
background(255);
displayImgTimerSubtitle();
//audio visualizer
let spectrum = fft.analyze();
noStroke();
for (let i = 0; i < spectrum.length; i++) {
let x = map(i, 0, spectrum.length, 0, width);
let h = map(spectrum[i], 0, 255, 0, height);
fill(spectrum[i] * 1.5 + 50, 173, 159, 80);
rect(x, 0, width / spectrum.length, height);
}
}
p.draw = () => {
p.background(255);
p.displayImgTimerSubtitle();
//audio visualizer
p.spectrum = p.fft.analyze();
p.noStroke();
for (let i = 0; i < p.spectrum.length; i++) {
p.x = p.map(i, 0, p.spectrum.length, 0, p.width);
p.fill(p.spectrum[i] * 1.5 + 50, 173, 159, 80);
p.rect(p.x, 0, p.width / p.spectrum.length, p.height);
}
}
As a beginner coder, this was an amazing opportunity to continue learning and advancing in creative coding. I always find it incredibly helpful to have mentors and teachers who can guide you through having a better understanding of the processing environment. It was also a great experience to contribute to open-source processing and be a part of public discourse to solve issues and help the processing community.
This project has allowed me to have a better idea of what I could do with creative coding. Now I feel that another career path besides Graphic Design has opened up to me. I hope to continue creating collaborative projects with programming and further contribute to the open-source creative coding community.