Date: 2020.07.20 | datgui | images | p5js | typescript |
DISCLOSURE: If you buy through affiliate links, I may earn a small commission. (disclosures)
I do a lot of personal coding projects using images. I often use datgui as a quick, easy way to parameterize these projects. When you put them together, that also means that I'm often dealing with file inputs and like to put buttons for that in the gui so it's all in one place and out of the way.
I'm going to break down how I load files into my P5js + Typescript projects when a user clicks a button in datgui.
I'm using parcel to package up my code, so your import code may look a bit different depending on your build process. The p5js sketch itself is in instance mode though so everything else should look almost exactly the same. If you're using vanilla javascript instead of Typescript, that's cool too - I think the only things that would change are the imports and the removal of types.
At a high level, here's what's going on:
The code:
import * as dat from 'dat.gui'
import P5 from "p5"
export const sketch = (sketch: P5) => {
let params = {
loadSourceImage: () => {
console.log('hamy - source image')
sourceInputElement.click()
},
}
let gui: any
let sourceInputElement: HTMLInputElement
let sourceP5Image: P5.Image = null
sketch.setup = () => {
sketch.createCanvas(sketch.windowWidth, sketch.windowHeight)
sketch.frameRate(30)
sketch.angleMode(sketch.DEGREES)
sourceInputElement = createHiddenFileInputElement()
sourceInputElement.onchange = handleSourceInputElement
gui = new dat.GUI()
gui.add(params, 'loadSourceImage').name('Load source')
}
sketch.draw = () => {
sketch.background(0)
}
const handleSourceInputElement = (event) => {
let fileUrls = getLocalUrlsFromFileInput(event)
sourceP5Image = sketch.loadImage(
fileUrls[0],
img => {
console.log('hamy - image finished loading')
}
)
}
const getLocalUrlsFromFileInput = (event) => {
console.log('hamy - file input!')
let files = event.target.files
let localUrls: Array<string> = []
console.log(files)
for(let file of files) {
let localUrl = URL.createObjectURL(file)
localUrls.push(localUrl)
console.log('hamy - loading file')
}
return localUrls
}
const createHiddenFileInputElement = (): HTMLInputElement => {
let inputElement = document.createElement('input')
inputElement.type = 'file'
inputElement.style.visibility = 'hidden'
inputElement.setAttribute('multiple', 'true')
document.body.appendChild(inputElement)
return inputElement
}
}
Happy coding!
The best way to support my work is to like / comment / share for the algorithm and subscribe for future updates.