Learn HTML5 Canvas Drawing with JavaScript

Let’s explore what the canvas is and draw some shapes.

Prerequisites / Info

  • This is part of the JS Game Dev Series
  • You should have some knowledge of JavaScript — I will not explain irrelevant syntax such as for-loops
  • Knowledge of ES6 Classes is helpful but not required
  • Basic math/geometry knowledge
  • Basic artistic skills

Starter Code

I moved this to a separate page to keep this article short and so I only have to update it in one place.

Final Code for this Tutorial

You can get all the code from this tutorial on the repository below. Keep in mind there’s also a lot of code included that’s not written here. This is because I added more code to create screenshots/diagrams for this tutorial.

Note: As the focus of this tutorial is not building a project, you don’t need to copy every line exactly. In fact, since we’ll be covering many examples, I encourage you to play with it and make a mess.

What is the Canvas Element?

Some quick bullet points to introduce you to the canvas.

  • Introduced with HTML version 5 to draw graphics using JavaScript
  • Graphics can be 2D or 3D and it’s able to use hardware acceleration
  • Used often today for creating games and visualizations (data or artistic)

Steps to Getting Started with The Canvas

When working with a canvas there are five steps to get started.

  1. Create the canvas element —give it an id, and a width/height (HTML)
  2. Add base styles — center the canvas, add a background color, etc (CSS)
  3. In JavaScript, get your canvas element by using the id
  4. Use the canvas element to get the context (your toolbox; more on it later)
  5. Use the context to draw

We’ll do steps one and two in HTML/CSS, but you could do it in JavaScript if you prefer.

Steps 1 and 2 for this project Our boilerplate / CodePen template already covered setting up the basic styles and adding a canvas element. For this project, I will change the canvas width/height to be 800x1200 to give us plenty of space.

// index.html
<canvas id="gameCanvas" width="800" height="1200"></canvas>

I also changed the canvas background to be white and added some margin to the bottom.

// styles.css
body {
  background: #111;
  color: #f8f8f8;
}
canvas {
  background: #f8f8f8;
  padding: 0;
  margin: 0 auto;
  margin-bottom: 1rem;
  display: block;
}

Steps 3 and 4 Get the canvas element by id, then use it to get the “2d” context.

// index.js
;(function () {
  const canvas = document.getElementById('gameCanvas')
  const ctx = canvas.getContext('2d')

})()

canvas-starter.js

grab the canvas element and create a 2D context

document.getElementById(‘gameCanvas’) — searches for an HTML element that has the id of gameCanvas. Once it finds the element, we can then manipulate it with JavaScript.

canvas.getContext() — context is our toolbox of paintbrushes and shapes. The 2D context contains the set of tools we want. If you were working with 3D, you would use WebGL instead.

But wait what’s with the function thingy wrapping all of this?

This is an immediately invoked function expression (IIFE). We use it to prevent our code from leaking out in the global scope. This has several benefits such as preventing players (if this were a game) from accessing your variables directly and prevents your code from colliding with someone else’s code (such as a library or another script on the website). The semicolon is there in case some other code is loaded before ours and it doesn’t have a semicolon at the end.

We’ll talk more about security in a future article, for now, let’s get to drawing stuff.

The Canvas Coordinate System

By default, the coordinate system starts at the top left. (X: 0, Y: 0) Moving down or to the right increases X and Y positions. You can play with the example below on this page.

This is image title

a grid/coordinate project we’ll be creating

Quiz: The Canvas Element

  1. How do you select the canvas element in JavaScript?
  2. How do you get the context?
  3. Where is X: 0, Y: 0 on the canvas by default?

Simple Shapes

Let’s make use of the 2d context object to draw shapes. Feel free to reference the documentation page at any time.

There will also be a link to each method we use.

But wait for the DOM…

Before we draw anything, we want to make sure the DOM (HTML) finished loading to avoid any related errors. To do that, we will make a function to handle the setup process we did above and listen for the DOMContentLoaded event. We will call this function init (for initialize).

Remember: everything stays inside the IIFE wrapper. I won’t be showing it in the example code from now on. If you ever get lost refer to the completed project here.

// initialize config variables here
let canvas, ctx

// setup config variables and start the program
function init () {
  canvas = document.getElementById('gameCanvas')
  ctx = canvas.getContext('2d')
}

// wait for the HTML to load
document.addEventListener('DOMContentLoaded', init)

canvas-wait-for-dom.js

wait for DOM to load then run init function

We want our canvas and context variables to be available to all of our functions. This requires defining them up top and then giving them a value in the init function once the DOM loads. This completes our setup.

Note: A more scalable option is to accept the context variable as an argument to our drawing functions.

Rectangles / Squares

Let’s start by creating a square:

function init () {
  // set our config variables
  canvas = document.getElementById('gameCanvas')
  ctx = canvas.getContext('2d')

  // outlined square X: 50, Y: 35, width/height 50
  ctx.beginPath()
  ctx.strokeRect(50, 35, 50, 50)

  // filled square X: 125, Y: 35, width/height 50
  ctx.beginPath()
  ctx.fillRect(125, 35, 50, 50)
}

canvas-basic-rectangles.js

basic squares

Inside of our init function, we use context2D.beginPath to tell the canvas we want to start a new path/shape. On the next line, we create and draw a rectangle (a square in this case).

There are two different methods we use to draw the path to the screen:

ctx.strokeRect(x, y, width, height) — this creates a “stroked” rectangle. Stroke is the same thing as an outline or border

ctx.fillRect(x, y, width, height) — similar to strokeRect but this fills in the rectangle with a color

The Result:

This is image title

stroked square and filled square

There are a few things to note here:

  1. The colors default to black stroke and black fill.
  2. The origin point or X: 0, Y: 0 for these shapes are at their top left, similar to the canvas.
  3. I just picked a random x, y for the first square and then added 50 + 50+ 25 (previous square X + previous square width + 25px margin) for the x position.

This is image title
positioning the squares

What if we want to change the color/style? Let’s add a red outlined square that’s also filled with blue.

Position first:

  • X = 200 previous square width + previous position + 25px margin = 50 + 125 + 25
  • Y = 35 We will keep it in the same row
  • The size will be the same (50 x 50)
ctx.beginPath()
ctx.strokeRect(200, 35, 50, 50) // plugging in our new position

But wait… we want a fill AND a stroke, does this mean we have to draw two squares? You can draw two squares but we will make use of several other methods instead.

// inside the init function

// filled, outlined square X: 200, Y: 35, width/height 50
ctx.beginPath()
ctx.strokeStyle = 'red'
ctx.fillStyle = 'blue'
ctx.lineWidth = 5
ctx.rect(200, 35, 50, 50)
ctx.fill()
ctx.stroke()

stroke-filled-square.js

create an outline and filled in square

The Result:

This is image title

a third colorful square

ctx.rect(x, y, width, height) — this is like the other two rectangle methods, but it does not immediately draw it. It creates a path for the square in memory, we then configure the stroke, fill, and stroke width before calling ctx.fill and/or ctx.stroke to draw it on screen

ctx.strokeStyle = ‘any valid css color’ — sets the outline/stroke color to any string that works in CSS. i.e. ‘blue’, ‘rgba(200, 200, 150, 0.5)’, etc

ctx.fillStyle = ‘any valid css color’ — same as above but for the fill

ctx.lineWidth = number — sets the stroke width

ctx.fill() — fills the current path

ctx.stroke() — strokes the current path

