Greetings – puny humans – HTML



Greetings – puny humans – HTML

0 0


presentation


On Github whostolemyhat / presentation

Greetings

puny humans

James Tease / @whostolemyhat

Demo

Do a click on it! Mouse pos is off since canvas isn't top left

Inspiration

Particles are cool

Cogmind

http://www.gridsagegames.com/blog/2014/03/particle-effects/

Code

HTML

<canvas id="canvas" width="800" height="600"></canvas>

id or class to access in JS

width/height: don't resize in CSS! use JS or inline style

<canvas id="canvas" width="300" height="150"></canvas>
<canvas id="canvas" style="height: 400px;width:150px;"></canvas>

Canvas drawing

<canvas id="canvas" width="300" height="150"></canvas>
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');

Canvas drawing

context.beginPath();
// x, y, radius, startAngle, endAngle, antiClockwise
context.arc(150, 75, 20, 0, Math.PI*2, true);
context.closePath();

// colour it in so we can see it
context.fillStyle = '#ff3';
context.fill();

Draw lots

context.beginPath();
context.arc(150, 75, 20, 0, Math.PI*2, true);
context.closePath();
context.fillStyle = '#ff3';
context.fill();

context.beginPath();
context.arc(10, 95, 10, 0, Math.PI*2, true);
context.closePath();
context.fillStyle = '#f33';
context.fill();

context.beginPath();
context.arc(80, 120, 25, 0, Math.PI*2, true);
context.closePath();
context.fillStyle = '#3f3';
context.fill();

context.beginPath();
context.arc(220, 35, 30, 0, Math.PI*2, true);
context.closePath();
context.fillStyle = '#3ff';
context.fill();

Refactor

function drawCircle(context, x, y, radius, colour) {
    context.beginPath();
    context.arc(x, y, radius, 0, Math.PI*2, true);
    context.closePath();
    context.fillStyle = colour;
    context.fill();
}

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');

drawCircle(context, 150, 75, 20, '#ff3');
drawCircle(context, 10, 95, 10, '#f33');
drawCircle(context, 80, 20, 25, '#3f3');
drawCircle(context, 220, 35, 30, '#3ff');

DRY (again)

Tell the particle to make itself

function Particle() {
    this.x = randomHorzPosition();
    this.y = randomVertPosition();
    this.radius = randomSize();
    this.colour = randomColour();
}

function drawCircle(ctx, particle) {
    ctx.beginPath();
    ctx.arc(particle.x, particle.y, particle.radius, 0, Math.PI*2, true);
    ctx.closePath();
    ctx.fillStyle = particle.colour;
    ctx.fill();
}

for(var i = 0; i < 10; i++) {
    drawCircle(new Particle());
}

Animation

The fun stuff

The game loop

  • update
  • draw

The loop

Lots of drawing

60fps = call drawCircle() 60 times per second

setInterval()

var particles = [];
for(var i = 0; i < 10; i++) {
    particles.push(new Particle());
}

setInterval(function() {
    for(var i = 0; i < particles.length; i++) {
        drawCircle(particles[i]);
    }
}, 16); // 1000ms / 60fps = ~16ms

Problems with setInterval

  • Inaccurate (lag)
  • Runs even in background
  • Fixed FPS

requestAnimationFrame

// named function containing rAF
(function animation() {
    // call rAF and pass in your animation loop
    requestAnimationFrame(animation);

    // do all your drawing
    for(var i = 0; i < particles.length; i++) {
            drawCircle(particles[i]);
    }
})(); // IIFE

Movement

  • update
  • draw

Update in each frame

(function animation() {
    requestAnimationFrame(animation);



    for(var i = 0; i < particles.length; i++) {
            var particle = particles[i];

            // update each particle
            particle.x += randomHorzMovement();
            particle.y += randomVertMovement();

            // draw
            drawCircle(particle);
    }
})();
Play

Well, that didn't work

Clear canvas each frame

