<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: mishafb</title>
    <description>The latest articles on DEV Community by mishafb (@mishafb).</description>
    <link>https://dev.to/mishafb</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F225136%2Fa8498654-6351-4990-ab18-aed1f7b7c82d.png</url>
      <title>DEV Community: mishafb</title>
      <link>https://dev.to/mishafb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mishafb"/>
    <language>en</language>
    <item>
      <title>An introduction to the canvas</title>
      <dc:creator>mishafb</dc:creator>
      <pubDate>Sat, 07 Sep 2019 12:45:23 +0000</pubDate>
      <link>https://dev.to/mishafb/an-introduction-to-the-canvas-2ffe</link>
      <guid>https://dev.to/mishafb/an-introduction-to-the-canvas-2ffe</guid>
      <description>&lt;h2&gt;
  
  
  Prerequisites:
&lt;/h2&gt;

&lt;p&gt;This tutorial is made for beginners. It's enough if you know that &lt;code&gt;let&lt;/code&gt; is the block scope &lt;code&gt;var&lt;/code&gt; and you know how to use &lt;code&gt;const&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Who this is for
&lt;/h3&gt;

&lt;p&gt;Most of your webapps so far probably consisted of getting inputs from elements, listening to button presses, modifying texts, and maybe even making new elements. This quick tutorial will teach you how to make graphics in JS starting with basic shapes, but the possibilities are endless!&lt;/p&gt;

&lt;h2&gt;
  
  
  The &amp;lt;canvas&amp;gt; element
&lt;/h2&gt;

&lt;p&gt;The canvas element (from now on just called canvas) is the only element that can be drawn on. Before you draw on a canvas, it's completely transparent. The default size for a canvas is 300 by 150 pixels. This size can be changed with the &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; attributes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; you can scale a canvas with CSS, but if the aspect ratio (ratio between width and height) is different, the image will stretch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; As of the time of writing, &lt;a href="https://caniuse.com/#feat=canvas" rel="noopener noreferrer"&gt;98.9% of browsers support canvas&lt;/a&gt;, so you shouldn't worry about compatibility because that's as common as &lt;a href="https://caniuse.com/#feat=css3-boxsizing" rel="noopener noreferrer"&gt;CSS3 Box-sizing&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting everything up
&lt;/h2&gt;

&lt;p&gt;To draw on a canvas, first get a reference to that canvas in the JS. The simplest and most common way to do so is using &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById" rel="noopener noreferrer"&gt;&lt;code&gt;document.getElementById('id')&lt;/code&gt;&lt;/a&gt; which returns the element that has that specific &lt;code&gt;id&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p&gt;index.html&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Canvas Tutorial&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"style.css"&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/css"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;canvas&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"my-first-canvas"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"480"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"270"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/canvas&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"script.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &amp;lt;canvas&amp;gt; tags must be closed.&lt;/p&gt;

&lt;p&gt;style.css&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;script.js&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-first-canvas&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can &lt;a href="https://repl.it/@liltaco/Canvas-Tutorial-Starter" rel="noopener noreferrer"&gt;fork this super minimalist starter on Repl.it&lt;/a&gt; if you want to save the hassle of copying and pasting this yourself. All following snippets only apply to the JS; the HTML and CSS will stay the same.&lt;/p&gt;
&lt;h2&gt;
  
  
  The rendering context
&lt;/h2&gt;

&lt;p&gt;The canvas element is just an element. In order to draw on it, you need to get a &lt;em&gt;rendering context&lt;/em&gt;. Rendering contexts are the ways you can draw on a canvas. Currently, these are &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D" rel="noopener noreferrer"&gt;&lt;code&gt;CanvasRenderingContext2D&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext" rel="noopener noreferrer"&gt;&lt;code&gt;WebGLRenderingContext&lt;/code&gt;&lt;/a&gt;. 2D is the simplest to work with; it gives you functions for all kinds of shapes, texts and images. The main drawback of the 2D rendering context is that it runs on the CPU and not on the GPU, so it's much slower than WebGL. WebGL is a port of OpenGL ES 2.0 (a low-level graphics library) to the web that allows advanced graphics on the GPU. However, it's very complicated to use without libraries. This tutorial will only use the 2D rendering context.&lt;/p&gt;

&lt;p&gt;To get the 2D rendering context, just type:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2d&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Drawing
&lt;/h2&gt;

&lt;p&gt;Now that you have your rendering context, you can draw your very first rectangle:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;ctx.fillRect&lt;/code&gt; accepts 4 parameters: &lt;code&gt;x, y, width, height&lt;/code&gt;. The line &lt;code&gt;ctx.fillRect(0, 0, 50, 100)&lt;/code&gt; will fill a rectangle with a width of 50 and a height of 100 with its top-left corner at &lt;code&gt;x = 0&lt;/code&gt; and &lt;code&gt;y = 10&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The position &lt;code&gt;x: 0, y: 0&lt;/code&gt; is at the top-left corner, so a higher X value goes to the right and a higher Y value goes downwards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Everything you draw on a canvas will stick around until you either draw something on top of it or change the &lt;code&gt;width&lt;/code&gt; and &lt;code&gt;height&lt;/code&gt; attributes.&lt;/p&gt;
&lt;h3&gt;
  
  
  Colors