Drawing any shape always follows these steps:

  1. Set the styles — optional and can be set any time before rendering
  2. Begin the path — start creating the virtual path (not drawn to screen yet)
  3. Use the path functions to create a shape — i.e. the rect method
  4. Draw the path to the screen — using fill or stroke

Note: We did not need to use the _ctx.rect()_ function just to change the colors, we used it because we wanted both a stroke and a fill. You can just as easily set _ctx.fillStyle_ and use _ctx.fillRect()_

Setting the fill or stroke style will cause any shapes created after, to have the same style. For example, if we add a fourth square using the code below it would have the same style as the third square.

// 4th square, uses the same style defined previously
ctx.beginPath()
ctx.rect(275, 35, 50, 50)
ctx.fill()
ctx.stroke()

Result:

This is image title

4th square, oops same style

Anytime you want to add a fill/stroke to your shapes, explicitly define the styles.

Optimizing our Code with Classes

Making use of classes we can create a robust Rectangle object and clean up our code.

Classes are functions that create Objects. We want to create Rectangle objects that contain information about themselves, such as their position, styles, area, and dimensions.

I won’t go into much detail on classes as it’s not required and you can get by with normal functions. Check the MDN documentation page on classes to learn more about them.

// ( still inside the IIFE )

// function to create rectangle objects
class Rectangle {
  // you create new Rectangles by calling this as a function
  // these are the arguments you pass in
  // add default values to avoid errors on empty arguments
  constructor (
    x = 0, y = 0,
    width = 0, height = 0,
    fillColor = '', strokeColor = '', strokeWidth = 2
  ) {
    // ensure the arguments passed in are numbers
    // a bit overkill for this tutorial
    this.x = Number(x)
    this.y = Number(y)
    this.width = Number(width)
    this.height = Number(height)
    this.fillColor = fillColor
    this.strokeColor = strokeColor
    this.strokeWidth = strokeWidth
  }

  // get keyword causes this method to be called
  // when you use myRectangle.area
  get area () {
    return this.width * this.height
  }

  // gets the X position of the left side
  get left () {
    // origin is at top left so just return x
    return this.x
  }

  // get X position of right side
  get right () {
    // x is left position + the width to get end point
    return this.x + this.width
  }

  // get the Y position of top side
  get top () {
    // origin is at top left so just return y
    return this.y
  }

  // get Y position at bottom
  get bottom () {
    return this.y + this.height
  }

  // draw rectangle to screen
  draw () {
    // destructuring
    const {
      x, y, width, height,
      fillColor, strokeColor, strokeWidth
    } = this

    // saves the current styles set elsewhere
    // to avoid overwriting them
    ctx.save()

    // set the styles for this shape
    ctx.fillStyle = fillColor
    ctx.lineWidth = strokeWidth

    // create the *path*
    ctx.beginPath()
    ctx.strokeStyle = strokeColor
    ctx.rect(x, y, width, height)

    // draw the path to screen
    ctx.fill()
    ctx.stroke()

    // restores the styles from earlier
    // preventing the colors used here
    // from polluting other drawings
    ctx.restore()
  }
}

rectangle-class.js

rectangle class

Classes are optional and if the syntax confuses you, then just think of it as an object with methods and properties. Classes aside, two more canvas functions were introduced in the draw method:

ctx.save() — saves the current styles

ctx.restore() — restores the last saved styles

We use these methods to prevent the issue we saw with the fourth square that had unexpected colors.

Canvas stores styles on a stack structure. When we call ctx.save() it pushes the current styles onto the stack and calling ctx.restore() pops it off the stack.

This is image title
style stack animated

I only saved one set of styles in this animation but you can save as many times as you want and restore the most recent styles. Note that saving does not reset the current styles.

Styles include:
strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, lineDashOffset, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation, font, textAlign, textBaseline, direction, imageSmoothingEnabled
— MDN

We can now start putting this Rectangle class to use:

// create a new rectangle object using the Rectangle class
const mySquare = new Rectangle(400, 85, 50, 50, 'gold')

// now we have data and methods to describe our square
console.log(mySquare)
// Object
// fillColor: "gold"
// height: 50
// strokeColor: ""
// strokeWidth: 2
// width: 50
// x: 450
// y: 100
// area: (...)
// bottom: (...)
// left: (...)
// right: (...)
// top: (...)

// draw the square data to screen
mySquare.draw()

using-rectangle-class.js

create a new square using Rectangle class

The Result:

This is image title
square drawing from rectangle class

Note: I added a grid for the screenshots. We’ll be making a grid at the end of this section.

We can keep reusing the class to make more squares/rectangles:


// mySquare from earlier...
// const mySquare = new Rectangle(400, 85, 50, 50, 'gold')

// lets use the helper methods to
// draw shapes on the sides of mySquare
const childrenSquares = [
  // top side square - align x with mySquare's left side
  // align bottom with top of mySquare
  new Rectangle(mySquare.left, mySquare.top - 50, 50, 50, 'red'),

  // right side square - align x with right side of mySquare
  // align top with mySquare top
  new Rectangle(mySquare.right, mySquare.top, 50, 50, 'green'),

  // bottom square
  new Rectangle(mySquare.left, mySquare.bottom, 50, 50, 'blue'),

  // left square
  new Rectangle(mySquare.left - 50, mySquare.top, 50, 50, 'magenta')
]

// draw all of the child squares by looping over them
childrenSquares.forEach(square => square.draw())

children-squares.js

child squares nonsense

We create an array and populate it with new Rectangles positioned based on the mySquare object created earlier. Then we loop over the array and call the draw method on every square.

What do we get from all that code?

This is image title

child squares?

Well… it’s something.

I know this is all boring and tedious but we’ve covered the basics of canvas and you’ve at least seen what a class looks like now. Let’s finish creating more shapes. (it’ll go quicker from now on I promise)

Lines 🔗

Rectangles are the only pre-defined shape with canvas, we create other shapes on our own. We can use lines to build the foundation of these shapes.

// LINES

// save previous styles & set our current styles
ctx.save()
ctx.strokeStyle = 'blue'
ctx.fillStyle = 'blue'
ctx.lineWidth = 4

// stroked trapezoid
ctx.beginPath()
ctx.moveTo(50, 200) // sets our starting point
ctx.lineTo(100, 200) // create a line from start point to X: 100, Y: 200
ctx.lineTo(90, 180) // create the right side
ctx.lineTo(60, 180) // top side
ctx.closePath() // left side and closes the path
ctx.stroke() // draws it to screen via a stroke

// filled trapezoid
ctx.beginPath()
ctx.moveTo(150, 200) // starting point
ctx.lineTo(200, 200) // bottom side
ctx.lineTo(190, 180) // right side
ctx.lineTo(160, 180) // top side
// no need to closePath, fill automatically closes the path
ctx.fill()

// restore saved styles (for other examples)
ctx.restore()

lines-trapezoids.js

using lines to make trapezoid-like shapes

The Result:

This is image title

trapezoid things

New Methods:

ctx.moveTo(x, y) — you can think of this as moving our virtual “pen”, we use it to set the starting point for the first line

ctx.lineTo(x, y) — creates a line to X, Y; the starting point is the last position of our “pen”. This allows us to start new lines at the endpoint of previous lines.

ctx.closePath() — when using a stroke we need to call this to draw the final line and close the path. Fill will automatically close the path