(function animation() {
    requestAnimationFrame(animation);

    // clear screen
    context.clearRect(0, 0, context.canvas.width, context.canvas.height);

    for(var i = 0; i < particles.length; i++) {
            var particle = particles[i];

            // update each particle
            particle.x += randomHorzMovement();
            particle.y += randomVertMovement();

            // draw
            drawCircle(particle);
    }
})();
Play

Beter, but not quite right

Generate movement on particle creation

function Particle() {
    this.x = randomHorzPosition();
    this.y = randomVertPosition();
    this.velocityX = randomHorzMovememnt();
    this.velocityY = randomVertMovement();

    this.radius = randomSize();
    this.colour = randomColour();
}
Could also use velocity and angle - depends on use case

Particles from a point

Particles should come from the same point

var x = context.canvas.width / 2;
var y = context.canvas.width / 2;

(function animation() {
    requestAnimationFrame(animation);

    // clear screen
    context.clearRect(0, 0, context.canvas.width, context.canvas.height);

    for(var i = 0; i < particles.length; i++) {
            var particle = particles[i];

            // update each particle
            particle.x += particle.velocityX;
            particle.y += particle.velocityY;

            // draw
            drawCircle(particle);
    }
})();
Play

Enough of circles!

Let's use letters

Letters all have character codes

// Find the character code of lowercase a
'a'.charCodeAt(0)
// -> 97

// ... and uppercase
'A'.charCodeAt(0)
// -> 65

Uppercase letters start at 65, lowercase letters start at 97, punctuation starts at 33

Letters from numbers

String.fromCharCode(33)
// -> "!"

String.fromCharCode(65)
// -> "A"

Pick random letter

