draw 3d points from console firefox
Drawing graphics
Graphics on the Spider web
As nosotros talked about in our HTML Multimedia and embedding module, the Web was originally but text, which was very tedious, so images were introduced — first via the <img>
element and afterward via CSS properties such as groundwork-paradigm
, and SVG.
This however was still not enough. While y'all could apply CSS and JavaScript to breathing (and otherwise manipulate) SVG vector images — as they are represented past markup — there was still no way to do the aforementioned for bitmap images, and the tools available were rather limited. The Web still had no style to effectively create animations, games, 3D scenes, and other requirements commonly handled by lower level languages such as C++ or Java.
The situation started to improve when browsers began to support the <sail>
element and associated Canvas API — Apple invented it in effectually 2004, and other browsers followed by implementing it in the years that followed. Equally you'll see below, sail provides many useful tools for creating second animations, games, data visualizations, and other types of app, peculiarly when combined with some of the other APIs the web platform provides.
The below case shows a simple 2D canvas-based billowy balls blitheness that we originally met in our Introducing JavaScript objects module:
Around 2006–2007, Mozilla started work on an experimental 3D canvas implementation. This became WebGL, which gained traction amongst browser vendors, and was standardized around 2009–2010. WebGL allows you to create real 3D graphics inside your web browser; the below instance shows a simple rotating WebGL cube:
This commodity will focus mainly on 2D sheet, equally raw WebGL code is very complex. We will however show how to use a WebGL library to create a 3D scene more easily, and y'all tin can find a tutorial roofing raw WebGL elsewhere — come across Getting started with WebGL.
Annotation: Basic sail functionality is supported well beyond browsers, with the exception of IE viii and below for second canvas, and IE 11 and beneath for WebGL.
Active learning: Getting started with a <sail>
If you want to create a 2D or 3D scene on a web page, you need to get-go with an HTML <canvas>
chemical element. This chemical element is used to define the area on the page into which the image will be drawn. This is as unproblematic every bit including the element on the folio:
<sail width = "320" height = "240" > </canvas >
This will create a canvas on the page with a size of 320 by 240 pixels.
Inside the canvas tags, yous can put some fallback content, which is shown if the user's browser doesn't support sail.
<canvas width = "320" pinnacle = "240" > <p > Your browser doesn't support canvas. Boo hoo! </p > </sheet >
Of course, the above bulletin is really unhelpful! In a real example you'd want to relate the fallback content to the canvas content. For example, if you lot were rendering a constantly updating graph of stock prices, the fallback content could be a static image of the latest stock graph, with alt text saying what the prices are in text.
Creating and sizing our sail
Let's start by creating our own canvas that we describe future experiments on to.
- First brand a local re-create of our 0_canvas_start.html file, and open up it in your text editor.
- Add the following code into information technology, simply below the opening
<body>
tag:<canvas class = "myCanvas" > <p > Add suitable fallback here. </p > </sheet >
class
to the<canvas>
element and so information technology will be easier to select if we have multiple canvases on the folio, just we accept removed thewidth
andheight
attributes for now (you could add them back in if you wanted, merely nosotros will set them using JavaScript in a below section). Canvases with no explicit width and height default to 300 pixels wide by 150 pixels high. - Now add the following lines of JavaScript inside the
<script>
chemical element:const sail = certificate. querySelector ( '.myCanvas' ) ; const width = canvas.width = window.innerWidth; const superlative = canvass.tiptop = window.innerHeight;
canvas
constant. In the second line we set both a new constantwidth
and the canvass'width
holding equal toWindow.innerWidth
(which gives us the viewport width). In the third line we fix both a new abidingheight
and the canvas'height
property equal toWindow.innerHeight
(which gives united states the viewport summit). So now nosotros have a canvas that fills the entire width and tiptop of the browser window! You'll also see that we are chaining assignments together with multiple equals signs — this is allowed in JavaScript, and it is a good technique if you want to make multiple variables all equal to the same value. We wanted to brand the canvas width and height easily accessible in the width/top variables, as they are useful values to have bachelor for afterwards (for example, if you want to draw something exactly halfway across the width of the canvas). - If you save and load your example in a browser now, you lot'll see zip, which is fine, but you'll also encounter scrollbars — this is a trouble for united states, which happens because the
<body>
element has amargin
that, added to our full-window-size canvas, results in a document that'south wider than the window. To get rid of the scrollbars, we need to remove themargin
and likewise gear upoverflow
tohidden
. Add together the following into the<head>
of your document:<style > torso { margin : 0; overflow : subconscious; } </way >
Note: You should generally set the size of the epitome using HTML attributes or DOM properties, as explained above. You could utilise CSS, just the problem and so is that the sizing is washed after the sail has rendered, and but like any other image (the rendered canvas is but an image), the image could become pixelated/distorted.
Getting the canvas context and final setup
We need to do one last affair before we tin consider our canvas template finished. To draw onto the canvas we demand to get a special reference to the cartoon surface area called a context. This is done using the HTMLCanvasElement.getContext()
method, which for basic usage takes a unmarried string as a parameter representing the type of context you desire to retrieve.
In this case we desire a 2d canvass, and then add the post-obit JavaScript line below the others within the <script>
chemical element:
const ctx = sail. getContext ( '2d' ) ;
Notation: other context values you lot could choose include webgl
for WebGL, webgl2
for WebGL two, etc., but we won't demand those in this article.
Then that's it — our canvas is at present primed and fix for drawing on! The ctx
variable now contains a CanvasRenderingContext2D
object, and all drawing operations on the sheet will involve manipulating this object.
Let's do ane concluding thing earlier nosotros motion on. Nosotros'll colour the sail groundwork black to requite you a offset taste of the canvass API. Add the following lines at the lesser of your JavaScript:
ctx.fillStyle = 'rgb(0, 0, 0)' ; ctx. fillRect ( 0 , 0 , width, height) ;
Here nosotros are setting a fill color using the canvas' fillStyle
property (this takes color values just like CSS properties exercise), and so drawing a rectangle that covers the entire area of the canvas with thefillRect
method (the showtime two parameters are the coordinates of the rectangle's elevation left paw corner; the last ii are the width and superlative you lot want the rectangle drawn at — we told you those width
and height
variables would be useful)!
OK, our template is done and information technology's fourth dimension to move on.
2D canvass basics
Every bit we said above, all cartoon operations are done by manipulating a CanvasRenderingContext2D
object (in our example, ctx
). Many operations need to exist given coordinates to pinpoint exactly where to draw something — the peak left of the sheet is point (0, 0), the horizontal (x) centrality runs from left to right, and the vertical (y) centrality runs from meridian to bottom.
Cartoon shapes tends to be done using the rectangle shape primitive, or past tracing a line along a certain path and so filling in the shape. Below nosotros'll show how to do both.
Simple rectangles
Let's get-go with some simple rectangles.
- First of all, have a copy of your newly coded canvas template (or make a local re-create of 1_canvas_template.html if y'all didn't follow the higher up steps).
- Adjacent, add together the following lines to the lesser of your JavaScript:
ctx.fillStyle = 'rgb(255, 0, 0)' ; ctx. fillRect ( l , 50 , 100 , 150 ) ;
- Let's add another rectangle into the mix — a green one this time. Add the post-obit at the bottom of your JavaScript:
ctx.fillStyle = 'rgb(0, 255, 0)' ; ctx. fillRect ( 75 , 75 , 100 , 100 ) ;
- Note that yous can depict semi-transparent graphics by specifying a semi-transparent colour, for example by using
rgba()
. Thea
value defines what'south called the "alpha channel, " or the amount of transparency the color has. The higher its value, the more than it will obscure whatsoever'south behind it. Add the post-obit to your code:ctx.fillStyle = 'rgba(255, 0, 255, 0.75)' ; ctx. fillRect ( 25 , 100 , 175 , l ) ;
- Now try cartoon some more rectangles of your ain; have fun!
Strokes and line widths
So far we've looked at cartoon filled rectangles, just you can also draw rectangles that are just outlines (chosen strokes in graphic design). To ready the color y'all desire for your stroke, yous employ the strokeStyle
property; drawing a stroke rectangle is done using strokeRect
.
- Add together the following to the previous case, again below the previous JavaScript lines:
ctx.strokeStyle = 'rgb(255, 255, 255)' ; ctx. strokeRect ( 25 , 25 , 175 , 200 ) ;
- The default width of strokes is 1 pixel; y'all can conform the
lineWidth
property value to change this (it takes a number representing the number of pixels broad the stroke is). Add the following line in between the previous two lines:
Now you should see that your white outline has become much thicker! That'south it for now. At this indicate your example should look like this:
Drawing paths
If y'all want to draw anything more complex than a rectangle, you need to draw a path. Basically, this involves writing code to specify exactly what path the pen should movement along on your canvas to trace the shape you want to depict. Canvass includes functions for drawing directly lines, circles, Bézier curves, and more.
Allow's get-go the section off by making a fresh copy of our sail template (1_canvas_template.html), in which to draw the new example.
We'll be using some common methods and properties across all of the beneath sections:
-
beginPath()
— start drawing a path at the indicate where the pen currently is on the canvas. On a new canvas, the pen starts out at (0, 0). -
moveTo()
— move the pen to a different point on the canvas, without recording or tracing the line; the pen "jumps" to the new position. -
fill()
— depict a filled shape by filling in the path you lot've traced and then far. -
stroke()
— draw an outline shape by drawing a stroke along the path you lot've drawn so far. - You can also use features like
lineWidth
andfillStyle
/strokeStyle
with paths as well as rectangles.
A typical, elementary path-cartoon operation would look something like so:
ctx.fillStyle = 'rgb(255, 0, 0)' ; ctx. beginPath ( ) ; ctx. moveTo ( 50 , 50 ) ; // draw your path ctx. fill ( ) ;
Drawing lines
Let'due south depict an equilateral triangle on the canvas.
- First of all, add the following helper function to the bottom of your lawmaking. This converts caste values to radians, which is useful because whenever you need to provide an angle value in JavaScript, information technology will almost e'er be in radians, simply humans usually think in degrees.
role degToRad ( degrees ) { render degrees * Math. PI / 180 ; } ;
- Next, start off your path by adding the following below your previous addition; here we set a color for our triangle, start drawing a path, and then move the pen to (50, 50) without cartoon annihilation. That'due south where nosotros'll first drawing our triangle.
ctx.fillStyle = 'rgb(255, 0, 0)' ; ctx. beginPath ( ) ; ctx. moveTo ( 50 , 50 ) ;
- Now add the following lines at the lesser of your script:
ctx. lineTo ( 150 , 50 ) ; let triHeight = 50 * Math. tan ( degToRad ( 60 ) ) ; ctx. lineTo ( 100 , 50 +triHeight) ; ctx. lineTo ( 50 , 50 ) ; ctx. fill ( ) ;
- The longest side is called the hypotenuse
- The side next to the 60 caste angle is called the next — which we know is 50 pixels, as it is one-half of the line we just drew.
- The side opposite the 60 degree bending is called the contrary, which is the height of the triangle nosotros want to summate.
I of the basic trigonometric formulae states that the length of the next multiplied by the tangent of the angle is equal to the opposite, hence we come up with
50 * Math.tan(degToRad(60))
. We use ourdegToRad()
function to convert threescore degrees to radians, equallyMath.tan()
expects an input value in radians. - With the tiptop calculated, nosotros draw another line to
(100, fifty + triHeight)
. The X coordinate is simple; information technology must be halfway betwixt the previous two X values we set. The Y value on the other hand must exist 50 plus the triangle height, every bit nosotros know the peak of the triangle is l pixels from the elevation of the sail. - The next line draws a line back to the starting point of the triangle.
- Terminal of all, we run
ctx.fill()
to end the path and fill in the shape.
Cartoon circles
Now let's await at how to draw a circumvolve in canvas. This is accomplished using the arc()
method, which draws all or part of a circumvolve at a specified signal.
- Allow'due south add together an arc to our canvas — add the post-obit to the lesser of your lawmaking:
ctx.fillStyle = 'rgb(0, 0, 255)' ; ctx. beginPath ( ) ; ctx. arc ( 150 , 106 , 50 , degToRad ( 0 ) , degToRad ( 360 ) , fake ) ; ctx. fill up ( ) ;
arc()
takes 6 parameters. The first two specify the position of the arc'due south center (X and Y, respectively). The third is the circle'south radius, the fourth and 5th are the start and finish angles at which to draw the circumvolve (so specifying 0 and 360 degrees gives us a full circle), and the sixth parameter defines whether the circle should be drawn counterclockwise (anticlockwise) or clockwise (false
is clockwise).Annotation: 0 degrees is horizontally to the right.
- Let's effort adding some other arc:
ctx.fillStyle = 'xanthous' ; ctx. beginPath ( ) ; ctx. arc ( 200 , 106 , l , degToRad ( - 45 ) , degToRad ( 45 ) , true ) ; ctx. lineTo ( 200 , 106 ) ; ctx. fill ( ) ;
- We have set the last parameter of
arc()
totruthful
, meaning that the arc is drawn counterclockwise, which means that even though the arc is specified as starting at -45 degrees and catastrophe at 45 degrees, we describe the arc around the 270 degrees non within this portion. If you were to altertrue
tosimulated
and so re-run the code, but the 90 degree slice of the circle would be drawn. - Before calling
fill()
, nosotros draw a line to the center of the circle. This means that nosotros get the rather nice Pac-Man-style cutout rendered. If you removed this line (endeavour information technology!) then re-ran the lawmaking, you lot'd get but an edge of the circumvolve chopped off between the start and end bespeak of the arc. This illustrates some other important point of the sheet — if yous endeavour to fill an incomplete path (i.due east. ane that is non closed), the browser fills in a direct line betwixt the start and end indicate and and so fills information technology in.
- We have set the last parameter of
That's it for now; your concluding example should await like this:
Notation: To find out more than about advanced path cartoon features such as Bézier curves, cheque out our Drawing shapes with canvas tutorial.
Text
Canvas as well has features for drawing text. Let's explore these briefly. Get-go by making another fresh copy of our canvas template (1_canvas_template.html) in which to draw the new example.
Text is drawn using 2 methods:
-
fillText()
— draws filled text. -
strokeText()
— draws outline (stroke) text.
Both of these accept three properties in their basic usage: the text string to draw and the X and Y coordinates of the point to commencement drawing the text at. This works out every bit the bottom left corner of the text box (literally, the box surrounding the text you lot depict), which might confuse yous as other drawing operations tend to start from the top left corner — behave this in mind.
There are also a number of backdrop to assistance control text rendering such as font
, which lets you lot specify font family unit, size, etc. It takes equally its value the same syntax every bit the CSS font
belongings.
Try adding the following block to the lesser of your JavaScript:
ctx.strokeStyle = 'white' ; ctx.lineWidth = one ; ctx.font = '36px arial' ; ctx. strokeText ( 'Canvas text' , 50 , 50 ) ; ctx.fillStyle = 'red' ; ctx.font = '48px georgia' ; ctx. fillText ( 'Canvas text' , l , 150 ) ;
Here we draw ii lines of text, 1 outline and the other stroke. The concluding example should expect similar so:
Have a play and come across what you can come up up with! You can discover more information on the options available for canvas text at Drawing text.
Drawing images onto sheet
It is possible to render external images onto your sail. These tin exist simple images, frames from videos, or the content of other canvases. For the moment nosotros'll simply look at the instance of using some elementary images on our sail.
- Equally before, brand another fresh copy of our sheet template (1_canvas_template.html) in which to draw the new case. In this case y'all'll also need to salvage a re-create of our sample epitome — firefox.png — in the same directory. Images are fatigued onto canvass using the
drawImage()
method. The simplest version takes 3 parameters — a reference to the paradigm you desire to render, and the X and Y coordinates of the image'southward top left corner. - Let'south start by getting an image source to embed in our canvas. Add the following lines to the bottom of your JavaScript:
let image = new Epitome ( ) ; image.src = 'firefox.png' ;
HTMLImageElement
object using theImage()
constructor. The returned object is the same type as that which is returned when you catch a reference to an existing<img>
element). We and so set itssrc
aspect to equal our Firefox logo image. At this point, the browser starts loading the image. - We could now try to embed the image using
drawImage()
, simply we need to make certain the image file has been loaded beginning, otherwise the code volition fail. We can achieve this using theonload
issue handler, which will just exist invoked when the image has finished loading. Add the post-obit block below the previous ane:image. onload = office ( ) { ctx. drawImage (image, 50 , 50 ) ; }
- Merely at that place's more! What if we want to display only a role of the image, or to resize information technology? We tin can do both with the more circuitous version of
drawImage()
. Update yourctx.drawImage()
line like so:ctx. drawImage (image, 20 , 20 , 185 , 175 , 50 , 50 , 185 , 175 ) ;
- The first parameter is the paradigm reference, as before.
- Parameters ii and iii define the coordinates of the top left corner of the area you want to cut out of the loaded image, relative to the top-left corner of the image itself. Nothing to the left of the first parameter or above the second will be drawn.
- Parameters four and five define the width and height of the surface area we want to cutting out from the original image we loaded.
- Parameters vi and seven define the coordinates at which you want to draw the meridian-left corner of the cut-out portion of the image, relative to the height-left corner of the sail.
- Parameters viii and 9 ascertain the width and height to depict the cut-out area of the prototype. In this case, we have specified the same dimensions as the original slice, merely you could resize it by specifying dissimilar values.
The concluding example should look like so:
Loops and animations
We have so far covered some very basic uses of 2D canvas, but really you won't feel the full power of canvas unless you update or breathing it in some way. Later on all, sail does provide scriptable images! If you aren't going to change annihilation, then you might equally well just apply static images and save yourself all the work.
Creating a loop
Playing with loops in canvas is rather fun — y'all can run canvas commands within a for
(or other type of) loop just similar any other JavaScript code.
Let's build a unproblematic example.
- Brand another fresh copy of our canvas template (1_canvas_template.html) and open information technology in your lawmaking editor.
- Add the following line to the bottom of your JavaScript. This contains a new method,
translate()
, which moves the origin point of the canvas:ctx. interpret (width/ 2 , elevation/ ii ) ;
- Now add the following lawmaking to the lesser of the JavaScript:
function degToRad ( degrees ) { return degrees * Math. PI / 180 ; } ; function rand ( min, max ) { return Math. flooring (Math. random ( ) * (max-min+ 1 ) ) + (min) ; } let length = 250 ; let moveOffset = twenty ; for ( var i = 0 ; i < length; i++ ) { }
degToRad()
role we saw in the triangle case above, arand()
part that returns a random number betwixt given lower and upper bounds,length
andmoveOffset
variables (which we'll find out more about afterward), and an emptyfor
loop. - The idea here is that we'll draw something on the canvas within the
for
loop, and iterate on information technology each time and so we tin can create something interesting. Add together the following code inside yourfor
loop:ctx.fillStyle = 'rgba(' + ( 255 -length) + ', 0, ' + ( 255 -length) + ', 0.nine)' ; ctx. beginPath ( ) ; ctx. moveTo (moveOffset, moveOffset) ; ctx. lineTo (moveOffset+length, moveOffset) ; let triHeight = length/ ii * Math. tan ( degToRad ( 60 ) ) ; ctx. lineTo (moveOffset+ (length/ 2 ) , moveOffset+triHeight) ; ctx. lineTo (moveOffset, moveOffset) ; ctx. fill up ( ) ; length-- ; moveOffset += 0.7 ; ctx. rotate ( degToRad ( 5 ) ) ;
- Set the
fillStyle
to be a shade of slightly transparent purple, which changes each time based on the value oflength
. As yous'll run into later the length gets smaller each time the loop runs, so the effect hither is that the color gets brighter with each successive triangle drawn. - Begin the path.
- Move the pen to a coordinate of
(moveOffset, moveOffset)
; This variable defines how far we want to move each time we draw a new triangle. - Describe a line to a coordinate of
(moveOffset+length, moveOffset)
. This draws a line of lengthlength
parallel to the X centrality. - Calculate the triangle's top, as before.
- Draw a line to the down-pointing corner of the triangle, then describe a line dorsum to the start of the triangle.
- Call
fill()
to fill in the triangle. - Update the variables that describe the sequence of triangles, so we can be ready to draw the next one. Nosotros subtract the
length
value by 1, so the triangles go smaller each fourth dimension; increasemoveOffset
past a small amount and then each successive triangle is slightly farther away, and use some other new function,rotate()
, which allows the states to rotate the entire sail! We rotate information technology by 5 degrees earlier drawing the next triangle.
- Set the
That's it! The concluding example should look like so:
At this signal, we'd similar to encourage you lot to play with the example and brand information technology your own! For example:
- Draw rectangles or arcs instead of triangles, or fifty-fifty embed images.
- Play with the
length
andmoveOffset
values. - Innovate some random numbers using that
rand()
role nosotros included in a higher place merely didn't use.
Animations
The loop instance we built higher up was fun, but really you need a constant loop that keeps going and going for any serious canvass applications (such as games and real time visualizations). If you lot think of your sheet as beingness like a picture show, you really want the display to update on each frame to show the updated view, with an ideal refresh charge per unit of sixty frames per 2nd so that movement appears nice and smooth to the human eye.
There are a few JavaScript functions that will permit yous to run functions repeatedly, several times a second, the all-time 1 for our purposes hither being window.requestAnimationFrame()
. It takes one parameter — the proper name of the function you want to run for each frame. The next fourth dimension the browser is gear up to update the screen, your function will get called. If that part draws the new update to your animation, then calls requestAnimationFrame()
again just before the end of the function, the animation loop will keep to run. The loop ends when yous stop calling requestAnimationFrame()
or if you call window.cancelAnimationFrame()
subsequently calling requestAnimationFrame()
but before the frame is called.
Annotation: It's adept practice to call cancelAnimationFrame()
from your principal code when y'all're done using the animation, to ensure that no updates are notwithstanding waiting to exist run.
The browser works out complex details such as making the animation run at a consistent speed, and non wasting resources animating things that can't be seen.
To see how it works, let's rapidly look again at our Bouncing Balls instance (see it live, and also see the source code). The code for the loop that keeps everything moving looks similar this:
function loop ( ) { ctx.fillStyle = 'rgba(0, 0, 0, 0.25)' ; ctx. fillRect ( 0 , 0 , width, pinnacle) ; for ( permit i = 0 ; i < balls.length; i++ ) { assurance[i] . describe ( ) ; assurance[i] . update ( ) ; balls[i] . collisionDetect ( ) ; } requestAnimationFrame (loop) ; } loop ( ) ;
We run the loop()
part one time at the bottom of the lawmaking to start the bike, drawing the outset animation frame; the loop()
function then takes charge of calling requestAnimationFrame(loop)
to run the next frame of the animation, again and once more.
Notation that on each frame we are completely clearing the canvas and redrawing everything. For every ball nowadays we draw information technology, update its position, and cheque to see if it is colliding with whatever other assurance. In one case y'all've drawn a graphic to a canvas, there'south no way to manipulate that graphic individually like you can with DOM elements. You can't motility each ball effectually on the canvas, considering once information technology'south drawn, it'south part of the sail, and is not an individual accessible element or object. Instead, you have to erase and redraw, either by erasing the entire frame and redrawing everything, or by having lawmaking that knows exactly what parts demand to be erased and but erases and redraws the minimum area of the canvas necessary.
Optimizing animation of graphics is an entire specialty of programming, with lots of clever techniques bachelor. Those are beyond what nosotros need for our case, though!
In general, the procedure of doing a sail animation involves the post-obit steps:
- Clear the canvas contents (due east.g. with
fillRect()
orclearRect()
). - Save land (if necessary) using
salve()
— this is needed when you want to salvage settings you've updated on the canvas before standing, which is useful for more than avant-garde applications. - Draw the graphics you are animating.
- Restore the settings you saved in step 2, using
restore()
- Call
requestAnimationFrame()
to schedule drawing of the next frame of the animation.
Notation: We won't cover save()
and restore()
hither, merely they are explained nicely in our Transformations tutorial (and the ones that follow information technology).
A simple graphic symbol animation
Now let's create our ain unproblematic animation — we'll get a character from a certain rather awesome retro computer game to walk across the screen.
- Brand another fresh copy of our canvas template (1_canvas_template.html) and open up it in your code editor. Make a copy of walk-right.png in the same directory.
- At the bottom of the JavaScript, add the post-obit line to once over again brand the coordinate origin sit in the middle of the canvas:
ctx. translate (width/ 2 , pinnacle/ ii ) ;
- Now allow's create a new
HTMLImageElement
object, set itssrc
to the image we desire to load, and add anonload
issue handler that will cause thedepict()
function to fire when the image is loaded:let paradigm = new Epitome ( ) ; image.src = 'walk-right.png' ; image.onload = describe;
- Now we'll add together some variables to keep track of the position the sprite is to be fatigued on the screen, and the sprite number we want to brandish.
let sprite = 0 ; let posX = 0 ;
It contains six sprites that make up the whole walking sequence — each ane is 102 pixels wide and 148 pixels high. To display each sprite cleanly nosotros volition have to use
drawImage()
to chop out a unmarried sprite epitome from the spritesheet and display just that part, like we did above with the Firefox logo. The X coordinate of the slice will have to be a multiple of 102, and the Y coordinate will e'er exist 0. The slice size volition e'er be 102 by 148 pixels. - Now let's insert an empty
draw()
role at the bottom of the code, ready for filling upward with some code: - The rest of the code in this section goes inside
depict()
. Showtime, add the post-obit line, which clears the canvas to gear up for drawing each frame. Find that we have to specify the top-left corner of the rectangle as-(width/2), -(height/ii)
because we specified the origin position equallywidth/2, height/ii
earlier on.ctx. fillRect ( - (width/ 2 ) , - (height/ two ) , width, acme) ;
- Next, nosotros'll describe our image using drawImage — the ix-parameter version. Add the following:
ctx. drawImage (image, (sprite* 102 ) , 0 , 102 , 148 , 0 +posX, - 74 , 102 , 148 ) ;
- We specify
paradigm
equally the paradigm to embed. - Parameters 2 and 3 specify the summit-left corner of the slice to cut out of the source image, with the 10 value every bit
sprite
multiplied past 102 (wheresprite
is the sprite number between 0 and v) and the Y value always 0. - Parameters 4 and 5 specify the size of the piece to cut out — 102 pixels by 148 pixels.
- Parameters half-dozen and seven specify the top-left corner of the box into which to draw the slice on the canvas — the 10 position is 0 +
posX
, meaning that nosotros tin can change the drawing position by altering theposX
value. - Parameters 8 and nine specify the size of the image on the canvas. We just want to proceed its original size, so we specify 102 and 148 as the width and elevation.
- We specify
- Now we'll change the
sprite
value later on each draw — well, later on some of them anyway. Add the post-obit block to the bottom of thedraw()
function:if (posX % 13 === 0 ) { if (sprite === 5 ) { sprite = 0 ; } else { sprite++ ; } }
if (posX % 13 === 0) { ... }
. We utilize the modulo (%
) operator (also known as the balance operator) to check whether theposX
value can exist exactly divided by 13 with no balance. If so, we move on to the side by side sprite past incrementingsprite
(wrapping to 0 later on we're done with sprite #5). This effectively ways that we are only updating the sprite on every 13th frame, or roughly almost 5 frames a 2d (requestAnimationFrame()
calls u.s.a. at upwardly to 60 frames per 2nd if possible). We are deliberately slowing down the frame rate because nosotros only accept vi sprites to work with, and if we display one every 60th of a second, our character will move style too fast! Inside the outer block we use anif ... else
statement to check whether thesprite
value is at 5 (the last sprite, given that the sprite numbers run from 0 to 5). If we are showing the terminal sprite already, we resetsprite
back to 0; if not we merely increment it past 1. - Side by side nosotros need to work out how to change the
posX
value on each frame — add the post-obit lawmaking block but below your last 1.if (posX > width/ 2 ) { newStartPos = - ( (width/ 2 ) + 102 ) ; posX = Math. ceil (newStartPos) ; console. log (posX) ; } else { posX += 2 ; }
if ... else
statement to meet if the value ofposX
has go greater thanwidth/2
, which means our character has walked off the correct edge of the screen. If so, nosotros calculate a position that would put the grapheme just to the left of the left side of the screen. If our character hasn't even so walked off the edge of the screen, we incrementposX
by 2. This volition brand him move a fiddling bit to the right the adjacent fourth dimension we draw him. - Finally, nosotros demand to brand the blitheness loop by calling
requestAnimationFrame()
at the lesser of thedraw()
function:window. requestAnimationFrame (depict) ;
That'south it! The final case should look similar so:
A unproblematic drawing application
As a last animation example, nosotros'd like to evidence you lot a very elementary drawing application, to illustrate how the animation loop can be combined with user input (similar mouse movement, in this case). Nosotros won't get y'all to walk through and build this 1; we'll only explore the near interesting parts of the lawmaking.
The example tin can be found on GitHub as 8_canvas_drawing_app.html, and you can play with it live below:
Let'due south look at the most interesting parts. Start of all, we keep track of the mouse's X and Y coordinates and whether information technology is being clicked or not with three variables: curX
, curY
, and pressed
. When the mouse moves, nosotros fire a function set equally the onmousemove
event handler, which captures the current 10 and Y values. Nosotros as well use onmousedown
and onmouseup
event handlers to change the value of pressed
to true
when the mouse push button is pressed, and back to false
once again when it is released.
let curX; allow curY; let pressed = false ; document. onmousemove = function ( e ) { curX = (window.Consequence) ? eastward.pageX : e.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft) ; curY = (window.Event) ? eastward.pageY : e.clientY + (certificate.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) ; } canvas. onmousedown = part ( ) { pressed = truthful ; } ; canvas. onmouseup = function ( ) { pressed = false ; }
When the "Articulate canvas" push button is pressed, we run a simple role that clears the whole canvas back to black, the aforementioned way nosotros've seen before:
clearBtn. onclick = role ( ) { ctx.fillStyle = 'rgb(0, 0, 0)' ; ctx. fillRect ( 0 , 0 , width, pinnacle) ; }
The cartoon loop is pretty elementary this time effectually — if pressed is true
, we draw a circle with a fill manner equal to the value in the color picker, and a radius equal to the value set in the range input. We have to depict the circle 85 pixels higher up where we measured it from, because the vertical measurement is taken from the peak of the viewport, but nosotros are cartoon the circle relative to the summit of the canvas, which starts below the 85 pixel-high toolbar. If we drew it with simply curY
as the y coordinate, it would appear 85 pixels lower than the mouse position.
function draw ( ) { if (pressed) { ctx.fillStyle = colorPicker.value; ctx. beginPath ( ) ; ctx. arc (curX, curY- 85 , sizePicker.value, degToRad ( 0 ) , degToRad ( 360 ) , false ) ; ctx. fill ( ) ; } requestAnimationFrame (draw) ; } draw ( ) ;
Note: The <input>
range
and color
types are supported fairly well across browsers, with the exception of Net Explorer versions less than ten; as well Safari doesn't nevertheless support color
. If your browser doesn't support these inputs, they volition autumn back to simple text fields and you'll just have to enter valid color/number values yourself.
WebGL
It'southward now time to go out 2D backside, and take a quick await at 3D canvas. 3D canvas content is specified using the WebGL API, which is a completely separate API from the 2D canvas API, even though they both render onto <canvas>
elements.
WebGL is based on OpenGL (Open Graphics Library), and allows you to communicate straight with the reckoner's GPU. As such, writing raw WebGL is closer to low level languages such equally C++ than regular JavaScript; it is quite complex but incredibly powerful.
Using a library
Because of its complication, most people write 3D graphics code using a tertiary party JavaScript library such as Iii.js, PlayCanvas, or Babylon.js. Most of these work in a like mode, providing functionality to create archaic and custom shapes, position viewing cameras and lighting, covering surfaces with textures, and more than. They handle the WebGL for you, letting you piece of work on a higher level.
Yes, using one of these means learning some other new API (a 3rd political party one, in this case), only they are a lot simpler than coding raw WebGL.
Recreating our cube
Let's wait at a simple instance of how to create something with a WebGL library. Nosotros'll choose Iii.js, equally it is 1 of the nigh pop ones. In this tutorial nosotros'll create the 3D spinning cube nosotros saw before.
- To outset with, make a local copy of alphabetize.html in a new folder, so relieve a copy of metal003.png in the aforementioned binder. This is the paradigm we'll utilise as a surface texture for the cube afterward.
- Next, create a new file called
main.js
, again in the aforementioned folder as before. - If you open up
index.html
in your code editor, yous'll encounter that it has two<script>
elements — the starting time one attachingthree.min.js
to the page, and the second ane attaching ourmain.js
file to the page. You lot need to download the three.min.js library and save it in the same directory every bit earlier. - Now we've got
three.js
attached to our page, we tin start to write JavaScript that makes use of it intomain.js
. Let's start past creating a new scene — add the following into your chief.js file:const scene = new 3.Scene ( ) ;
Scene()
constructor creates a new scene, which represents the whole 3D earth we are trying to brandish. - Next, nosotros need a camera so nosotros tin can run into the scene. In 3D imagery terms, the camera represents a viewer'southward position in the globe. To create a camera, add the following lines next:
const camera = new Three.PerspectiveCamera ( 75 , window.innerWidth / window.innerHeight, 0.1 , 1000 ) ; photographic camera.position.z = 5 ;
PerspectiveCamera()
constructor takes four arguments:- The field of view: How wide the area in forepart of the camera is that should be visible onscreen, in degrees.
- The aspect ratio: Usually, this is the ratio of the scene's width divided by the scene'southward tiptop. Using another value will distort the scene (which might exist what y'all want, only unremarkably isn't).
- The near airplane: How shut to the camera objects can exist before we stop rendering them to the screen. Think nigh how when you move your fingertip closer and closer to the space between your optics, eventually you can't encounter it anymore.
- The far airplane: How far away things are from the camera before they are no longer rendered.
- The third vital ingredient is a renderer. This is an object that renders a given scene, as viewed through a given photographic camera. We'll create one for at present using the
WebGLRenderer()
constructor, but we'll non use it till later. Add the post-obit lines next:const renderer = new 3.WebGLRenderer ( ) ; renderer. setSize (window.innerWidth, window.innerHeight) ; document.body. appendChild (renderer.domElement) ;
<canvas>
element created by the renderer to the document'southward<body>
. Now annihilation the renderer draws will be displayed in our window. - Next, we want to create the cube we'll display on the sail. Add together the following clamper of code at the bottom of your JavaScript:
let cube; let loader = new THREE.TextureLoader ( ) ; loader. load ( 'metal003.png' , function ( texture ) { texture.wrapS = THREE .RepeatWrapping; texture.wrapT = THREE .RepeatWrapping; texture.repeat. gear up ( 2 , 2 ) ; permit geometry = new Iii.BoxGeometry ( 2.4 , 2.4 , 2.4 ) ; let material = new THREE.MeshLambertMaterial ( { map : texture, shading : THREE .FlatShading } ) ; cube = new THREE.Mesh (geometry, material) ; scene. add (cube) ; draw ( ) ; } ) ;
- We first create a
cube
global variable and then we tin can access our cube from anywhere in the code. - Next, we create a new
TextureLoader
object, then phone callload()
on information technology.load()
takes two parameters in this case (although it tin accept more): the texture we desire to load (our PNG), and a function that volition run when the texture has loaded. - Within this role nosotros use backdrop of the
texture
object to specify that nosotros want a 2 x 2 repeat of the image wrapped around all sides of the cube. Next, we create a newBoxGeometry
object and a newMeshLambertMaterial
object, and bring them together in aMesh
to create our cube. An object typically requires a geometry (what shape it is) and a material (what its surface looks like). - Last of all, we add our cube to the scene, then call our
draw()
function to start off the animation.
- We first create a
- Before we get to defining
describe()
, we'll add a couple of lights to the scene, to liven things up a bit; add the following blocks next:permit light = new THREE.AmbientLight ( 'rgb(255, 255, 255)' ) ; // soft white calorie-free scene. add (light) ; allow spotLight = new THREE.SpotLight ( 'rgb(255, 255, 255)' ) ; spotLight.position. set ( 100 , thousand , grand ) ; spotLight.castShadow = truthful ; scene. add together (spotLight) ;
AmbientLight
object is a kind of soft light that lightens the whole scene a bit, like the sun when you are outside. TheSpotLight
object, on the other paw, is a directional beam of calorie-free, more like a flashlight/torch (or a spotlight, in fact). - Last of all, let'south add together our
draw()
role to the bottom of the code:function draw ( ) { cube.rotation.10 += 0.01 ; cube.rotation.y += 0.01 ; renderer. render (scene, camera) ; requestAnimationFrame (draw) ; }
requestAnimationFrame()
to schedule drawing our adjacent frame.
Let's have some other quick expect at what the finished product should look like:
You tin notice the finished lawmaking on GitHub.
Notation: In our GitHub repo you can also find another interesting 3D cube example — Three.js Video Cube (see it alive too). This uses getUserMedia()
to take a video stream from a calculator web cam and project it onto the side of the cube as a texture!
Summary
At this point, yous should have a useful idea of the basics of graphics programming using Sheet and WebGL and what you can do with these APIs, as well every bit a expert idea of where to go for further data. Have fun!
Run across likewise
Here nosotros have covered only the existent basics of canvas — there is then much more than to acquire! The below articles will take you lot further.
- Canvas tutorial — A very detailed tutorial series explaining what y'all should know most 2nd sail in much more particular than was covered hither. Essential reading.
- WebGL tutorial — A serial that teaches the basics of raw WebGL programming.
- Building up a bones demo with Three.js — bones 3.js tutorial. We also have equivalent guides for PlayCanvas or Babylon.js.
- Game development — the landing page for spider web games evolution on MDN. There are some actually useful tutorials and techniques available here related to second and 3D canvas — meet the Techniques and Tutorials carte options.
Examples
In this module
- Introduction to web APIs
- Manipulating documents
- Fetching data from the server
- Tertiary party APIs
- Cartoon graphics
- Video and audio APIs
- Client-side storage
Source: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics
Post a Comment for "draw 3d points from console firefox"