Note: If you need curved lines then you can use Bézier curves with the quadratic or cubic bézier curve functions. I’ll cover them in another tutorial to keep this one from becoming too long.

Text 🔤

If you ever worked with any kind of text editor similar to Microsoft Word or any of Adobe’s tools, then these options will be familiar to you.

// TEXT

// usual setup
ctx.save()
ctx.strokeStyle = 'red'
ctx.fillStyle = 'black'

// text specific styles
ctx.font = 'bold 16px Monospace'
ctx.textAlign = 'left'
ctx.textBaseline = 'alphabetic'

// draw stroked text to screen
ctx.strokeText('Stroked Text', 50, 250)

// calculate the width of this text using current font/styles
const textWidth = ctx.measureText('Stroked Text').width

// X = previous X position + width + 25px margin
ctx.fillText('Filled Text', 50 + textWidth + 25, 250)

ctx.restore()

canvas-text.js

This is image title

ctx.strokeText(text, x, y) — creates the text path and strokes it

ctx.fillText(text, x, y) — same as above but fills the text

ctx.font(CSSFontString) — set the font using the CSS font format

ctx.measureText(text) — performs some calculations using the current styles and returns an object with the results, including the calculated width

The rest of the options are self-explanatory or require knowledge of font design, which is outside the scope of this tutorial.

Circles & Partial Circles (arcs) 🔴

// ARCS / Circles
// usual setup
ctx.save()
ctx.strokeStyle = 'black'
ctx.fillStyle = 'red'

// x, y, radius, startAngle, endAngle, antiClockwise = false by default
ctx.beginPath()
ctx.arc(50, 300, 15, 0, 2 * Math.PI, false) // full circle
ctx.fill()
ctx.stroke()

// half circle counter clockwise
ctx.beginPath()
ctx.arc(100, 300, 15, 0, Math.PI, true)
ctx.fill()
ctx.stroke()

// half circle clockwise
ctx.beginPath()
ctx.arc(150, 300, 15, 0, Math.PI)
ctx.fill()
ctx.stroke()

// pacman like
ctx.beginPath()
ctx.fillStyle = 'gold'
ctx.arc(200, 300, 15, 0.1 * Math.PI, 1.85 * Math.PI)
ctx.lineTo(200, 300)
ctx.fill()

ctx.restore()

canvas-arcs.js

circles / arcs code

This is image title

resulting circles/arcs

The only new function here is the arc method.

arc(x, y, radius, startAngle, endAngle, antiClockwise)

X, Y — defines the position of the center point, not the top left

radius — the size of the circle/arc

startAngle, endAngle — I think these are self-explanatory but it’s important to note that these angles are in Radians not degrees.

Math Aside: 1π (Pi) radians is equal to half a circle, 2π gives you a full circle.
Watch this video for more on the math of a circle

Triangles 🔺

As there are no triangle functions, we have to make them ourselves using lines.

// TRIANGLES
// usual setup
ctx.save()
ctx.strokeStyle = 'black'
ctx.fillStyle = 'orangered'

// Filled Triangle
ctx.beginPath()
ctx.moveTo(50, 400) // starting point
ctx.lineTo(50, 350) // left side
ctx.lineTo(100, 400) // hypotenuse / long side
ctx.fill() // closes the bottom side & fills

// stroked triangle
ctx.beginPath()
ctx.moveTo(150, 400) // starting point
ctx.lineTo(200, 400) // bottom side
ctx.lineTo(200, 350) // right side
ctx.closePath() // hypotenuse/long side (remember to close path for strokes!)
ctx.stroke()

ctx.restore()

canvas-triangle.js

This is image title

Nothing new here. Refer to the sections above if you’re lost. (or ask in the comments)

Quiz: Basic Shapes

  1. What arguments does the rect(_, _, _, _) function take?
  2. After you’ve used the rect function, what two methods can draw the rectangle to the screen? (the same functions for any path)
  3. What function can create circles?
  4. What two properties can we set to change the fill and outline styles?
  5. How do you set the starting position when using lineTo(x,y)

Answers: (links to related MDN pages)

  1. Rect function docs
  2. Drawing method 1, drawing method 2
  3. Function to draw circles
  4. strokeStyle, fillStyle
  5. ctx.moveTo(x,y)

Challenge: Visualize the Canvas Coordinate System

Use what you learned to draw a coordinate plane or grid with X and Y starting at the top left and end where the canvas ends.

Examples

This is image title

This is image title

Tips

  • Use for loops to create multiple lines
  • It can be a full grid, just text, or lines with tick marks… Make the grid you will want to use
  • As we haven’t covered animation yet, don’t worry about animating it. The example above was animated only for demonstration purposes.

Solution Don’t worry if you didn’t solve it, this one is challenging.

I started by making a new JS file and loading it instead of the example shapes from earlier.

<!-- index.html -->
<!-- <script src="js/index.js"></script> -->
<script src="js/gridSolution.js"></script>

Add the initial setup to your new JS file.

// gridSolution.js

;(function () {
  let canvas, ctx
  
  function init () {
    // set our config variables
    canvas = document.getElementById('gameCanvas')
    ctx = canvas.getContext('2d')
  }
  
  document.addEventListener('DOMContentLoaded', init)
})()

gridSolution-initial.js

initial setup for the grid solution

Now, decide if you want to make a reusable Grid class or create something simpler. I will keep it simple for this example solution by using only one function.

// draws a grid
function createGrid () {
  // draw a line every *step* pixels
  const step = 25

  // our end points
  const width = canvas.width
  const height = canvas.height

  // set our styles
  ctx.save()
  ctx.strokeStyle = 'gray' // line colors
  ctx.fillStyle = 'black' // text color

  // draw vertical from X to Height
  for (let x = 0; x < width; x += step) {

  }

  // draw horizontal from Y to Width
  for (let y = 0; y < height; y += step) {

  }

  // restore the styles from before this function was called
  ctx.restore()
}

function init () {
  // set our config variables
  canvas = document.getElementById('gameCanvas')
  ctx = canvas.getContext('2d')

  createGrid()
}

createGrid-starter.js

partial grid solution

Look at the above code, then try to fill in the blanks yourself if you haven’t already solved it. The next snippet will be the complete code.

This is image title
example solution result

// GRID CHALLENGE SOLUTION

;(function () {
  let canvas, ctx

  // draws a grid
  function createGrid () {
    // draw a line every *step* pixels
    const step = 50

    // our end points
    const width = canvas.width
    const height = canvas.height

    // set our styles
    ctx.save()
    ctx.strokeStyle = 'gray' // line colors
    ctx.fillStyle = 'black' // text color
    ctx.font = '14px Monospace'
    ctx.lineWidth = 0.35

    // draw vertical from X to Height
    for (let x = 0; x < width; x += step) {
      // draw vertical line
      ctx.beginPath()
      ctx.moveTo(x, 0)
      ctx.lineTo(x, height)
      ctx.stroke()

      // draw text
      ctx.fillText(x, x, 12)
    }

    // draw horizontal from Y to Width
    for (let y = 0; y < height; y += step) {
      // draw horizontal line
      ctx.beginPath()
      ctx.moveTo(0, y)
      ctx.lineTo(width, y)
      ctx.stroke()

      // draw text
      ctx.fillText(y, 0, y)
    }

    // restore the styles from before this function was called
    ctx.restore()
  }

  function init () {
    // set our config variables
    canvas = document.getElementById('gameCanvas')
    ctx = canvas.getContext('2d')

    createGrid()
  }

  document.addEventListener('DOMContentLoaded', init)
})()

