Interactive Physics Animations Javascript Canvas 14

Here is an update to allow the end user to create more dots. A good way to do that is to just let users click on the canvas, and if they click a dot, drag it, if they don’t click a dot, create a new dot at the point of click. I moved the dot creation into it’s own function and we can use that as our constructor for every dot. It has settings we can send in, but the defaults are set to pick random values. This could also be used to create a particle emitter of sorts, but for now it’s just creating a dot on clicking the blank canvas. interactive physics animations via javascript & canvas | 14.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
$(function () {
    var canvas, context, width, height, x, y, radius = 25, clickX, clickY, drag = false;
    var total_dots = 10;
    var fps = 24;
   
    canvas = $("#canvas")[0];
    context = canvas.getContext("2d");
    var dots = new Array();
    var drag_i = -1;
    var gravity = 2;
    var friction = .98;
    var bounce = -.96;
   
    var this_dot = {};
    for (var i=0; i < total_dots; i++){
        createDot();
    }
    function createDot(x, y, r, vx, vy){
        var this_dot = {
            x:      typeof(x) != 'undefined' ? x : Math.random()*canvas.width,
            y:      typeof(y) != 'undefined' ? y : Math.random()*canvas.height,
            radius: typeof(r) != 'undefined' ? r : Math.random()*20+10,
            vx:     typeof(vx) != 'undefined' ? vx : Math.random()*30-10,
            vy:     typeof(vy) != 'undefined' ? vy : Math.random()*30-10
        };
        dots.push(this_dot);
    }
   
    draw();
   
    $("#canvas").mousedown(function (event) {
        var dx, dy, dist;
        for (var i=0; i < dots.length; i++){
            dx = event.pageX - this.offsetLeft - dots[i].x;
            dy = event.pageY - this.offsetTop - dots[i].y;
            dist = Math.sqrt(dx * dx + dy * dy);
            if(dist < radius) {
                drag = true;
                drag_i = i
                clickX = dx;
                clickY = dy;
                continue;
            }
        }
        //none clicked
        if (!drag) {
            createDot(event.pageX - this.offsetLeft, event.pageY - this.offsetTop);
        }
    });
 
    $("#canvas").mouseup(function (event) {
        drag = false;
        drag_i = -1;
    });
 
    $("#canvas").mousemove(function (event) {
        if(drag) {
            dots[drag_i].x = event.pageX - this.offsetLeft - clickX;
            dots[drag_i].y = event.pageY - this.offsetTop - clickY;
            draw();
        }
    });
    function update(){
        for (var i=0; i < dots.length; i++){
            if (drag_i != i){
                var this_dot = dots[i];
                this_dot.vx *= friction;
                this_dot.vy = this_dot.vy * friction + gravity;
                this_dot.x += this_dot.vx;
                this_dot.y += this_dot.vy;
                if (this_dot.x > canvas.width - this_dot.radius){
                    this_dot.x = canvas.width - this_dot.radius;
                    this_dot.vx = this_dot.vx * bounce;
                }
                else if(this_dot.x < 0 + this_dot.radius){
                    this_dot.x = this_dot.radius;
                    this_dot.vx = this_dot.vx * bounce;
                }
                if (this_dot.y > canvas.height - this_dot.radius){
                    this_dot.y = canvas.height - this_dot.radius;
                    this_dot.vy = this_dot.vy * bounce;
                }
                else if(this_dot.y < 0 + this_dot.radius){
                    this_dot.y = this_dot.radius;
                    this_dot.vy = this_dot.vy * bounce;
                }
            }
        }
    }
    function draw() {
        context.clearRect(0, 0, canvas.width, canvas.height);
        for (var i=0; i < dots.length; i++){
            context.beginPath();
            context.arc(dots[i].x, dots[i].y, dots[i].radius, 0, Math.PI * 2, false);
            context.fill();
            context.closePath();
        }
    }
   
    setInterval(function() {
        update();
        draw();
    }, 1000/fps);  

    $("#gravity").click(function(){
        if($("#gravity").is(':checked')){
            gravity = 2;   
        }
        else{
            gravity = 0;
        }
    });
   
});

Follow the whole Interactive Physics Animations via Javascript & Canvas series.

This entry was posted in interactive javascript canvas, tutorial and tagged , , , , , , , , , , , , , , , , , , , . Bookmark the permalink. Both comments and trackbacks are currently closed.
  • Recent Posts

    promo

    What Is Code? If You Don’t Know, You Need to Read This

    Here’s a great read that may take a while but is a nice trip through programming history through the lens of one who’s been there. The world belongs to people who code. Those who don’t understand will be left behind. Source: What Is Code? If You Don’t Know, You Need to Read This Tweet

    Adactio: Journal—Instantiation

    There needs to be a cultural change in how we approach building for the web. Yes, some of the tools we choose are part of the problem, but the bigger problem is that performance still isn’t being recognised as the most important factor in how people feel about websites (and by extension, the web). This […]

    human_time_diff « WordPress Codex

    Determines the difference between two timestamps.The difference is returned in a human readable format such as “1 hour”, “5 mins”, “2 days”. Source: Function Reference/human time diff « WordPress Codex Used this little known, but nice gem today. It’s a core WordPress function that gives human relative time from any other datetime in “U” format. […]

    logo

    Cyclomatic Complexity: Logic in CSS – CSS Wizardry – CSS, OOCSS, front-end architecture, performance and more, by Harry Roberts

    I recently hit upon a way of thinking that made me realise that CSS does include logic, and the fact that it’s rarely viewed as such is probably also why we end up with such poor CSS at all.I found myself explaining compound selectors to a client as being made up of the subject—the thing […]

    Screenshot-2013-11-27-14.20.16

    Add Links to Twitter Mentions, Hashtags, and URLs with PHP

    This gem helped me out today as I was working with the Twitter API to create a custom WordPress widget. I was about to do exactly this and was not looking forward to it, luckily I did a quick search and found this webtips post. Thanks! If you’re using the Twitter v1.1 API to fetch […]

    regex101.com

    Online regex tester and debugger: JavaScript, Python, PHP, and PCRE

    Stumbled on a great regex tool today. An explanation of your regex will be automatically generated as you type. Detailed match information will be displayed here automatically. via Online regex tester and debugger: JavaScript, Python, PHP, and PCRE. Tweet

css.php