 rgb(0,0,0)



 ## Page Not Found

### Students, staff, or faculty? Please try [my.ocadu.ca](http://my.ocadu.ca).



 

 

 

 

  

 

  

 


#paragraph-id--7869 .layout {
    background-color: transparent !important;
    position: absolute;
    top: 40px;
    z-index: 99;
    text-align: center;
    display: flex;
    align-items: center;
    width: 100%;
    height: 50vw;
}
@media (max-width: 900px) {
    #paragraph-id--7869 .layout {
        top: 86px !important;
    }
}
#text-id--7867 {
    background: black;
    padding: 4rem;
    width: 90%;
    max-width: 777px;
    margin: 0 auto;
}
#shader {
    width: 100%;
    height: 50%;
    position: relative;
}
#canvas {
    display: block;
    width: 100%;
    height: 100%;
}


let term = window.location.href.substring(window.location.href.lastIndexOf('/') + 1)
term = decodeURIComponent(term)
term = term.replace(/[^a-zA-Z0-9 ]/g, ' ')
const txt = document.querySelector('#text-id--7867 .field--paragraph.field--text-long')
const srch = document.createElement('h3');
srch.innerHTML = `Search ocadu.ca for "<a href="/search?fulltext=${term}">${term}".`
srch.style.marginTop = "18px"
txt.append(srch)

/*****
// Setup the canvas.
*****/
const gl = canvas.getContext('webgl2', { antialias: true, preserveDrawingBuffer: true })


/*****
// Declare global variables and constants.
*****/
let program
let ctime = 0
let ptime = 0
let pdelta = 0
let paused = false
const themeColors = ["blue", "red", "green", "orange", "purple", "lightblue", "yellow"]

const patterns = [
  `// lines 
   uv.x=1.0;
   vec2 grid = vec2(1.0, 60.0);
   pattern = smoothstep(.2, 0.01, sin(grid.x*uv.x) * sin(grid.y*uv.y));`,
  
  `// sunburst
   float angle = atan(uv.y, uv.x);
   pattern = smoothstep(0.2, 0.01, sin(angle * 45.0));`,

  `// concentric circles
   float dist = length(uv);
   pattern = smoothstep(0.2, 0.01, sin(dist * 45.0));`,

  `// checkboard
   vec2 grid = vec2(60.0, 60.0);
   pattern = smoothstep(.2, 0.01, sin(grid.x*uv.x) * sin(grid.y*uv.y));`,

  `// hex grid
   vec2 uv2 = uv * 10.0;
   uv2.x *= 0.866; // sqrt(3)/2 to correct aspect
   vec2 hexID = floor(uv2);
   if (mod(hexID.y, 1.0) == 1.0) { uv2.x += 0.5; }
   vec2 hexUV = fract(uv2) - 0.5;
   float dist = max(abs(hexUV.x) * 1.732, abs(hexUV.y));
   dist = max(dist, abs(hexUV.x * 1.732 + hexUV.y));
   pattern = smoothstep(0.5, 0.48, dist);`,
    
  `// dots
   vec2 grid = vec2(27.0, 27.0);
   vec2 gridUV = fract(uv * grid) - vec2(0.5);
   float dist = length(gridUV);
   pattern = smoothstep(0.3, 0.28, dist);`,
    
  `// triangles
   vec2 grid = vec2(24.0);
   vec2 id = floor(uv * grid);
   vec2 gv = fract(uv * grid);
   float checker = mod(id.x + id.y, 2.0);
   float diag1 = step(gv.x, gv.y);
   float diag2 = step(1.0 - gv.x, gv.y);
   pattern = checker * diag1 + (1.0 - checker) * diag2;`]


/*****
// Handle window resize.
*****/
const resize = () => {
  canvas.width = window.innerWidth - 100
  canvas.height = window.innerHeight - 100
  canvas.style.width = canvas.style.height = 100 + '%'
}
window.addEventListener('resize', resize)



/*****
// Compile shaders.
*****/
const compileShader = (gl, shaderSource, shaderType) => {
  const shader = gl.createShader(shaderType)
  gl.shaderSource(shader, shaderSource)
  gl.compileShader(shader)
  const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS)
  if (!success) {
    throw "could not compile shader:" + gl.getShaderInfoLog(shader)
  }
  return shader;
}



/*****
// Create shader program.
*****/
const createProgram = (gl, vertexShader, fragmentShader) => {
  const program = gl.createProgram()
  gl.attachShader(program, vertexShader)
  gl.attachShader(program, fragmentShader)
  gl.linkProgram(program)
  const success = gl.getProgramParameter(program, gl.LINK_STATUS);
  if (!success) {
    throw ("program failed to link:" + gl.getProgramInfoLog (program))
  }  
  return program
}