grid-example-final-solution.js

final example grid code

Feel free to tweak your grid and save it for future use. I saved the animated one as an NPM package to use with upcoming tutorials.

Final Challenge: Draw Some Art

Now it’s time to put everything you’ve learned to use, here’s your challenge:

Draw a picture using a combination of the shapes we learned. Find some reference images or make something up.

Ideas

  • Emojis / Faces
  • Flags (Japan’s flag? 😂)
  • 2D Game/Cartoon Characters
  • Logos
  • Charts (bar chart, pie chart, etc) — a little more advanced and I’ll be doing another tutorial on charts but if you want to try it on your own go for it.
  • Landscape — draw a house, some grass, a sun or perhaps a starry night sky
  • Search for examples on CodePen to get ideas (prepare to be overwhelmed by the crazy art some people make)

Tips

  • Use canvas.height / 2 and canvas.width / 2 to get the center X, Y of the canvas
  • If you did the grid challenge from earlier, now is a good time to use it
  • If your drawing needs a lot of curves, look into the bezier curve functions: quadraticCurveTo and bezierCurveTo
  • Try finding some examples on CodePen
  • Keep it simple. This challenge is just to practice drawing shapes on the canvas, not to create some complex game character.

When you finish share a link to your CodePen / GitHub repository in the comments.

Reflection

What did you struggle with the most? Or was everything a cakewalk? What could have been different? I would love to hear your feedback in the comments. Otherwise, note what you struggled with and spend more time researching and reviewing that topic.

#html5 #javascript #Canvas

What is GEEK

Buddha Community

Learn HTML5 Canvas Drawing with JavaScript
Sival Alethea

Sival Alethea

1624298400

Learn JavaScript - Full Course for Beginners. DO NOT MISS!!!

This complete 134-part JavaScript tutorial for beginners will teach you everything you need to know to get started with the JavaScript programming language.
⭐️Course Contents⭐️
0:00:00 Introduction
0:01:24 Running JavaScript
0:04:23 Comment Your Code
0:05:56 Declare Variables
0:06:15 Storing Values with the Assignment Operator
0:11:31 Initializing Variables with the Assignment Operator
0:11:58 Uninitialized Variables
0:12:40 Case Sensitivity in Variables
0:14:05 Add Two Numbers
0:14:34 Subtract One Number from Another
0:14:52 Multiply Two Numbers
0:15:12 Dividing Numbers
0:15:30 Increment
0:15:58 Decrement
0:16:22 Decimal Numbers
0:16:48 Multiply Two Decimals
0:17:18 Divide Decimals
0:17:33 Finding a Remainder
0:18:22 Augmented Addition
0:19:22 Augmented Subtraction
0:20:18 Augmented Multiplication
0:20:51 Augmented Division
0:21:19 Declare String Variables
0:22:01 Escaping Literal Quotes
0:23:44 Quoting Strings with Single Quotes
0:25:18 Escape Sequences
0:26:46 Plus Operator
0:27:49 Plus Equals Operator
0:29:01 Constructing Strings with Variables
0:30:14 Appending Variables to Strings
0:31:11 Length of a String
0:32:01 Bracket Notation
0:33:27 Understand String Immutability
0:34:23 Find the Nth Character
0:34:51 Find the Last Character
0:35:48 Find the Nth-to-Last Character
0:36:28 Word Blanks
0:40:44 Arrays
0:41:43 Nest Arrays
0:42:33 Access Array Data
0:43:34 Modify Array Data
0:44:48 Access Multi-Dimensional Arrays
0:46:30 push()
0:47:29 pop()
0:48:33 shift()
0:49:23 unshift()
0:50:36 Shopping List
0:51:41 Write Reusable with Functions
0:53:41 Arguments
0:55:43 Global Scope
0:59:31 Local Scope
1:00:46 Global vs Local Scope in Functions
1:02:40 Return a Value from a Function
1:03:55 Undefined Value returned
1:04:52 Assignment with a Returned Value
1:05:52 Stand in Line
1:08:41 Boolean Values
1:09:24 If Statements
1:11:51 Equality Operator
1:13:18 Strict Equality Operator
1:14:43 Comparing different values
1:15:38 Inequality Operator
1:16:20 Strict Inequality Operator
1:17:05 Greater Than Operator
1:17:39 Greater Than Or Equal To Operator
1:18:09 Less Than Operator
1:18:44 Less Than Or Equal To Operator
1:19:17 And Operator
1:20:41 Or Operator
1:21:37 Else Statements
1:22:27 Else If Statements
1:23:30 Logical Order in If Else Statements
1:24:45 Chaining If Else Statements
1:27:45 Golf Code
1:32:15 Switch Statements
1:35:46 Default Option in Switch Statements
1:37:23 Identical Options in Switch Statements
1:39:20 Replacing If Else Chains with Switch
1:41:11 Returning Boolean Values from Functions
1:42:20 Return Early Pattern for Functions
1:43:38 Counting Cards
1:49:11 Build Objects
1:50:46 Dot Notation
1:51:33 Bracket Notation
1:52:47 Variables
1:53:34 Updating Object Properties
1:54:30 Add New Properties to Object
1:55:19 Delete Properties from Object
1:55:54 Objects for Lookups
1:57:43 Testing Objects for Properties
1:59:15 Manipulating Complex Objects
2:01:00 Nested Objects
2:01:53 Nested Arrays
2:03:06 Record Collection
2:10:15 While Loops
2:11:35 For Loops
2:13:56 Odd Numbers With a For Loop
2:15:28 Count Backwards With a For Loop
2:17:08 Iterate Through an Array with a For Loop
2:19:43 Nesting For Loops
2:22:45 Do…While Loops
2:24:12 Profile Lookup
2:28:18 Random Fractions
2:28:54 Random Whole Numbers
2:30:21 Random Whole Numbers within a Range
2:31:46 parseInt Function
2:32:36 parseInt Function with a Radix
2:33:29 Ternary Operator
2:34:57 Multiple Ternary Operators
2:36:57 var vs let
2:39:02 var vs let scopes
2:41:32 const Keyword
2:43:40 Mutate an Array Declared with const
2:44:52 Prevent Object Mutation
2:47:17 Arrow Functions
2:28:24 Arrow Functions with Parameters
2:49:27 Higher Order Arrow Functions
2:53:04 Default Parameters
2:54:00 Rest Operator
2:55:31 Spread Operator
2:57:18 Destructuring Assignment: Objects
3:00:18 Destructuring Assignment: Nested Objects
3:01:55 Destructuring Assignment: Arrays
3:03:40 Destructuring Assignment with Rest Operator to Reassign Array
3:05:05 Destructuring Assignment to Pass an Object
3:06:39 Template Literals
3:10:43 Simple Fields
3:12:24 Declarative Functions
3:12:56 class Syntax
3:15:11 getters and setters
3:20:25 import vs require
3:22:33 export
3:23:40 * to Import
3:24:50 export default
3:25:26 Import a Default Export
📺 The video in this post was made by freeCodeCamp.org
The origin of the article: https://www.youtube.com/watch?v=PkZNo7MFNFg&list=PLWKjhJtqVAblfum5WiQblKPwIbqYXkDoC&index=4