&lt;/h3&gt;

&lt;p&gt;Colors in the 2D rendering context can be any CSS color, so you can write them hexadecimal, &lt;code&gt;rgb(1, 2, 3)&lt;/code&gt;, &lt;code&gt;hsl(120, 100%, 50%)&lt;/code&gt;, &lt;code&gt;rgba&lt;/code&gt;, &lt;code&gt;hsla&lt;/code&gt;, and conveniently you can use a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#Color_keywords" rel="noopener noreferrer"&gt;color keyword&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, let's apply color to the rectangle.&lt;/p&gt;

&lt;p&gt;There's &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle" rel="noopener noreferrer"&gt;&lt;code&gt;ctx.fillStyle&lt;/code&gt;&lt;/a&gt; which is the color for filled shapes and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle" rel="noopener noreferrer"&gt;&lt;code&gt;ctx.strokeStyle&lt;/code&gt;&lt;/a&gt; for the color of the outlined shapes. Once you set the color, everything you draw will be drawn in that color until you change it.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;strokeStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strokeRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;75&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// x, y, width, height&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fi0yb50xollw0b7xdhupr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fi0yb50xollw0b7xdhupr.png" alt="Result of the previous code snippet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating abstract art has never been easier!&lt;/p&gt;

&lt;p&gt;In addition to &lt;code&gt;fillRect&lt;/code&gt; and &lt;code&gt;strokeRect&lt;/code&gt;, there's also &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clearRect" rel="noopener noreferrer"&gt;&lt;code&gt;clearRect&lt;/code&gt;&lt;/a&gt;. clearRect also gets &lt;code&gt;x, y, width, height&lt;/code&gt; parameters, but clearRect will make everything inside of the rectangle transparent. If you want to clear the whole canvas, you can also do &lt;code&gt;canvas.width = canvas.width&lt;/code&gt; or &lt;code&gt;canvas.height = canvas.height&lt;/code&gt; because setting the canvas size will clear it too.&lt;/p&gt;
&lt;h2&gt;
  
  
  Advanced shapes
&lt;/h2&gt;

&lt;p&gt;A path is a list of lines, which can be straight or curved. Once you have created a path, you call &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fill" rel="noopener noreferrer"&gt;&lt;code&gt;ctx.fill()&lt;/code&gt;&lt;/a&gt; or &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/stroke" rel="noopener noreferrer"&gt;&lt;code&gt;ctx.stroke()&lt;/code&gt;&lt;/a&gt; or even both to draw the path on the canvas.&lt;/p&gt;
&lt;h3&gt;
  
  
  Essential functions:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/beginPath" rel="noopener noreferrer"&gt;&lt;code&gt;ctx.beginPath()&lt;/code&gt;&lt;/a&gt; resets the path, always run this before drawing something so it won't get mixed up with what you just drew.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/moveTo" rel="noopener noreferrer"&gt;&lt;code&gt;ctx.moveTo(x, y)&lt;/code&gt;&lt;/a&gt; 'raises' the path pen and moves it to a position.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineTo" rel="noopener noreferrer"&gt;&lt;code&gt;ctx.lineTo(x, y)&lt;/code&gt;&lt;/a&gt; will move the path pen to the given point in a straight line.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/closePath" rel="noopener noreferrer"&gt;&lt;code&gt;ctx.closePath()&lt;/code&gt;&lt;/a&gt; moves the path pen from the last point to the first point in a straight line.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to draw curved lines or do something more advanced like path clipping, you can see the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D#Paths" rel="noopener noreferrer"&gt;complete list of path methods&lt;/a&gt; from MDN.&lt;/p&gt;

&lt;p&gt;Now, let's draw our first triangle!&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;strokeStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strokeRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;75&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;beginPath&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;    &lt;span class="c1"&gt;// reset the path&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;moveTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// raise the pen to x = 60 and y = 20&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lineTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// move the pen in a straight line to x = 20 and y = 50&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lineTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// move the pen in a straight line to x = 60 and y = 80&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;closePath&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;    &lt;span class="c1"&gt;// move the pen back to the starting position of x = 60 and y = 20&lt;/span&gt;

&lt;span class="c1"&gt;// Note: when using ctx.fill(), ctx.closePath() is not required;&lt;/span&gt;
&lt;span class="c1"&gt;// if the path wasn't a closed one, ctx.fill() will draw it the same.&lt;/span&gt;
&lt;span class="c1"&gt;// However, ctx.stroke() will not.&lt;/span&gt;

&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;strokeStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lineWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="c1"&gt;// ctx.lineWidth will decide how thick the outline is when running ctx.stroke()&lt;/span&gt;
&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0wkzglh7oeil8vvef7t3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F0wkzglh7oeil8vvef7t3.png" alt="Result of the previous code snippet"&gt;&lt;/a&gt;&lt;br&gt;
It's coming together!&lt;/p&gt;
&lt;h2&gt;
  
  
  Common Shapes
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Circle
&lt;/h3&gt;