/*****
// Initalize and send shaders to be compiled.
*****/
const init = () => {
  const vertices = new Float32Array([-1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1])

  const vertexBuffer = gl.createBuffer()
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
  gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)

  const v = compileShader(gl, vertexShaderSource, gl.VERTEX_SHADER)
  const f = compileShader(gl, fragmentShaderSource, gl.FRAGMENT_SHADER)
  program = createProgram(gl, v, f)
      
  program.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition')
  gl.enableVertexAttribArray(program.aVertexPosition)
  gl.vertexAttribPointer(program.aVertexPosition, 2, gl.FLOAT, false, 0, 0)

  gl.useProgram(program)

  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
}



/*****
// Render the shader, only if unpaused.
*****/
const render = (time) => {
  gl.viewport(0, 0, canvas.width, canvas.height)
  gl.clearColor(1, 1, 1, 1)
  gl.clear(gl.COLOR_BUFFER_BIT)

  program.uPosition = gl.getUniformLocation(program, 'u_resolution')
  gl.uniform2fv(program.uPosition, [gl.canvas.width, gl.canvas.height])

  program.uTime = gl.getUniformLocation(program, 'u_time')
  gl.uniform1f(program.uTime, ctime * 0.001)

  gl.drawArrays(gl.TRIANGLES, 0, 6)
  
  if(!paused) {
    ctime = time - pdelta;
    requestAnimationFrame(render)
  }
}



/******
// Handle motion settings.
******/
const pause = () => {
  paused = true
  ptime = performance.now()
};

const unpause = () => {
  paused = false
  pdelta += performance.now()-ptime
  ptime = 0.0
  requestAnimationFrame(render)
};

const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
const handleMotionChange = (e) => {
  console.log(e.matches)
    if (e.matches) {
        pause()
    } else {
        unpause()
    }
}
handleMotionChange(prefersReducedMotion);
prefersReducedMotion.addEventListener('change', handleMotionChange);

document.addEventListener("mousedown", () => {
  if (!prefersReducedMotion.matches) {
    if (!paused) { 
      pause()
    } else {
      unpause()
    }
  }
});



/*****
// Shaders as template strings.
*****/
const vertexShaderSource = 
`attribute vec2 aVertexPosition;
void main() {
  gl_Position = vec4(aVertexPosition, 0.0, 1.0);
}
`

const fragmentShaderSource = 
`#ifdef GL_ES
precision highp float;
#endif

uniform float u_time;
uniform vec2 u_resolution;

mat2 Rot(float a) {
  float s=sin(a), c=cos(a);
  return mat2(c, -s, s, c);
}

vec3 permute(vec3 x){return mod(((x*34.)+1.)*x,289.);}
float snoise(vec2 v){
    const vec4 C=vec4(.211324865405187,.366025403784439,
    -.577350269189626,.024390243902439);
    vec2 i=floor(v+dot(v,C.yy));
    vec2 x0=v-i+dot(i,C.xx);
    vec2 i1;
    i1=(x0.x>x0.y)?vec2(1.,0.):vec2(0.,1.);
    vec4 x12=x0.xyxy+C.xxzz;
    x12.xy-=i1;
    i=mod(i,289.);
    vec3 p=permute(permute(i.y+vec3(0.,i1.y,1.))
    +i.x+vec3(0.,i1.x,1.));
    vec3 m=max(.5-vec3(dot(x0,x0),dot(x12.xy,x12.xy),
    dot(x12.zw,x12.zw)),0.);
    m=m*m;
    m=m*m;
    vec3 x=2.*fract(p*C.www)-1.;
    vec3 h=abs(x)-.5;
    vec3 ox=floor(x+.5);
    vec3 a0=x-ox;
    m*=1.79284291400159-.85373472095314*(a0*a0+h*h);
    vec3 g;
    g.x=a0.x*x0.x+h.x*x0.y;
    g.yz=a0.yz*x12.xz+h.yz*x12.yw;
    return 130.*dot(m,g);
}

void main() {
    vec2 uv = (2.0*(gl_FragCoord.xy)-u_resolution.xy)/min(u_resolution.x, u_resolution.y);   
    
    uv*=Rot(${Math.random()*Math.PI*2});
    uv.x+=snoise(1.+uv+vec2(1.,u_time*.1))*.15;
    uv.y+=snoise(1.+uv+vec2(-u_time*.05,1.))*.15;

    vec3 col = vec3(0.0);
    float pattern = 0.0;

    vec3 blue = vec3(0.02,0.424,0.976);
    vec3 red = vec3(0.973,0.078,0.137);
    vec3 green = vec3(0.235,0.671,0.286);
    vec3 orange = vec3(0.949,0.388,0.137);
    vec3 purple = vec3(0.627,0.078,0.925);
    vec3 lightblue = vec3(0.102,0.69,0.965);
    vec3 yellow = vec3(0.965,0.996,0.31);
    
    ${patterns[Math.floor(Math.random() * patterns.length)]}
    col = pattern * ${themeColors[Math.floor(Math.random() * themeColors.length)]};
        
    gl_FragColor = vec4(col,1.0);
}
`


/******
// Init program.
*****/
init()
resize()
render()