🔥 If you’re a beginner. I believe the article below will be useful to you ☞ What You Should Know Before Investing in Cryptocurrency - For Beginner
⭐ ⭐ ⭐The project is of interest to the community. Join to Get free ‘GEEK coin’ (GEEKCASH coin)!
☞ **-----CLICK HERE-----**⭐ ⭐ ⭐
Thanks for visiting and watching! Please don’t forget to leave a like, comment and share!

#javascript #learn javascript #learn javascript for beginners #learn javascript - full course for beginners #javascript programming language

Learn HTML5 Canvas Drawing with JavaScript

Let’s explore what the canvas is and draw some shapes.

Prerequisites / Info

  • This is part of the JS Game Dev Series
  • You should have some knowledge of JavaScript — I will not explain irrelevant syntax such as for-loops
  • Knowledge of ES6 Classes is helpful but not required
  • Basic math/geometry knowledge
  • Basic artistic skills

Starter Code

I moved this to a separate page to keep this article short and so I only have to update it in one place.

Final Code for this Tutorial

You can get all the code from this tutorial on the repository below. Keep in mind there’s also a lot of code included that’s not written here. This is because I added more code to create screenshots/diagrams for this tutorial.

Note: As the focus of this tutorial is not building a project, you don’t need to copy every line exactly. In fact, since we’ll be covering many examples, I encourage you to play with it and make a mess.

What is the Canvas Element?

Some quick bullet points to introduce you to the canvas.

  • Introduced with HTML version 5 to draw graphics using JavaScript
  • Graphics can be 2D or 3D and it’s able to use hardware acceleration
  • Used often today for creating games and visualizations (data or artistic)

Steps to Getting Started with The Canvas

When working with a canvas there are five steps to get started.

  1. Create the canvas element —give it an id, and a width/height (HTML)
  2. Add base styles — center the canvas, add a background color, etc (CSS)
  3. In JavaScript, get your canvas element by using the id
  4. Use the canvas element to get the context (your toolbox; more on it later)
  5. Use the context to draw

We’ll do steps one and two in HTML/CSS, but you could do it in JavaScript if you prefer.

Steps 1 and 2 for this project Our boilerplate / CodePen template already covered setting up the basic styles and adding a canvas element. For this project, I will change the canvas width/height to be 800x1200 to give us plenty of space.

// index.html
<canvas id="gameCanvas" width="800" height="1200"></canvas>

I also changed the canvas background to be white and added some margin to the bottom.

// styles.css
body {
  background: #111;
  color: #f8f8f8;
}
canvas {
  background: #f8f8f8;
  padding: 0;
  margin: 0 auto;
  margin-bottom: 1rem;
  display: block;
}

Steps 3 and 4 Get the canvas element by id, then use it to get the “2d” context.

// index.js
;(function () {
  const canvas = document.getElementById('gameCanvas')
  const ctx = canvas.getContext('2d')

})()

canvas-starter.js

grab the canvas element and create a 2D context

document.getElementById(‘gameCanvas’) — searches for an HTML element that has the id of gameCanvas. Once it finds the element, we can then manipulate it with JavaScript.

canvas.getContext() — context is our toolbox of paintbrushes and shapes. The 2D context contains the set of tools we want. If you were working with 3D, you would use WebGL instead.

But wait what’s with the function thingy wrapping all of this?

This is an immediately invoked function expression (IIFE). We use it to prevent our code from leaking out in the global scope. This has several benefits such as preventing players (if this were a game) from accessing your variables directly and prevents your code from colliding with someone else’s code (such as a library or another script on the website). The semicolon is there in case some other code is loaded before ours and it doesn’t have a semicolon at the end.

We’ll talk more about security in a future article, for now, let’s get to drawing stuff.

The Canvas Coordinate System

By default, the coordinate system starts at the top left. (X: 0, Y: 0) Moving down or to the right increases X and Y positions. You can play with the example below on this page.

This is image title

a grid/coordinate project we’ll be creating

Quiz: The Canvas Element

  1. How do you select the canvas element in JavaScript?
  2. How do you get the context?
  3. Where is X: 0, Y: 0 on the canvas by default?

Simple Shapes

Let’s make use of the 2d context object to draw shapes. Feel free to reference the documentation page at any time.

There will also be a link to each method we use.

But wait for the DOM…

Before we draw anything, we want to make sure the DOM (HTML) finished loading to avoid any related errors. To do that, we will make a function to handle the setup process we did above and listen for the DOMContentLoaded event. We will call this function init (for initialize).

Remember: everything stays inside the IIFE wrapper. I won’t be showing it in the example code from now on. If you ever get lost refer to the completed project here.

// initialize config variables here
let canvas, ctx

// setup config variables and start the program
function init () {
  canvas = document.getElementById('gameCanvas')
  ctx = canvas.getContext('2d')
}

// wait for the HTML to load
document.addEventListener('DOMContentLoaded', init)

canvas-wait-for-dom.js

wait for DOM to load then run init function

We want our canvas and context variables to be available to all of our functions. This requires defining them up top and then giving them a value in the init function once the DOM loads. This completes our setup.

Note: A more scalable option is to accept the context variable as an argument to our drawing functions.

Rectangles / Squares

Let’s start by creating a square:

function init () {
  // set our config variables
  canvas = document.getElementById('gameCanvas')
  ctx = canvas.getContext('2d')

  // outlined square X: 50, Y: 35, width/height 50
  ctx.beginPath()
  ctx.strokeRect(50, 35, 50, 50)

  // filled square X: 125, Y: 35, width/height 50
  ctx.beginPath()
  ctx.fillRect(125, 35, 50, 50)
}

canvas-basic-rectangles.js

basic squares

Inside of our init function, we use context2D.beginPath to tell the canvas we want to start a new path/shape. On the next line, we create and draw a rectangle (a square in this case).

There are two different methods we use to draw the path to the screen:

ctx.strokeRect(x, y, width, height) — this creates a “stroked” rectangle. Stroke is the same thing as an outline or border

ctx.fillRect(x, y, width, height) — similar to strokeRect but this fills in the rectangle with a color

The Result:

This is image title

stroked square and filled square

There are a few things to note here:

  1. The colors default to black stroke and black fill.
  2. The origin point or X: 0, Y: 0 for these shapes are at their top left, similar to the canvas.
  3. I just picked a random x, y for the first square and then added 50 + 50+ 25 (previous square X + previous square width + 25px margin) for the x position.

This is image title
positioning the squares

What if we want to change the color/style? Let’s add a red outlined square that’s also filled with blue.

Position first:

  • X = 200 previous square width + previous position + 25px margin = 50 + 125 + 25
  • Y = 35 We will keep it in the same row
  • The size will be the same (50 x 50)
ctx.beginPath()
ctx.strokeRect(200, 35, 50, 50) // plugging in our new position

But wait… we want a fill AND a stroke, does this mean we have to draw two squares? You can draw two squares but we will make use of several other methods instead.

// inside the init function

// filled, outlined square X: 200, Y: 35, width/height 50
ctx.beginPath()
ctx.strokeStyle = 'red'
ctx.fillStyle = 'blue'
ctx.lineWidth = 5
ctx.rect(200, 35, 50, 50)
ctx.fill()
ctx.stroke()

stroke-filled-square.js

create an outline and filled in square

The Result:

This is image title

a third colorful square

ctx.rect(x, y, width, height) — this is like the other two rectangle methods, but it does not immediately draw it. It creates a path for the square in memory, we then configure the stroke, fill, and stroke width before calling ctx.fill and/or ctx.stroke to draw it on screen

