example code comments, homework week 5
<canvas id="glitch_self_portrait"></canvas>
<script type="module">
// getting canvas element
const cnv = document.getElementById (`glitch_self_portrait`)
// sizing to be good size
cnv.width = cnv.parentNode.scrollWidth
cnv.height = cnv.width * 9 / 16
// setting background colour
cnv.style.backgroundColor = `deeppink`
// getting canvas context
const ctx = cnv.getContext (`2d`)
// instatiating variable for image data
let img_data
// defining a function that draws an image to the canvas
const draw = i => ctx.drawImage (i, 0, 0, cnv.width, cnv.height)
// creating a new image element
const img = new Image ()
// define function to execute upon loading image file
img.onload = () => {
// resizing the height of the canvas
// to be same aspect ratio as image
cnv.height = cnv.width * (img.height / img.width)
// drawing the image to the canvas
draw (img)
// storing image data as string in img_data
img_data = cnv.toDataURL ("image/jpeg")
// call the glitch function
add_glitch ()
}
// give filepath to image element
img.src = `/240405/pfp_glasses.jpg`
// define a function that returns a random value between 0 - max
const rand_int = max => Math.floor (Math.random () * max)
// define a recursive function
const glitchify = (data, chunk_max, repeats) => {
// random multiple of 4 between 0 - chunk_max
const chunk_size = rand_int (chunk_max / 4) * 4
// random position in the data between 24 - chunk_size
const i = rand_int (data.length - 24 - chunk_size) + 24
// grabbing all the data before the random position
const front = data.slice (0, i)
// leaving a gap the size of chunk_size
// grabbing the rest of the data
const back = data.slice (i + chunk_size, data.length)
// putting the two pieces back together
// leaving out a chunk
const result = front + back
// ternary operator to return result if repeats == 0
// otherwise call itself again with repeats - 1
return repeats == 0 ? result : glitchify (result, chunk_max, repeats - 1)
}
// instantiate empty array for glitched images
const glitch_arr = []
// define function that adds a glitched image
// to the glitch_arr array
const add_glitch = () => {
// make new image element
const i = new Image ()
// define function that executes when image recieves its data
i.onload = () => {
// push the image into the glitch_arr array
glitch_arr.push (i)
// call itself until there are 12 glitched images
if (glitch_arr.length < 12) add_glitch ()
// once there 12 images, start animating
else draw_frame ()
}
// give the new image some glitchified image data
i.src = glitchify (img_data, 96, 6)
}
// instantiate variable to keep track of glitch state
let is_glitching = false
// keep track of which glitched image from the array we are using
let glitch_i = 0
const draw_frame = () => {
// check to see if we are glitching
// if so, draw the glitched image from the array
if (is_glitching) draw (glitch_arr[glitch_i])
// otherwise draw the regular image
else draw (img)
// probability weightings for starting and stopping the glitch
const prob = is_glitching ? 0.05 : 0.02
// if random value is less than weighted value
if (Math.random () < prob) {
// choose a random glitched image index
glitch_i = rand_int (glitch_arr.length)
// flip the state of is_glitching
is_glitching = !is_glitching
}
// call the next animation frame
requestAnimationFrame (draw_frame)
}
</script>