To be done in class as a group. Each student turns in result by May 2

Moodle

Learn how to use an object oriented graphic library in javascript.

We can use jsfiddle, as before, to do our coding. Here is a link to a jsfiddle that includes Konva: https://jsfiddle.net/jimskon/ahm4xc50/

Let's start with a simple draggable circle:

varstage =newKonva.Stage({ container:'container',// id of container <div>width: 500, height: 500 });// then create layervarlayer =newKonva.Layer();// create our shapevarcircle =newKonva.Circle({ x: stage.getWidth()/ 2, y: stage.getHeight() /2, radius: 70, fill:'red', stroke:'black', strokeWidth: 4, draggable:true});// add the shape to the layerlayer.add(circle); stage.add(layer);

Look here for Konva documentation: https://konvajs.github.io/docs/overview.html

Can we add a square? How? Let's add a regular polygon!

varsquare =newKonva.RegularPolygon({ x: (stage.getWidth()/ 4)*3, y: stage.getHeight() /2, sides: 4, radius: 70, fill:'blue', stroke:'black', strokeWidth: 4 }); layer.add(square);

Can we rotate the square?

square.rotate(45);

Can we animate the square by making it spin?

We can use the Konva animation object. This runs and updates the screen quickly (I get around 60 frames a second). What does this mean? It means that you run code that changes the objects on the screen by the amount desired for every frame.

We need know how much time has passed since the frame, and thus how much change to make. We can access the time since the last frame with frame.timeDiff, the time in milliseconds since the last frame. This number changes with system load. But if we make changes based on the time, the screen changes will be constant despite the variation in frame rate (this is true for all animation systems). You can allow access frame.frameRate, the current number of frames per second.

If we multiply the timeDiff/1000 times the amount to rotate per second, we get the amount to rotate for the last frame time.

Consider the following code:

square.angle = 0; square.rps = 0.05;// revolutions per second

Now lets make a function to update the square:

functionupdateSquare(frame) {// Animate the squaresquare.angle = frame.timeDiff/ 1000 * square.rps * 360; square.rotate(square.angle); } var anim = new Konva.Animation(function(frame) { updateSquare(frame); }, layer); anim.start();

Let's make the ball bounce. First let's reduce the ball size to 30.

Now we want to move the ball at a certain speed. Let's say 200 pixels per second. What we want to do is update the Y coordinate by 1/frameRate * dy, where dy is the distance to move per second (200):

vardy=200; circleRadius = 40;// animate the circlevarnewY=circle.y()+(1/ frame.frameRate) * dy; circle.setY(newY);

Of course it doesn't bounce, how do we do that? Use stage.getHeight() to get the height of the screen.

if((newY + circleRadius) > stage.getHeight() || (newY - circleRadius) < 0) { dy = dy * -1; }else{ circle.setY(newY); }

We don't update the position on a bounce. Why?

Note that we use || for or in javascript. WE use && for and! Also note that you can still drag it!

To this we need to simulate gravity and the dampening effect from each bounce. First we need to model the acceleration of gravity when falling, and the deceleration caused by gravity on rising. Consider:

ay = 9.8 m/s^{2}

This gives the amount of acceleration that occurs each second. Of course we don't move in meters per second, we move in pixels per second. What this means is the thing falling increases it speed by 9.8 m/s for each second pasts. So, in our case we start a 0 velocity. For each second that something falls, the speed increases by 9.8 m/s more. What I have found to be a good amount is to increase the speed by 20 each second. Thus we should see the following (in pixels per second), if starting from y=50 on the screen:

Time | Accel | Velocity | Position |

0s | 20 p/s^{2} |
0 p/s | 50 |

1s | 20 p/s^{2} |
20 p/s | 50 |

2s | 20 p/s^{2} |
40 p/s | 70 |

3s | 20 p/s^{2} |
60 p/s | 110 |

4s | 20 p/s^{2} |
80 p/s | 170 |

5s | 20 p/s^{2} |
100 p/s | 250 |

circle =newKonva.Circle({ x:Math.random() * (stage.getWidth() - radius) + radius, y:Math.random() * (stage.getHeight() - radius) + radius, radius: circleRadius, fill:"green", stroke:'black', strokeWidth: 4, draggable:true}); circle.dy = 0;// current speed of the ball in pixels per secondcircle.accel = 20;// acceleration in pixels/s^2circle.damp = 0.90;// velocity to retain after bouncecircle.dx =Math.random() * 100;// current x speed of the ball in pixels per second

Now let's look at some code to bounce the ball...

functionupdateCircle(frame) {// animate the circlesvarnewY = circle.y() + frame.timeDiff/ 1000 * circle.dy; // Check if we hit the floor if ((newY + circle.radius()) > stage.getHeight()) { circle.dy = circle.dy * -1; circle.dy = circle.dy * circle.damp; circle.dx = circle.dx * circle.damp; // Check if we hit the ceiling } else if (newY + circle.radius() < 0) { circle.dy = circle.dy * -1; } else { circle.setY(newY); } // compute the newx speed based on the effect of gravity circle.dy = circle.dy + circle.accel; // compute x movement var newX = circle.x() + frame.timeDiff /1000 * circle.dx;if((newX + circle.radius()) > stage.getWidth() || (newX - circle.radius()) < 0) { circle.dx = circle.dx * -1; circle.dx = circle.dx * circle.damp; }else{ circle.setX(newX); } }

- Add multiple circles?
- Compute a collision between objects?
- Make the cirles "throwable"?

I | Attachment | History | Action | Size | Date | Who | Comment |
---|---|---|---|---|---|---|---|

png | Screen_Shot_2018-11-26_at_10.09.13_AM.png | r1 | manage | 8.0 K | 2018-11-26 - 15:10 | JimSkon | |

png | Screen_Shot_2018-11-26_at_10.11.29_AM.png | r1 | manage | 9.0 K | 2018-11-26 - 15:11 | JimSkon |

Copyright © 2008-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.

Ideas, requests, problems regarding TWiki? Send feedback

Ideas, requests, problems regarding TWiki? Send feedback