&lt;p&gt;There is no &lt;code&gt;ctx.circle&lt;/code&gt; function, but there are 2 main ways to draw circles in the canvas.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/ellipse" rel="noopener noreferrer"&gt;&lt;code&gt;ctx.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle)&lt;/code&gt;&lt;/a&gt; - as of writing this, it isn't supported on the Android webview which is an issue. That's why I usually use:&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arc" rel="noopener noreferrer"&gt;&lt;code&gt;ctx.arc(x, y, radius, 0, Math.PI * 2)&lt;/code&gt;&lt;/a&gt; - the 0 and the Math.PI * 2 are the startAngle and endAngle.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here are some circles you can play around with:&lt;/p&gt;


&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@liltaco/Canvas-Tutorial-Circles?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  Rounded Rectangles
&lt;/h3&gt;

&lt;p&gt;There is no &lt;code&gt;ctx.roundedRect()&lt;/code&gt; function, but you can use this modified snippet from MDN:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;CanvasRenderingContext2D&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;roundedRect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;moveTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lineTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arcTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lineTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arcTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lineTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arcTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lineTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arcTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just add this to the beginning of your code and every 2D rendering context will have the &lt;code&gt;ctx.roundedRect&lt;/code&gt; method. (&lt;a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes" rel="noopener noreferrer"&gt;&lt;code&gt;Object.prototype&lt;/code&gt;&lt;/a&gt; is basically a way to give every instance a new method).&lt;/p&gt;

&lt;h2&gt;
  
  
  Transformations
&lt;/h2&gt;

&lt;p&gt;Sometimes, you may want to scale, move, or rotate everything you draw on the canvas.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/save" rel="noopener noreferrer"&gt;&lt;code&gt;ctx.save()&lt;/code&gt;&lt;/a&gt; pushes the current transformation state&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/restore" rel="noopener noreferrer"&gt;&lt;code&gt;ctx.restore()&lt;/code&gt;&lt;/a&gt; pops the previous transformation state&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/translate" rel="noopener noreferrer"&gt;&lt;code&gt;ctx.translate(x, y)&lt;/code&gt;&lt;/a&gt; moves the canvas origin &lt;code&gt;x&lt;/code&gt; units to the right and &lt;code&gt;y&lt;/code&gt; units down. Everything you draw will be moved that much.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/scale" rel="noopener noreferrer"&gt;&lt;code&gt;ctx.scale(x, y)&lt;/code&gt;&lt;/a&gt; multiplies every unit by &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;; if it's less than 1 it scales everything down and if it's more than 1 it scales everything up.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/rotate" rel="noopener noreferrer"&gt;&lt;code&gt;ctx.rotate(angle)&lt;/code&gt;&lt;/a&gt; rotates everything you draw from now on by &lt;code&gt;angle&lt;/code&gt; radians.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Transformation order matters!
&lt;/h3&gt;

&lt;p&gt;If you do &lt;code&gt;ctx.scale(2, 2)&lt;/code&gt; and then &lt;code&gt;ctx.translate(10, 10)&lt;/code&gt;, then everything will be translated 20 units by the original scale, but if you do &lt;code&gt;ctx.translate(10, 10)&lt;/code&gt; and then &lt;code&gt;ctx.scale(2, 2)&lt;/code&gt; everything will be translated 10 units by the original scale. The same applies for rotation too.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transformations stack!
&lt;/h3&gt;

&lt;p&gt;If you run &lt;code&gt;ctx.scale(1.1, 1.1)&lt;/code&gt; then &lt;code&gt;ctx.scale(1.1, 1.1)&lt;/code&gt; again will scale everything up by 21%. Each transformation will stack up on the previous transformation state the same as it would on an empty transformation state.&lt;/p&gt;

&lt;p&gt;Try my &lt;a href="https://canvas-tutorial-transformations-playground.liltaco.repl.co/" rel="noopener noreferrer"&gt;Transformation Playground&lt;/a&gt; to learn by doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Notes
&lt;/h2&gt;

&lt;p&gt;You generally can't put elements inside of a canvas since they aren't shown, but if a user has an ancient browser like Internet Explorer 8 from 2009, any elements inside the canvas will be visible. Therefore you can place some content describing what should be on the canvas in there or just say "Your browser doesn't support canvas" as fallback.&lt;/p&gt;

&lt;p&gt;If you want to draw on top of another element, just place the canvas on top of it with CSS, then draw on the canvas (remember that a canvas is transparent by default).&lt;/p&gt;

&lt;p&gt;Another useful tip is that if you want to draw in layers, i.e. not erase the background when erasing an overlay (useful for games where backgrounds are mostly static but need to be drawn), you can place a canvas on top of another canvas with CSS.&lt;/p&gt;

&lt;h2&gt;
  
  
  That's it for this tutorial!
&lt;/h2&gt;

&lt;p&gt;Here are some pointers that you should read through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_text#Drawing_text" rel="noopener noreferrer"&gt;MDN tutorial on drawing text&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Using_images" rel="noopener noreferrer"&gt;MDN tutorial on drawing images&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Next up:&lt;/strong&gt; Mouse and keyboard input for your interactive webapps
&lt;/h2&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
