NewFiveFour | Blog | Portfolio


Javascript: Smoothly move a player in canvas

Previously we learnt how to move a player around a canvas: https://newfivefour.com/javascript-canvas-move-a-player.html

var canvas = document.querySelector("canvas")
var context = canvas.getContext("2d");
var player = {width: 30, height: 30, x: 0, y:110, speedX: 0.0, speedY: 0.0};

function updateGameArea() {
    context.clearRect(0, 0, canvas.width, canvas.height)  
    context.fillRect(player.x, player.y, player.width, player.height);

    requestAnimationFrame(updateGameArea);  
}

window.onkeydown = function(event) {
  event.preventDefault() // stops the button scrolling the page
  if(event.keyCode == 40) { // down
    player.y += 10
  } else if(event.keyCode == 38) { // up
    player.y -= 10    
  } else if(event.keyCode == 39) { // right 
    player.x += 10    
  } else if(event.keyCode == 37) { // left
    player.x -= 10        
  } 
}

requestAnimationFrame(updateGameArea);

But the movement is jerky. We can fix that.
 
We will make our player object take a speedX and speedY property firstly: player = {width: 30, height: 30, x: 0, y:110, speedX: 0.0, speedY: 0.0}; .
 
And in the update function we will change the player x and y by this variable:

function updateGameArea() {
    context.clearRect(0, 0, canvas.width, canvas.height)  
    player.x += player.speedX;
    player.y += player.speedY;
    context.fillRect(player.x, player.y, player.width, player.height);

    requestAnimationFrame(updateGameArea);  
}

All that's left is the onkeyup and down functions that change the speedX and speedY.
 
When the button is pressed down we'll increase the speed. And when it's released we'll completely stop the movement:
 
Here's all the code:

var canvas = document.querySelector("canvas")
var context = canvas.getContext("2d");
player = {width: 30, height: 30, x: 0, y:110, speedX: 0.0, speedY: 0.0};

function updateGameArea() {
    context.clearRect(0, 0, canvas.width, canvas.height)  
    player.x += player.speedX;
    player.y += player.speedY;
    context.fillRect(player.x, player.y, player.width, player.height);

    requestAnimationFrame(updateGameArea);  
}

window.onkeydown = function(event) {
  event.preventDefault() // stop the arrow keys scrolling the page
  if(event.keyCode == 40) { // down
    player.speedY += 1
  } else if(event.keyCode == 38) { // up
    player.speedY -= 1
  } else if(event.keyCode == 39) { // right 
    player.speedX += 1
  } else if(event.keyCode == 37) { // left
    player.speedX -= 1        
  } 
}

window.onkeyup = function(event) {
  event.preventDefault() // stop the arrow keys scrolling the page
  player.speedX = 0
  player.speedY = 0
}

requestAnimationFrame(updateGameArea);


javascript canvas


Javascript: Move a player on the canvas

We're going to create a player. This is a rectangle. We're going to move it around our canvas.
 
First create a HTML file a canvas tag with width and height attributes.
 
Let's start the javascript. Call requestAnimationFrame with a function that loops by calling requestAnimationFrame inside that function.
 
In the function clear the screen each time. Obviously nothing will be printed on the screen at this point.

var canvas = document.querySelector("canvas")
var context = canvas.getContext("2d");

function updateGameArea() {
    context.clearRect(0, 0, canvas.width, canvas.height)  
    requestAnimationFrame(updateGameArea);  
}

requestAnimationFrame(updateGameArea);

For the next iteration we'll create a player object. It will have height and width and an x and a y.
 
In the updateGameArea function we'll use these properties to draw a rectangle to the screen.

var canvas = document.querySelector("canvas")
var context = canvas.getContext("2d");
var player = {width: 30, height: 30, x: 0, y:110};

function updateGameArea() {
    context.clearRect(0, 0, canvas.width, canvas.height)  
    context.fillRect(player.x, player.y, player.width, player.height);

    requestAnimationFrame(updateGameArea);  
}

requestAnimationFrame(updateGameArea);

This now constantly prints a rectangle to the screen.
 
In the next iteration we will use a onkeydown listener to check for the left, right and up and down buttons.
 
When we find those, we will update the player x and y positions and thus move our player.

var canvas = document.querySelector("canvas")
var context = canvas.getContext("2d");
var player = {width: 30, height: 30, x: 0, y:110, speedX: 0.0, speedY: 0.0};

function updateGameArea() {
    context.clearRect(0, 0, canvas.width, canvas.height)  
    context.fillRect(player.x, player.y, player.width, player.height);

    requestAnimationFrame(updateGameArea);  
}

window.onkeydown = function(event) {
  event.preventDefault() // stops the button scrolling the page
  if(event.keyCode == 40) { // down
    player.y += 10
  } else if(event.keyCode == 38) { // up
    player.y -= 10    
  } else if(event.keyCode == 39) { // right 
    player.x += 10    
  } else if(event.keyCode == 37) { // left
    player.x -= 10        
  } 
}

