How To Code A Drawing App
Creating and Drawing on an HTML5 Sail using JavaScript
Allow'due south explore what the canvas is and draw some shapes.
Prerequisites / Info
- This is part of the JS Game Dev Series
- Yous should have some noesis of JavaScript — I will not explain irrelevant syntax such as for-loops
- Cognition of ES6 Classes is helpful but not required
- Bones math/geometry knowledge
- Basic artistic skills
Starter Lawmaking
I moved this to a dissever page to continue this article short and then I only have to update it in 1 place.
Terminal Code for this Tutorial
You can get all the code from this tutorial on the repository beneath. Go on in mind there's likewise a lot of lawmaking included that's not written here. This is considering I added more than lawmaking to create screenshots/diagrams for this tutorial.
Note: As the focus of this tutorial is not building a projection, you don't need to re-create every line exactly. In fact, since we'll be covering many examples, I encourage you to play with information technology and make a mess.
What is the Canvas Element?
Some quick bullet points to introduce yous to the sheet.
- Introduced with HTML version 5 to draw graphics using JavaScript
- Graphics can exist 2D or 3D and information technology'due south 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 sail at that place are five steps to get started.
- Create the sail element — requite it an id, and a width/height (HTML)
- Add base styles — center the canvas, add together a groundwork color, etc (CSS)
- In JavaScript, go your canvas element by using the id
- Use the sail chemical element to get the context (your toolbox; more on it later)
- Use the context to draw
Nosotros'll do steps ane and two in HTML/CSS, just y'all could exercise it in JavaScript if you lot adopt.
Steps 1 and ii for this project
Our average / CodePen template already covered setting up the basic styles and calculation a canvass element. For this project, I will change the canvass width/height to be 800x1200 to give us enough of space.
// index.html
<canvas id="gameCanvas" width="800" height="1200"></canvas>
I too changed the sheet background to be white and added some margin to the bottom.
// styles.css
torso {
background: #111;
color: #f8f8f8;
} canvas {
background: #f8f8f8;
padding: 0;
margin: 0 car;
margin-lesser: 1rem;
brandish: cake;
}
Steps 3 and four
Get the canvas element by id, and so use it to get the "2d" context.
certificate.getElementById('gameCanvas')
— searches for an HTML chemical element that has the id of gameCanvas
. Once it finds the element, nosotros tin can so manipulate information technology with JavaScript.
canvas.getContext()
— context is our toolbox of paintbrushes and shapes. The 2D context contains the fix of tools nosotros want. If you were working with 3D, y'all would use WebGL instead.
Merely look what'southward with the function thingy wrapping all of this?
This is an immediately invoked function expression (IIFE). We use information technology to prevent our lawmaking from leaking out in the global telescopic. This has several benefits such equally preventing players (if this were a game) from accessing your variables direct and prevents your code from colliding with someone else's lawmaking (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 than about security in a time to come article, for now, allow's get to cartoon stuff.
The Canvas Coordinate Organisation
By default, the coordinate system starts at the tiptop left. (X: 0, Y: 0) Moving down or to the correct increases X and Y positions. You tin play with the example below on this folio.
Quiz: The Canvas Chemical element
- How do you select the canvas chemical element in JavaScript?
- How do yous get the context?
- Where is Ten: 0, Y: 0 on the canvas by default?
Elementary Shapes
Permit's brand use of the 2d context object to describe shapes. Feel costless to reference the documentation page at whatsoever time.
There will likewise exist a link to each method we apply.
Just wait for the DOM…
Earlier 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 mind for the DOMContentLoaded
event. We volition call this part init
(for initialize).
Remember: everything stays inside the IIFE wrapper. I won't be showing information technology in the example code from now on. If you ever get lost refer to the completed project here .
We desire our canvas and context variables to be available to all of our functions. This requires defining them up top and and so giving them a value in the init
function once the DOM loads. This completes our setup.
Notation: A more than scalable option is to accept the context variable as an argument to our cartoon functions.
Rectangles / Squares 🔲
Allow's showtime by creating a foursquare:
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 foursquare 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 matter equally an outline or border
ctx.fillRect(x, y, width, superlative)
— like to strokeRect
simply this fills in the rectangle with a color
The Result:
There are a few things to annotation here:
- The colors default to blackness stroke and blackness fill.
- The origin bespeak or X: 0, Y: 0 for these shapes are at their top left, similar to the sheet.
- I just picked a random x, y for the commencement square then added 50 + 50+ 25 (previous square 10 + previous square width + 25px margin) for the x position.
What if we want to change the color/style? Allow's add together a crimson outlined foursquare that'due south also filled with blue.
Position first:
- X = 200 previous square width + previous position + 25px margin = 50 + 125 + 25
- Y = 35 We will go along it in the same row
- The size will be the same (50 10 50)
ctx.beginPath()
ctx.strokeRect(200, 35, l, fifty) // plugging in our new position
But look… we desire a fill AND a stroke, does this mean we have to draw two squares? You lot can describe ii squares but nosotros volition make utilise of several other methods instead.
The Result:
ctx.rect(ten, y, width, acme)
— this is similar the other two rectangle methods, but it does not immediately describe information technology. It creates a path for the square in retentivity, we so configure the stroke, fill, and stroke width earlier calling ctx.fill
and/or ctx.stroke
to describe information technology on screen
ctx.strokeStyle = 'any valid css colour'
— sets the outline/stroke color to any string that works in CSS. i.e. 'bluish', '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 electric current path
Drawing any shape e'er follows these steps:
- Ready the styles — optional and can exist set any time before rendering
- Begin the path — starting time creating the virtual path (not fatigued to screen all the same)
- Utilize the path functions to create a shape — i.eastward. the
rect
method - Describe the path to the screen — using fill up or stroke
Note: We did not need to apply the
ctx.rect()
function merely to alter the colors, we used it considering we wanted both a stroke and a fill. Yous can merely as easily setctx.fillStyle
and usectx.fillRect()
Setting the fill or stroke style will crusade whatsoever shapes created after, to take the aforementioned style. For example, if we add a 4th foursquare using the lawmaking below it would have the same style equally the third foursquare.
// quaternary foursquare, uses the same manner defined previously
ctx.beginPath()
ctx.rect(275, 35, 50, l)
ctx.fill()
ctx.stroke()
Outcome:
Anytime you desire to add a fill/stroke to your shapes, explicitly define the styles.
Optimizing our Code with Classes
Making use of classes we tin create a robust Rectangle object and clean upwardly our code.
Classes are functions that create Objects. We want to create Rectangle objects that contain information about themselves, such as their position, styles, expanse, and dimensions.
I won't go into much detail on classes as it's non required and you lot tin can get by with normal functions. Cheque the MDN documentation page on classes to acquire more about them.
Classes are optional and if the syntax confuses you lot, then just think of it as an object with methods and properties. Classes aside, 2 more canvas functions were introduced in the describe method:
ctx.save()
— saves the current styles
ctx.restore()
— restores the last saved styles
We utilise 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 electric current styles onto the stack and calling ctx.restore()
pops it off the stack.
I merely saved one gear up of styles in this animation just you tin can salve as many times as y'all desire and restore the near 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 tin now get-go putting this Rectangle class to utilise:
The Upshot:
Notation: I added a grid for the screenshots. We'll be making a grid at the end of this department.
We can keep reusing the class to make more than squares/rectangles:
We create an array and populate it with new Rectangles positioned based on the mySquare
object created earlier. Then nosotros loop over the array and telephone call the draw method on every foursquare.
What practise nosotros get from all that code?
Well… it'due south something.
I know this is all slow and boring but we've covered the nuts of canvas and you've at least seen what a class looks like now. Let's finish creating more shapes. (it'll become 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.
The Consequence:
New Methods:
ctx.moveTo(10, y)
— you lot tin 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 signal 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 nosotros demand to call this to draw the terminal line and close the path. Fill up will automatically close the path
Note: If y'all need curved lines so 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 ane from becoming too long.
Text 🔤
If yous ever worked with whatever kind of text editor similar to Microsoft Give-and-take or whatsoever of Adobe's tools, so these options will be familiar to you lot.
ctx.strokeText(text, 10, y)
— creates the text path and strokes it
ctx.fillText(text, x, y)
— same as above merely fills the text
ctx.font(CSSFontString)
— set the font using the CSS font format
ctx.measureText(text)
— performs some calculations using the electric current styles and returns an object with the results, including the calculated width
The rest of the options are cocky-explanatory or require knowledge of font design, which is outside the scope of this tutorial.
- ctx.textAlign
- ctx.textBaseline
Circles & Partial Circles (arcs) 🔴
The only new function hither is the arc
method.
arc(x, y, radius, startAngle, endAngle, antiClockwise)
Ten, Y
— defines the position of the eye betoken, non the top left
radius
— the size of the circle/arc
startAngle, endAngle
— I think these are self-explanatory simply information technology'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.
Sentinel this video for more on the math of a circumvolve
Triangles 🔺
As there are no triangle functions, we have to make them ourselves using lines.
Cypher new here. Refer to the sections above if you're lost. (or ask in the comments)
Quiz: Basic Shapes
- What arguments does the
rect(_, _, _, _)
function take? - Afterwards you've used the
rect
function, what ii methods can draw the rectangle to the screen? (the same functions for whatsoever path) - What function can create circles?
- What ii backdrop can nosotros set to change the fill and outline styles?
- How do you ready the starting position when using
lineTo(x,y)
Answers: (links to related MDN pages)
- Rect function docs
- Drawing method 1, cartoon method 2
- Function to draw circles
- strokeStyle, fillStyle
- ctx.moveTo(ten,y)
Challenge: Visualize the Canvas Coordinate System
Use what yous learned to describe a coordinate aeroplane or filigree with 10 and Y starting at the summit left and stop where the canvass ends.
Examples
Tips
- Utilize for loops to create multiple lines
- It tin be a full grid, just text, or lines with tick marks... Brand the grid you volition desire to use
- As we haven't covered animation yet, don't worry almost animating it. The instance above was blithe 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.
At present, decide if yous desire to make a reusable Grid class or create something simpler. I will keep it simple for this example solution by using merely i function.
Look at the in a higher place code, so attempt to fill up in the blanks yourself if you haven't already solved information technology. The next snippet will be the consummate code.
Feel free to tweak your filigree and save it for future use. I saved the animated one as an NPM bundle to use with upcoming tutorials.
Final Challenge: Draw Some Art
Now it's time to put everything you've learned to employ, here'south your challenge:
Describe a picture using a combination of the shapes nosotros learned.
Observe some reference images or make something up.
Ideas
- Emojis / Faces
- Flags (Japan's flag? 😂)
- 2D Game/Cartoon Characters
- Logos
- Charts (bar nautical chart, pie chart, etc) — a little more than avant-garde and I'll be doing another tutorial on charts but if yous want to endeavor it on your ain go for it.
- Mural — draw a house, some grass, a dominicus or perhaps a starry night sky
- Search for examples on CodePen to go ideas (prepare to be overwhelmed past the crazy art some people make)
Tips
- Utilize
canvass.height / 2
andcanvas.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, await into the bezier bend functions: quadraticCurveTo and bezierCurveTo
- Try finding some examples on CodePen
- Go on it simple. This challenge is just to practice drawing shapes on the canvas, not to create some circuitous game graphic symbol.
When yous stop share a link to your CodePen / GitHub repository in the comments.
Reflection
What did y'all struggle with the most? Or was everything a cakewalk? What could accept been unlike? I would dear to hear your feedback in the comments. Otherwise, note what you struggled with and spend more time researching and reviewing that topic.
Resources and Links
Back to Index Page
Thank you for Reading!
I had to cutting a lot of data to go along this tutorial from getting too long simply we'll exist roofing pretty much everything throughout the series.
I would dearest to hear your feedback and questions! Leave a comment below or bulletin me on Twitter.
Source: https://codeburst.io/creating-and-drawing-on-an-html5-canvas-using-javascript-93da75f001c1
Posted by: cookshiled.blogspot.com
0 Response to "How To Code A Drawing App"
Post a Comment