ctx.strokeStyle = ‘any valid css color’ — sets the outline/stroke color to any string that works in CSS. i.e. ‘blue’, ‘rgba(200, 200, 150, 0.5)’, etc

ctx.fillStyle = ‘any valid css color’ — same as above but for the fill

ctx.lineWidth = number — sets the stroke width

ctx.fill() — fills the current path

ctx.stroke() — strokes the current path

Drawing any shape always follows these steps:

  1. Set the styles — optional and can be set any time before rendering
  2. Begin the path — start creating the virtual path (not drawn to screen yet)
  3. Use the path functions to create a shape — i.e. the rect method
  4. Draw the path to the screen — using fill or stroke

Note: We did not need to use the _ctx.rect()_ function just to change the colors, we used it because we wanted both a stroke and a fill. You can just as easily set _ctx.fillStyle_ and use _ctx.fillRect()_

Setting the fill or stroke style will cause any shapes created after, to have the same style. For example, if we add a fourth square using the code below it would have the same style as the third square.

// 4th square, uses the same style defined previously
ctx.beginPath()
ctx.rect(275, 35, 50, 50)
ctx.fill()
ctx.stroke()

Result:

This is image title

4th square, oops same style

Anytime you want to add a fill/stroke to your shapes, explicitly define the styles.

Optimizing our Code with Classes

Making use of classes we can create a robust Rectangle object and clean up our code.

Classes are functions that create Objects. We want to create Rectangle objects that contain information about themselves, such as their position, styles, area, and dimensions.

I won’t go into much detail on classes as it’s not required and you can get by with normal functions. Check the MDN documentation page on classes to learn more about them.

// ( still inside the IIFE )

// function to create rectangle objects
class Rectangle {
  // you create new Rectangles by calling this as a function
  // these are the arguments you pass in
  // add default values to avoid errors on empty arguments
  constructor (
    x = 0, y = 0,
    width = 0, height = 0,
    fillColor = '', strokeColor = '', strokeWidth = 2
  ) {
    // ensure the arguments passed in are numbers
    // a bit overkill for this tutorial
    this.x = Number(x)
    this.y = Number(y)
    this.width = Number(width)
    this.height = Number(height)
    this.fillColor = fillColor
    this.strokeColor = strokeColor
    this.strokeWidth = strokeWidth
  }

  // get keyword causes this method to be called
  // when you use myRectangle.area
  get area () {
    return this.width * this.height
  }

  // gets the X position of the left side
  get left () {
    // origin is at top left so just return x
    return this.x
  }

  // get X position of right side
  get right () {
    // x is left position + the width to get end point
    return this.x + this.width
  }

  // get the Y position of top side
  get top () {
    // origin is at top left so just return y
    return this.y
  }

  // get Y position at bottom
  get bottom () {
    return this.y + this.height
  }

  // draw rectangle to screen
  draw () {
    // destructuring
    const {
      x, y, width, height,
      fillColor, strokeColor, strokeWidth
    } = this

    // saves the current styles set elsewhere
    // to avoid overwriting them
    ctx.save()

    // set the styles for this shape
    ctx.fillStyle = fillColor
    ctx.lineWidth = strokeWidth

    // create the *path*
    ctx.beginPath()
    ctx.strokeStyle = strokeColor
    ctx.rect(x, y, width, height)

    // draw the path to screen
    ctx.fill()
    ctx.stroke()

    // restores the styles from earlier
    // preventing the colors used here
    // from polluting other drawings
    ctx.restore()
  }
}

rectangle-class.js

rectangle class

Classes are optional and if the syntax confuses you, then just think of it as an object with methods and properties. Classes aside, two more canvas functions were introduced in the draw method:

ctx.save() — saves the current styles

ctx.restore() — restores the last saved styles

We use these methods to prevent the issue we saw with the fourth square that had unexpected colors.

Canvas stores styles on a stack structure. When we call ctx.save() it pushes the current styles onto the stack and calling ctx.restore() pops it off the stack.

This is image title
style stack animated

I only saved one set of styles in this animation but you can save as many times as you want and restore the most recent styles. Note that saving does not reset the current styles.

Styles include:
strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, lineDashOffset, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation, font, textAlign, textBaseline, direction, imageSmoothingEnabled
— MDN

We can now start putting this Rectangle class to use:

// create a new rectangle object using the Rectangle class
const mySquare = new Rectangle(400, 85, 50, 50, 'gold')

// now we have data and methods to describe our square
console.log(mySquare)
// Object
// fillColor: "gold"
// height: 50
// strokeColor: ""
// strokeWidth: 2
// width: 50
// x: 450
// y: 100
// area: (...)
// bottom: (...)
// left: (...)
// right: (...)
// top: (...)

// draw the square data to screen
mySquare.draw()

using-rectangle-class.js

create a new square using Rectangle class

The Result:

This is image title
square drawing from rectangle class

Note: I added a grid for the screenshots. We’ll be making a grid at the end of this section.

We can keep reusing the class to make more squares/rectangles:


// mySquare from earlier...
// const mySquare = new Rectangle(400, 85, 50, 50, 'gold')

// lets use the helper methods to
// draw shapes on the sides of mySquare
const childrenSquares = [
  // top side square - align x with mySquare's left side
  // align bottom with top of mySquare
  new Rectangle(mySquare.left, mySquare.top - 50, 50, 50, 'red'),

  // right side square - align x with right side of mySquare
  // align top with mySquare top
  new Rectangle(mySquare.right, mySquare.top, 50, 50, 'green'),

  // bottom square
  new Rectangle(mySquare.left, mySquare.bottom, 50, 50, 'blue'),

  // left square
  new Rectangle(mySquare.left - 50, mySquare.top, 50, 50, 'magenta')
]

// draw all of the child squares by looping over them
childrenSquares.forEach(square => square.draw())

children-squares.js

child squares nonsense

We create an array and populate it with new Rectangles positioned based on the mySquare object created earlier. Then we loop over the array and call the draw method on every square.

What do we get from all that code?

This is image title

child squares?

Well… it’s something.

I know this is all boring and tedious but we’ve covered the basics of canvas and you’ve at least seen what a class looks like now. Let’s finish creating more shapes. (it’ll go quicker from now on I promise)

Lines 🔗

Rectangles are the only pre-defined shape with canvas, we create other shapes on our own. We can use lines to build the foundation of these shapes.

// LINES

// save previous styles & set our current styles
ctx.save()
ctx.strokeStyle = 'blue'
ctx.fillStyle = 'blue'
ctx.lineWidth = 4

// stroked trapezoid
ctx.beginPath()
ctx.moveTo(50, 200) // sets our starting point
ctx.lineTo(100, 200) // create a line from start point to X: 100, Y: 200
ctx.lineTo(90, 180) // create the right side
ctx.lineTo(60, 180) // top side
ctx.closePath() // left side and closes the path
ctx.stroke() // draws it to screen via a stroke

// filled trapezoid
ctx.beginPath()
ctx.moveTo(150, 200) // starting point
ctx.lineTo(200, 200) // bottom side
ctx.lineTo(190, 180) // right side
ctx.lineTo(160, 180) // top side
// no need to closePath, fill automatically closes the path
ctx.fill()

// restore saved styles (for other examples)
ctx.restore()

lines-trapezoids.js

using lines to make trapezoid-like shapes

The Result:

This is image title

trapezoid things

New Methods:

ctx.moveTo(x, y) — you can think of this as moving our virtual “pen”, we use it to set the starting point for the first line