requestAnimationFrame(updateGameArea);

And voila.

javascript canvas


Javascript: A scrolling background in canvas

If you want a scrolling background in Canvas let's first do the initial canvas stuff, including specifying the canvas width and height, and setting a new image and loading a local png file in it.

var canvas = document.querySelector("canvas")
var ctx = canvas.getContext("2d")
var canvasWidth = 1000 // for example
var canvasHeight = 400 // for example
var image = new Image()
image.src = "somefile.png" // for example

Next let's specify the scrolling speed in pixels and initial x position:

var speed = -0.2
var x = 0;

Let's create a update function. It will move the x position depending on the pixel speed.
 
Then it will draw two images, one that will be scrolling off the screen, another that will be to the right of it.

function update() {
  x += speed
  x %= canvasWidth
  ctx.drawImage(image, x, 0, 
    canvasWidth, canvasHeight)
  ctx.drawImage(image, x + canvasWidth, 0, 
    canvasWidth, canvasHeight)

  requestAnimationFrame(update)                      
} 
requestAnimationFrame(update)                      

It's doing two other things.
  1. The whole thing is started with requestAnimationFrame(update). It will only call update once though. So in update we must call it again.
  2. Say the canvas width is 500. Once x is 501 the image will be off the canvas. To make it back we can do 501 % 500 to get the position 1. (And when it's 499 that will produce 499 anyway). So that what the x %=500 lines does.

javascript canvas


Javascript: Draw rounded rectangle in canvas

Canvas doesn't provide a method to do rounded rectangles. But we can make one with arcs and lineTos.
 
We can also add it to the CanvasRenderingContext2D prototype. This means we can use it like the below. And set your own stroke and fill styles:

  let canvas = document.getElementById('example');
  let ctx = canvas.getContext('2d');  
  ctx.beginPath();
  ctx.roundedRectangle(0, 0, 100, 100, 20);
  ctx.stroke();
  
  ctx.beginPath();  
  ctx.roundedRectangle(5, 5, 90, 90, 15);
  ctx.stroke();     

Here's the function to draw a rounded rectangle.

CanvasRenderingContext2D.prototype.roundedRectangle = function(x, y, width, height, rounded) {
  const radiansInCircle = 2 * Math.PI
  const halfRadians = (2 * Math.PI)/2
  const quarterRadians = (2 * Math.PI)/4  
  
  // top left arc
  this.arc(rounded + x, rounded + y, rounded, -quarterRadians, halfRadians, true)
  
  // line from top left to bottom left
  this.lineTo(x, y + height - rounded)

  // bottom left arc  
  this.arc(rounded + x, height - rounded + y, rounded, halfRadians, quarterRadians, true)  
  
  // line from bottom left to bottom right
  this.lineTo(x + width - rounded, y + height)

  // bottom right arc
  this.arc(x + width - rounded, y + height - rounded, rounded, quarterRadians, 0, true)  
  
  // line from bottom right to top right
  this.lineTo(x + width, y + rounded)  

  // top right arc
  this.arc(x + width - rounded, y + rounded, rounded, 0, -quarterRadians, true)  
  
  // line from top right to top left
  this.lineTo(x + rounded, y)  
}

javascript canvas


ReactJS: Updating state

We have state in our component. And we can call this.setState from a click listener to update that state. When we update the state the component with effecticently (using virutaldom) redraw itself and any sub components.
 
this.setState takes a object as argument and its values relate to the property names in your state. It updates them.
 
We can call this from a onClick attribute on a HTML tag. The onClick's value is within curly bracked and the javascript is within: onclick={() => console.log("i am some javascript")}
 
We will change our style in our div object so it changes based on a clicked variable in our state.

<html>
  <head>
    <script src="https://unpkg.com/react@16.3.1/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16.3.1/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
    <script src="https://unpkg.com/prop-types@15.6.1/prop-types.js"></script>
  </head>
  <body>
    <div id="root"></div>
  </body>
  <script type="text/babel">

    class Hello extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          name: props.name,
          clicked: false,
        };
      }
      render() {
        return (
          <div style={{display: "flex", flexDirection: "row"}}>
            <div style={{color: (this.state.clicked) ? "lightgreen" : "blue" }}>Hello {this.state.name}!</div>
            <button onClick={() => this.setState({clicked: true})}>on acid</button>
          </div>
        );
      }
    }

    ReactDOM.render(
      <div>
        <Hello name="Davey dave dave" />
        <Hello name="Chris" />
        <Hello name="Ahmed" />
        <Hello name="Peter" />
      </div>,
      document.getElementById('root')
    );
  </script>
</html>

javascript reactjs


Page 2 of 92
prev next

Portfolio