function randomNumberInRange(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function pickALetterAnyLetter() {
    // interesting characters in the range 33 - 126
    return String.fromCharCode(randomNumberInRange(33, 126));
}

function Particle() {
    ...
    this.letter = pickALetterAnyLetter();
}

Drawing text

function drawParticle(context, particle) {
    context.fillStyle = particle.colour;
    context.font = 'bold 14px arial';
    context.fillText(particle.letter, particle.x, particle.y);
}
Play

Change the letter

function changeParticleLetter(particle) {
    particle.letter = pickALetterAnyLetter();
}

(function animloop(){
    requestAnimFrame(animloop);
    context.clearRect(0, 0, context.canvas.width, context.canvas.height);


    for(var i = 0; i < particles.length; i++) {
        // change the letter
        changeParticleLeter(particles[i]);

        updateParticlePosition(particles[i]);
        drawParticle(context, particles[i]);
    }
})();
Play

Frame-rate dependent

Letters change every frame - not what we want

Fixed vs Variable timestep

Animation tied to framerate can lead to unexpected results

eg move character 600px per second. At 60fps, need to move 10px per frame.

On slower machine, running at 30fps - now character only moves 300px per second

Need for Speed: Rivals

FPS locked at 30fps

Modders changed to 60fps

Cars moved twice as fast as the player

Space Invaders

As enemies killed, fewer entities to draw = frames rendered faster = enemies faster

Liked the effect so kept it (but unplayable on modern hardware!)

Animation independent from framerate

Check how much time has elapsed since the last frame

Use the difference (delta) between last frame and current time as basis for movement

Check the delta

// store the current time
var time;

function Particle() {
    ...
    // last time particle changed letter
    var changeLetterDelta = 0;

    // how long should we wait for the letter to change?
    var changeLetterThreshold = 250; // 250ms
}

(function animloop() {
    requestAnimFrame(animloop);
    
    // get current time
    var now = new Date().getTime();

    // difference between last frame (time) and current time (now)
    var delta = now - (time || now);

    // since we're now rendering a frame, save the current time as the time of the last frame
    time = now;

    context.clearRect(0, 0, context.canvas.width, context.canvas.height);
    
    for(var i = 0; i < particles.length; i++) {
        var particle = particles[i];

        // particles keep track of the last time they changed letter
        particle.changeLetterDelta += delta;
    
        // add the current time to the last time particle changed letter
        // if it's past a certain point (changeLetterThreshold) then change
        if(particle.changeLetterDelta >= particle.changeLetterThreshold) {
            changeParticleLeter(particle);
            particle.changeLetterDelta = 0;
        }

        updateParticlePosition(particle);
        drawParticle(context, particle);
    }
})();

Vertical Slides

Slides can be nested inside of other slides, try pressing down.

Basement Level 1

Press down or up to navigate.

Basement Level 2

Cornify

Basement Level 3

That's it, time to go back up.

Slides

Not a coder? No problem. There's a fully-featured visual editor for authoring these, try it out at http://slid.es.

Point of View

Press ESC to enter the slide overview.

Hold down alt and click on any element to zoom in on it using zoom.js. Alt + click anywhere to zoom back out.

Works in Mobile Safari

Try it out! You can swipe through the slides and pinch your way to the overview.

Marvelous Unordered List

  • No order here
  • Or here
  • Or here
  • Or here

Fantastic Ordered List

One is smaller than... Two is smaller than... Three!

Markdown support

For those of you who like that sort of thing. Instructions and a bit more info available here.

<section data-markdown>
  ## Markdown support

  For those of you who like that sort of thing.
  Instructions and a bit more info available [here](https://github.com/hakimel/reveal.js#markdown).
</section>

Transition Styles

You can select from different transitions, like: Cube - Page - Concave - Zoom - Linear - Fade - None - Default

Themes

Reveal.js comes with a few themes built in: Default - Sky - Beige - Simple - Serif - Night Moon - Solarized

* Theme demos are loaded after the presentation which leads to flicker. In production you should load your theme in the <head> using a <link>.

Global State

Set data-state="something" on a slide and "something" will be added as a class to the document element when the slide is open. This lets you apply broader style changes, like switching the background.

Custom Events

Additionally custom events can be triggered on a per slide basis by binding to the data-state name.

Reveal.addEventListener( 'customevent', function() {
    console.log( '"customevent" has fired' );
} );

Slide Backgrounds

Set data-background="#007777" on a slide to change the full page background to the given color. All CSS color formats are supported.

Image Backgrounds

<section data-background="image.png">

Repeated Image Backgrounds

<section data-background="image.png" data-background-repeat="repeat" data-background-size="100px">

Background Transitions

Pass reveal.js the backgroundTransition: 'slide' config argument to make backgrounds slide rather than fade.

Background Transition Override

You can override background transitions per slide by using data-background-transition="slide".

Clever Quotes

These guys come in two forms, inline: “The nice thing about standards is that there are so many to choose from” and block:

“For years there has been a theory that millions of monkeys typing at random on millions of typewriters would reproduce the entire works of Shakespeare. The Internet has proven this theory to be untrue.”

Pretty Code

function linkify( selector ) {
  if( supports3DTransforms ) {

    var nodes = document.querySelectorAll( selector );

    for( var i = 0, len = nodes.length; i < len; i++ ) {
      var node = nodes[i];

      if( !node.className ) {
        node.className += ' roll';
      }
    }
  }
}

Courtesy of highlight.js.

Intergalactic Interconnections

You can link between slides internally, like this.

Fragmented Views

Hit the next arrow...

... to step through ...

any type of view fragments This slide has fragments which are also stepped through in the notes window.

Fragment Styles

There's a few styles of fragments, like:

grow

shrink

roll-in

fade-out

highlight-red

highlight-green

highlight-blue

current-visible

highlight-current-blue

Spectacular image!

Export to PDF

Presentations can be exported to PDF, below is an example that's been uploaded to SlideShare.

Take a Moment

Press b or period on your keyboard to enter the 'paused' mode. This mode is helpful when you want to take distracting slides off the screen during a presentation.

Stellar Links

THE END

BY Hakim El Hattab / hakim.se