ctx.lineTo(x, y) — creates a line to X, Y; the starting point is the last position of our “pen”. This allows us to start new lines at the endpoint of previous lines.

ctx.closePath() — when using a stroke we need to call this to draw the final line and close the path. Fill will automatically close the path

Note: If you need curved lines then you can use Bézier curves with the quadratic or cubic bézier curve functions. I’ll cover them in another tutorial to keep this one from becoming too long.

Text 🔤

If you ever worked with any kind of text editor similar to Microsoft Word or any of Adobe’s tools, then these options will be familiar to you.

// TEXT

// usual setup
ctx.save()
ctx.strokeStyle = 'red'
ctx.fillStyle = 'black'

// text specific styles
ctx.font = 'bold 16px Monospace'
ctx.textAlign = 'left'
ctx.textBaseline = 'alphabetic'

// draw stroked text to screen
ctx.strokeText('Stroked Text', 50, 250)

// calculate the width of this text using current font/styles
const textWidth = ctx.measureText('Stroked Text').width

// X = previous X position + width + 25px margin
ctx.fillText('Filled Text', 50 + textWidth + 25, 250)

ctx.restore()

canvas-text.js

This is image title

ctx.strokeText(text, x, y) — creates the text path and strokes it

ctx.fillText(text, x, y) — same as above but fills the text

ctx.font(CSSFontString) — set the font using the CSS font format

ctx.measureText(text) — performs some calculations using the current styles and returns an object with the results, including the calculated width

The rest of the options are self-explanatory or require knowledge of font design, which is outside the scope of this tutorial.

Circles & Partial Circles (arcs) 🔴

// ARCS / Circles
// usual setup
ctx.save()
ctx.strokeStyle = 'black'
ctx.fillStyle = 'red'

// x, y, radius, startAngle, endAngle, antiClockwise = false by default
ctx.beginPath()
ctx.arc(50, 300, 15, 0, 2 * Math.PI, false) // full circle
ctx.fill()
ctx.stroke()

// half circle counter clockwise
ctx.beginPath()
ctx.arc(100, 300, 15, 0, Math.PI, true)
ctx.fill()
ctx.stroke()

// half circle clockwise
ctx.beginPath()
ctx.arc(150, 300, 15, 0, Math.PI)
ctx.fill()
ctx.stroke()

// pacman like
ctx.beginPath()
ctx.fillStyle = 'gold'
ctx.arc(200, 300, 15, 0.1 * Math.PI, 1.85 * Math.PI)
ctx.lineTo(200, 300)
ctx.fill()

ctx.restore()

canvas-arcs.js

circles / arcs code

This is image title

resulting circles/arcs

The only new function here is the arc method.

arc(x, y, radius, startAngle, endAngle, antiClockwise)

X, Y — defines the position of the center point, not the top left

radius — the size of the circle/arc

startAngle, endAngle — I think these are self-explanatory but it’s important to note that these angles are in Radians not degrees.

Math Aside: 1π (Pi) radians is equal to half a circle, 2π gives you a full circle.
Watch this video for more on the math of a circle

Triangles 🔺

As there are no triangle functions, we have to make them ourselves using lines.

// TRIANGLES
// usual setup
ctx.save()
ctx.strokeStyle = 'black'
ctx.fillStyle = 'orangered'

// Filled Triangle
ctx.beginPath()
ctx.moveTo(50, 400) // starting point
ctx.lineTo(50, 350) // left side
ctx.lineTo(100, 400) // hypotenuse / long side
ctx.fill() // closes the bottom side & fills

// stroked triangle
ctx.beginPath()
ctx.moveTo(150, 400) // starting point
ctx.lineTo(200, 400) // bottom side
ctx.lineTo(200, 350) // right side
ctx.closePath() // hypotenuse/long side (remember to close path for strokes!)
ctx.stroke()

ctx.restore()

canvas-triangle.js

This is image title

Nothing new here. Refer to the sections above if you’re lost. (or ask in the comments)

Quiz: Basic Shapes

  1. What arguments does the rect(_, _, _, _) function take?
  2. After you’ve used the rect function, what two methods can draw the rectangle to the screen? (the same functions for any path)
  3. What function can create circles?
  4. What two properties can we set to change the fill and outline styles?
  5. How do you set the starting position when using lineTo(x,y)

Answers: (links to related MDN pages)

  1. Rect function docs
  2. Drawing method 1, drawing method 2
  3. Function to draw circles
  4. strokeStyle, fillStyle
  5. ctx.moveTo(x,y)

Challenge: Visualize the Canvas Coordinate System

Use what you learned to draw a coordinate plane or grid with X and Y starting at the top left and end where the canvas ends.

Examples

This is image title

This is image title

Tips

  • Use for loops to create multiple lines
  • It can be a full grid, just text, or lines with tick marks… Make the grid you will want to use
  • As we haven’t covered animation yet, don’t worry about animating it. The example above was animated only for demonstration purposes.

Solution Don’t worry if you didn’t solve it, this one is challenging.

I started by making a new JS file and loading it instead of the example shapes from earlier.

<!-- index.html -->
<!-- <script src="js/index.js"></script> -->
<script src="js/gridSolution.js"></script>

Add the initial setup to your new JS file.

// gridSolution.js

;(function () {
  let canvas, ctx
  
  function init () {
    // set our config variables
    canvas = document.getElementById('gameCanvas')
    ctx = canvas.getContext('2d')
  }
  
  document.addEventListener('DOMContentLoaded', init)
})()

gridSolution-initial.js

initial setup for the grid solution

Now, decide if you want to make a reusable Grid class or create something simpler. I will keep it simple for this example solution by using only one function.

// draws a grid
function createGrid () {
  // draw a line every *step* pixels
  const step = 25

  // our end points
  const width = canvas.width
  const height = canvas.height

  // set our styles
  ctx.save()
  ctx.strokeStyle = 'gray' // line colors
  ctx.fillStyle = 'black' // text color

  // draw vertical from X to Height
  for (let x = 0; x < width; x += step) {

  }

  // draw horizontal from Y to Width
  for (let y = 0; y < height; y += step) {

  }

  // restore the styles from before this function was called
  ctx.restore()
}

function init () {
  // set our config variables
  canvas = document.getElementById('gameCanvas')
  ctx = canvas.getContext('2d')

  createGrid()
}

createGrid-starter.js

partial grid solution

Look at the above code, then try to fill in the blanks yourself if you haven’t already solved it. The next snippet will be the complete code.

This is image title
example solution result

// GRID CHALLENGE SOLUTION

;(function () {
  let canvas, ctx

  // draws a grid
  function createGrid () {
    // draw a line every *step* pixels
    const step = 50

    // our end points
    const width = canvas.width
    const height = canvas.height

    // set our styles
    ctx.save()
    ctx.strokeStyle = 'gray' // line colors
    ctx.fillStyle = 'black' // text color
    ctx.font = '14px Monospace'
    ctx.lineWidth = 0.35

    // draw vertical from X to Height
    for (let x = 0; x < width; x += step) {
      // draw vertical line
      ctx.beginPath()
      ctx.moveTo(x, 0)
      ctx.lineTo(x, height)
      ctx.stroke()

      // draw text
      ctx.fillText(x, x, 12)
    }

    // draw horizontal from Y to Width
    for (let y = 0; y < height; y += step) {
      // draw horizontal line
      ctx.beginPath()
      ctx.moveTo(0, y)
      ctx.lineTo(width, y)
      ctx.stroke()

      // draw text
      ctx.fillText(y, 0, y)
    }

    // restore the styles from before this function was called
    ctx.restore()
  }

  function init () {
    // set our config variables
    canvas = document.getElementById('gameCanvas')
    ctx = canvas.getContext('2d')

    createGrid()
  }

  document.addEventListener('DOMContentLoaded', init)
})()

