📜 ⬆️ ⬇️

LibCanvas basics - practice



This is a continuation of the article about the basics of LibCanvas If the first part touched on theoretical ambushes, then in this part we will move on to practice and try to implement very basic and simple things. The purpose of the article is to master the very basics of LibCanvas, we will write very simple scripts that are of little use in real life, but you can develop them into something great.


')

HTML


The structure of the html file is very simple:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script src="atom.js"></script> <script src="libcanvas.js"></script> <script src="application.js"></script> </head> <body> <canvas></canvas> </body> </html> 


You need to connect the latest AtomJS and LibCanvas . Beginners should use the *-full-compiled versions from the repository.

Next we will look at the contents of application.js

Simple drawing to canvas


We can still draw to the canvas using the context. You need to wait until the DOM is fully loaded, get the canvas element, its context, and draw two shapes. I immediately globalized all the contents of LibCanvas. Later on, when I show examples, only the content of the onready function will be implied.

Now we just draw a green rectangle and a red circle on a light coffee canvas:
 LibCanvas.extract(); atom.dom(function() { var canvas = atom.dom('canvas').first; var context = canvas.getContext('2d-libcanvas'); context .fillAll( '#efebe7' ) .fill( new Rectangle( 75, 75, 30, 30 ), 'green' ) .fill( new Circle ( 50, 50, 20 ) , '#c00' ); }); 



Animation


But this approach allows you to draw only some static images. For something interactive, you need to create a LibCanvas object. Let's make a very simple application - the black canvas is filled with random green rectangles.
Pay attention to two important points:
1. By default, the canvas is cleared every frame, so you must turn off this default behavior with { clear: null }
2. The function passed to start belongs to the render phase, so it will not be called without updating the canvas, which we achieved thanks to .addFunc( libcanvas.update ) . In fact, this is a bad decision, but in this case it is suitable.

 var libcanvas = new LibCanvas('canvas', { clear: null }); libcanvas.ctx.fillAll('black'); libcanvas .start(function () { this.ctx.fill( new Rectangle({ from: this.ctx.rectangle.getRandomPoint(), size: [ 2, 2 ] }), 'green' ); }) .addFunc( libcanvas.update ); 



Objects


Now add an object. Let it be a piece of black color that will rotate around one of its points. This time we need to clear the canvas before rendering the next frame, so we will not cancel clear. We look at the code and read the comments:

 var Item = atom.Class({ Implements: [ Drawable ], //       - // Point -          initialize: function (center, speed) { this.line = new Line( center, //          //         center.clone().move([ 20, 0 ]) ); //    ,      //       "/" this.speed = speed / 1000; }, update: function (time) { //        this.line.to.rotate( //  ,       fps  //     .  fps ,  //   ,       this.speed * time, this.line.from ); //   libcanvas,   //         this.libcanvas.update(); }, draw: function () { //    this.libcanvas.ctx .stroke( this.line, 'black' ); } }); var libcanvas = new LibCanvas('canvas'); //     //     .        //       . //         var item = new Item( new Point(50, 50), (180).degree() ); libcanvas.addElement( item ) //     "" LibCanvas,     "start" .start() //  ,      "item.update",     //   ,      bind  : .addFunc( item.update.bind(item) ); 


We got a spinning arrow .

Mouse response


Let's take our arrow in the red circle, which can be dragged. It's quite simple, I will show what has changed, as you see, just a few lines. Notice that I created the shape property, not the circle . This is necessary for Draggable.

 var Item = atom.Class({ Implements: [ Drawable, Draggable /*  */ ], [...] initialize: function (center, speed) { [...] //   this.shape = new Circle( center, 25 ); }, [...] draw: function () { [...] .stroke( this.shape, '#c00' ); } }); [...] libcanvas.listenMouse(); item.draggable() 


We see that almost everything worked , but there is a mistake when we pull the circle - the arrow changes its length. The secret is that when we move a circle, the point center also moves, which is the beginning of the segment. The end of the segment remains in place and begins to turn on a new path. It must be shifted with the beginning. This is very easy to do by subscribing to the move event at a point:

 initialize: function (center, speed) { [...] // ,        center.addEvent('move', function (diff) { this.line.to.move(diff); }.bind(this)) }, 


Now correct

Stopwatch


Now add another arrow and implement a stopwatch in this way - the time that has passed since entering the page. The code will change a little bit, but basically it will be very similar to the previous one, therefore I will comment on only the important sections and give only the class code:

 var StopWatch = atom.Class({ Implements: [ Drawable, Draggable ], initialize: function (center) { this.center = center; this.millisec = this.line(); this.seconds = this.line(); this.minutes = this.line(); this.shape = new Circle( center, 25 ); center.addEvent('move', function (diff) { //    "move"   "diff"    [this.millisec.to, this.seconds.to, this.minutes.to].invoke('move', diff); }.bind(this)); }, //      line: function () { return new Line( this.center, this.center.clone().move([0, -20]) ); }, update: function (time) { var full = (360).degree(); //  toSeconds, toMinutes  toHours   LibCanvas.Utils.Math //         this.millisec.to.rotate( full * time.toSeconds(), this.center ); //  -   this.seconds .to.rotate( full * time.toMinutes(), this.center ); //  -   this.minutes .to.rotate( full * time.toHours() , this.center ); this.libcanvas.update(); }, draw: function () { this.libcanvas.ctx .stroke( this.shape , '#c00' ) .stroke( this.millisec, '#999' ) .stroke( this.seconds , '#000' ) .stroke( this.minutes , '#090' ); } }); 


Here, it turned out!

Conclusion


Yes, the threshold of entry is high. But in return, you get a highly optimized application, extensibility, good architecture and powerful tools. I hope the article shed light on LibCanvas.

If you still have questions - feel free to write in the comments, on email shocksilien@gmail.com or in jabber shock@jabber.com.ua

Source: https://habr.com/ru/post/121047/


All Articles