Skip to content

Latest commit

 

History

History
608 lines (486 loc) · 13.9 KB

slides.md

File metadata and controls

608 lines (486 loc) · 13.9 KB

Doodling

with the Canvas API



https://knowuh.github.io/2019-nerd-doodle/

github

[related code pen example](https://codepen.io/knowuh/pen/GeEEMb?editors=0010)

# What is this talk? * Introduction to creative coding * Highlights from a class * For newbies * For cranky old-timers ## deets * [Canvas 2d api](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API) * Raw Javascript * Live mistakes * Visual tricks * Art history * Resources

## Why sketch with code?
  • Educational
  • Happy accidents
  • Brain benefits*

* I am not a doctor

"I like to think of play not as an activity, but as an attitude, a way of engaging with the world"
– *Mitchel Resnick* (@mres)

# Early Computer artists
Frieder Nake – Mathemetician
George Nees – Math & Philosophy
Vera Molnar – Artist
Vera Molnar – Artist
Vera Molnar – Artist
#### VLW / ACG

Point of departure: ~1970

## canvas

context

One-page sketch template

  <html>
    <head></head>
    <body>
      <canvas width="500" height="500"></canvas>
    </body>
    <script>

      // what we are doing is all in between these script tags
      var canvas = document.querySelector('canvas');
      var context = canvas.getContext('2d');

    </script>
  </html>
## Square on a canvas demo
    // Easy way to draw a square:  
    context.strokeRect(10, 10, 100, 100);

    // The hard way
    context.strokeStyle = "black";
    context.beginPath();
    context.moveTo(10,10);
    context.lineTo(100,10);
    context.lineTo(100,100);
    context.lineTo(10,100);
    context.lineTo(10,10);
    context.stroke();
## 01 ## Multiple Squares demo
    // Draw a square at x,y of size:
    function drawSquare (xLoc, yLoc, size) {
      context.beginPath();
      context.moveTo(xLoc       ,  yLoc       );
      context.lineTo(xLoc + size,  yLoc       );
      context.lineTo(xLoc + size,  yLoc + size);
      context.lineTo(xLoc       ,  yLoc + size);
      context.closePath();
      context.stroke();
    }

    // draw some squares
    var squareSize = 100;
    drawSquare(10, 10, squareSize);
    drawSquare(120, 10, squareSize);
## 02 ## Squares on a Grid

demo

    var squareSize = 140;
    var padding = 10;

    // Draw a square at grid-y grid-y:
    function drawSquare(gridX, gridY) {
      var startX = gridX * (squareSize + padding) + padding;
      var startY = gridY * (squareSize + padding) + padding;
      context.beginPath();
      context.moveTo(startX,               startY);
      context.lineTo(startX + squareSize,  startY);
      context.lineTo(startX + squareSize,  startY + squareSize) ;
      context.lineTo(startX,               startY + squareSize) ;
      context.closePath();
      context.stroke();
    }

    drawSquare(0, 0);
    drawSquare(1, 0);
    drawSquare(2, 1);
    drawSquare(0, 2);
## 03 ## Loop it demo
   // hella squares:
    var x, y;
    var numWide = 4;
    var numTall = 4;
    for(x=0; x < numWide; x++) {
      for(y=0; y < numTall; y++) {
        drawSquare(x,y);
      }
    }
## 04 #### *--record scratch--* ## Context & Transforms ### Remember this? ## We can change it with: * `context.save()` * `context.tranlate(…)` * `context.rotate(…)` * `context.scale(…)` * `context.transform(…)` * `context.restore()` ## Make it big demo
    // ★ The only grid-size variables :
    var marginScale = 0.9;
    var numColumns = 3;

    // ★ context.translate(…) to center the grid
    function adjustMargins () {
      var size = gridSize * numColumns;
      var extraSpaceX = canvas.width - size;
      var extraSpaceY = canvas.height - size;
      context.translate(extraSpaceX/2, extraSpaceY/2);
      if (canvas.width > canvas.height) {
        gridSize = canvas.height / numColumns;
      }
      else {
        gridSize = canvas.width / numColumns;
      }
    }

    // ★ record the new window size
    function resize() {
      var {width: w, height: h}  = canvas.getBoundingClientRect();
      canvas.width = w;
      canvas.height = h;
      setgridSize();
      draw();
    }

    // ★ When the window is resized, redraw …
    window.addEventListener("resize", resize);

    // ★ Align a drawing function with the grid
    function drawInGrid (gridX, gridY, drawingFunction) {
      var halfGrid = gridSize / 2;
      context.save();
      context.translate(gridX * gridSize + halfGrid, gridY * gridSize + halfGrid);
      context.scale(marginScale, marginScale);
      drawingFunction();
      context.restore();
    }

    // ★ Before we draw, measure everything
    function draw () {
      setgridSize();
      adjustMargins();
      context.save();
      var x, y;
      for(x=0; x < numColumns; x++) {
        for(y=0; y < numColumns; y++) {
          drawInGrid(x, y, veraSquare);
        }
      }
      context.restore();
    }
##### 05 ## Moar loops demo ```javascript function veraSquare() { var i = 0; var numSquares = 10; var stepSize = 1 / numSquares; // sale from 0 to 1 in numSquares steps for (i = 0; i <= 1; i += stepSize) { context.save(); context.scale(i, i); drawSquare(); context.restore(); } } ``` ##### 06 ### Imperfectionz & randomnez demo
  function randomNudge(gridFraction) {
    var randAmount = gridSize * gridFraction;
    return randAmount - Math.random() * (randAmount/2)
  }

  function drawSquare () {
    var halfGrid = gridSize / 2;
    var wiggleFraction = 0.3;

    var startX = - halfGrid + randomNudge(wiggleFraction) ;
    var startY = - halfGrid + randomNudge(wiggleFraction) ;
    var endX = halfGrid + randomNudge(wiggleFraction) ;
    var endY = halfGrid + randomNudge(wiggleFraction) ;

    context.beginPath();

    context.moveTo(startX, startY);
    context.lineTo(endX,   startY);
    context.lineTo(endX,   endY);
    context.lineTo(startX, endY) ;

    context.closePath();
    context.stroke();
  }
##### 07 ## Parameters and Variations demo
  function drawSquare (gridX, gridY) {

    var wiggleFraction = gridY / numColumns / 2

    var halfGrid = gridSize / 2;
    var startX = - halfGrid + randomNudge(wiggleFraction) ;
    var startY = - halfGrid + randomNudge(wiggleFraction) ;
    var endX = halfGrid + randomNudge(wiggleFraction) ;
    var endY = halfGrid + randomNudge(wiggleFraction) ;
    
  }
##### 08 ## HSLA Colors demo
  function getColor(hue,  sat, light, alpha) {
    var h = hue * 360; // Hue space is color wheel 360 deg
    var s = sat * 100;
    var l = light * 100;
    return `hsla(${h}, ${s}%, ${l}%, ${alpha})`
  }

  // … later
  var h = gridX / numColumns;
  var s = 0.5;
  var l = gridY / numColumns;
  var a = 0.15;

  context.fillStyle = getColor(h, s, l, a); // ★
##### 09

wait what?

# No Spirograph??! ## Polar to Cartesian * x = r × cos(θ) * y = r × sin(θ)

Or just use `context.rotate()`

radial drawing

demo
  var increment = (2 * Math.PI) / numPoints;

  context.save();
  context.beginPath();
  context.moveTo(0, maxRadius * radii[0]);

  for (i= 0; i < radii.length; i++) {
    context.lineTo(0, maxRadius * radii[i]);
    context.rotate(increment);
  }

  context.closePath();
  context.stroke();
  context.restore();
## Put it together demo ## Postscript: Animation demo # Accelerated Art School * Sketch. * Use arbitrary constraints. * Learn about Gestalt principles. * Some quick tips. ## Sketching: * On paper. * Many examples quickly. * Disposable. * Generate questions. * Process not product.



Sketch. All. The. Time.

## Constraints By holding some things constant, we focus on the possibilities of the remaining parameters. * Music * [Haiku](https://en.wikipedia.org/wiki/Haiku) * [Dogme films](https://en.m.wikipedia.org/wiki/Dogme_95) * eg: only paint 2" squares * eg: only 400 pixels * eg: only black and white ## Gestalt principles of design
The Gestalt principles are a set of laws arising from 1920s' psychology, describing how humans typically see objects by grouping similar elements, recognizing patterns and simplifying complex images. Designers use these to engage users via powerful -yet natural- "tricks" of perspective and best practice design standards.
## Gestlat principles of design * Gestalt principles are real. They are grounded in the *mechanics* of human perception. * Art, design, and [Optical illusions](https://en.wikipedia.org/wiki/Optical_illusion) exploit artifacts of human perception. ## Some Gestalt principles are …
  • Closure: Our brain fills in gaps.
  • Proximity: We group closer-together elements.
  • Continuation: We follow lines.
  • Similarity: We look for differences and commonality of shape.
proximity closure * ["Primer of Visual Literacy"](https://www.amazon.com/Primer-Visual-Literacy-Donis-Dondis/dp/0262540290) by Donis A. Dondis. ## Quick Tips: * Curate & crop * Contrasting elements * Accidents * Steal and **give credit**

Make it **Big**. Make it **red**. Or make **many** of them. 😅

Note:

  • Take 1000 photographs, and choose one.
  • Crop: Your initial framing will be wrong. Direct attention. Cut out noise.
  • Contrast: What is the focus, what will stand out?
  • Accidents: Investigate, celebrate, incorporate your accidents.
  • Fake it: It's art. It's all fake. Their is no purity, it's all for show.
# Questions? ## Resources: This talk: ## Resources: low-friction tools ## Resources: inspirational teachers: ## Resources: documentation & frameworks # ★ Thank you! ★

[email protected]

@knowuh