grid-example-final-solution.js

final example grid code

Feel free to tweak your grid and save it for future use. I saved the animated one as an NPM package to use with upcoming tutorials.

Final Challenge: Draw Some Art

Now it’s time to put everything you’ve learned to use, here’s your challenge:

Draw a picture using a combination of the shapes we learned. Find some reference images or make something up.

Ideas

  • Emojis / Faces
  • Flags (Japan’s flag? 😂)
  • 2D Game/Cartoon Characters
  • Logos
  • Charts (bar chart, pie chart, etc) — a little more advanced and I’ll be doing another tutorial on charts but if you want to try it on your own go for it.
  • Landscape — draw a house, some grass, a sun or perhaps a starry night sky
  • Search for examples on CodePen to get ideas (prepare to be overwhelmed by the crazy art some people make)

Tips

  • Use canvas.height / 2 and canvas.width / 2 to get the center X, Y of the canvas
  • If you did the grid challenge from earlier, now is a good time to use it
  • If your drawing needs a lot of curves, look into the bezier curve functions: quadraticCurveTo and bezierCurveTo
  • Try finding some examples on CodePen
  • Keep it simple. This challenge is just to practice drawing shapes on the canvas, not to create some complex game character.

When you finish share a link to your CodePen / GitHub repository in the comments.

Reflection

What did you struggle with the most? Or was everything a cakewalk? What could have been different? I would love to hear your feedback in the comments. Otherwise, note what you struggled with and spend more time researching and reviewing that topic.

#html5 #javascript #Canvas

Learning JavaScript: Working with Strings

Strings are the second most common data type used in JavaScript, and in many cases, since JavaScript is so widely used for web applications, it is the prominent data type. In this article I’ll discuss how strings work in JavaScript and how to work with them efficiently and effectively. I’ll also discuss some newer abilities of strings that are just being discovered and used.

Strings Defined

A string is any set of 0 or more characters enclosed in either single quotes or double quotes. The characters in a string can be alphabetic characters, numbers, symbols, and spaces. Here are some examples of JavaScript string literals:

"hello world"
'good bye, world!'
"1600 Pennsylvania Avenue"
'$*&!@ it!'

If you are using single quotes in your string, and you need to embed a single quote to write out a contraction, you use the backslash character (\) as an escape character. To see why you need to do this, let’s look at what happens when you don’t escape a single quote by writing out such a string in the JavaScript shell:

js> 'can't'
typein:1:5 SyntaxError: unexpected token: identifier:
typein:1:5 'can't'
typein:1:5 .....^

The interpreter can’t figure out what to do with the ‘t’ after the single quote.

Now watch what happens when we escape the single quote:

js> 'can\'t'
"can't"

The escape character tells the interpreter to treat the single quote as an apostrophe and not as an “end-of-string” character.

You can embed other characters into a string, including the newline character (\n) and the tab character (\t). Here are some examples using the shell:

js> print("Hello, \n world!");
Hello,
world!
js> print("Hello, \tworld");
Hello,  world

#javascript-training #learn-to-code #learn-to-program #javascript #javascript-tutorial #deep learning

Learning JavaScript: Computing with Object Methods

JavaScript has a set of built-in methods you can use with your user-defined objects. In this article I’m going to discuss several of these methods and how you can use them in your JavaScript programs.

Object.assign

The Object.assign method is used to make a copy of one object into another object. The syntax template for this method is:

Object.assign(target, source);

where source is the object you are copying from and target is the object you are copying into. This method returns the target object if you want to assign it.

Here is a sample program that demonstrates how to use Object.assign:

function Student(name, id, grades) {
  this.name = name;
  this.id = id;
  this.grades = grades;
}
let st1 = new Student("",0,[]);
et st2 = new Student("Jane Doe", 123, [91, 92, 93]);
Object.assign(st1, st2);
print(`${st1.name}, ${st1.id}\n[${st1.grades}]`);

The output from this program is:

Jane Doe, 123
[91, 92, 93]

A good reason to use this method is to make sure that a new object has all the properties and values of the old object. You may accidentally leave something out when writing your own method, while Object.assign will systematically make sure all properties and values are assigned to the new object.

Object.create

The Object.create method creates a new object from an existing object prototype. Here is the syntax template for this method:

const|let|var object-name = Object.create(existing-object);

Let’s look at a few examples to see how this method works in practice. The first example creates a new object from a function and then creates a second object using Object.create:

function Student(name, id, grades) {
  this.name = name;
  this.id = id;
  this.grades = grades;
}
let st1 = new Student("Bob Green", 1234, [81, 77, 92]);
print(`${st1.name}, ${st1.id}\n${st1.grades}`);
let st2 = Object.create(st1);
print(`${st2.name}, ${st2.id}\n${st2.grades}`);

The output from this program is:

Bob Green, 1234
81,77,92
Bob Green, 1234
81,77,92

Code must be written to change the properties of the newly created object.

#learn-to-code #javascript-development #learn-to-program #javascript #learning-javascript

Tia  Gottlieb

Tia Gottlieb

1596632340

Learning JavaScript: Statements, Arithmetic, and Math

In this article I will discuss how to perform arithmetic and more advanced mathematical operations in JavaScript. First, though, I need to discuss how statements are formed and used in JavaScript.

Statements

JavaScript programs are made up of statements. A statement can be anything from a single function call or command to even just a variable name. JavaScript evaluates statements and then executes them.

For example, when you create a variable, you write a statement:

let number = 100;

JavaScript recognizes this as a statement and evaluates it by following its grammar rules. In this case the rule is to assign the expression on the right-hand sign of the assignment operator to the variable on the left-hand side.

As I mentioned above, a statement can be just an expression, as in the following example:

js> 1;
1

You can do the same thing with a variable:

js> let name = "Brendan";
js> name
"Brendan"

Statements can be much more complicated than these examples, though, as you’ll learn as you get deeper into JavaScript. So far, you have seen examples of two types of statements — variable declaration and assignment statements and print statements.

JavaScript Arithmetic

Arithmetic is performed in JavaScript using the arithmetic operators. There are five arithmetic operators:

  • + (Addition)
  • - (Subtraction)
  • * (Multiplication)
  • / (Division)
  • % (Modulo/Remainder)

These operators are binary operators, meaning there must be values on either side of the operator. The + operator and the -operator can also be used as unary operators, in which can they are used to distinguish the sign (positive or negative) of a number.

The JavaScript arithmetic operators also have an order of operations, or precedence, they follow when used in a statement. The order of operations is: 1) modulo; 2) multiplication and division; 3) addition and subtraction.

You can use parentheses to modify the order of operations. When an arithmetic expression is placed inside parentheses, that expression is evaluated before any other operations.

For example, take the expression:

let n = 100 + 3 * 22;

Does n get the value 2266, 103 * 26, or does the variable get the value 166? Without parentheses the value of n is 166 because the multiplication takes place before the addition due to the precedence of the multiplication operator over the addition operator.

#learn-to-code #learning-javascript #javascript #learn-to-program #deep learning