summaryrefslogtreecommitdiff
path: root/src/rz_observer.js
blob: 4fe6385f0bfb00ade3e3d37801df1210d5b07b0c (plain)
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
115
116
117
118
"use strict"

/**
 * DOM object observers
 */
define(
        [],
        function() {

            var MutationObserver = window.MutationObserver;
            // more portable version: var MutationObserver =
            // window.MutationObserver ||
            // window.WebKitMutationObserver;

            /**
             * observe SVG object's translate attribute (x,y values), measure
             * change rate & invoke on_slowdown_threshold_reached() upon
             * reaching change slowdown threshold.
             *
             * Caller is responsible to disconnect observer.
             */
            function Mutation_Handler__on_dxy_slowdown(
                    on_slowdown_threshold_reached) {

                var x_cur, y_cur, d, dx, dy, avg_d = 0;

                this.on_slowdown_threshold_reached = on_slowdown_threshold_reached;

                /**
                 * handle observer mutation
                 */
                this.handle_mutation = function(m) {
                    if ('transform' != m.attributeName || null == m.oldValue) {
                        return;
                    }

                    /*
                     * parsed txt example:
                     * "translate(173.6007550157428,275.43228723527193)"
                     */
                    var rgx_m = m.oldValue.match(/\((\d+.\d+),(\d+.\d+)\)/);
                    x_cur = rgx_m[1];
                    y_cur = rgx_m[2];
                    if (undefined == this.x_prv) {
                        this.x_prv = x_cur;
                        this.y_prv = y_cur;
                        return;
                    }
                    dx = x_cur - this.x_prv;
                    dy = y_cur - this.y_prv;

                    var d = Math.sqrt(dx * dx + dy * dy);
                    // average across last samples
                    avg_d = (1.0 - this.most_recent_sample_weight) * avg_d
                            + this.most_recent_sample_weight * d;

                    // debug
                    // console.log({
                    //     'dx' : dx,
                    //     'dy' : dy,
                    //     'd' : d,
                    //     'avg_d' : avg_d,
                    // });

                    if (avg_d < this.slowdown_threshold) {
                        // slowdown threshold reached
                        if (this.on_slowdown_threshold_reached) {
                            this.on_slowdown_threshold_reached();
                        }
                    }

                    this.x_prv = x_cur;
                    this.y_prv = y_cur;
                }
            }

            function new_Mutation_Handler__on_dxy_slowdown(
                    on_slowdown_threshold_reached, slowdown_threshold,
                    most_recent_sample_weight) {
                if (undefined == slowdown_threshold) {
                    slowdown_threshold = 0.07;
                }
                if (undefined == most_recent_sample_weight) {
                    most_recent_sample_weight = 0.3;
                }

                var ret = new Mutation_Handler__on_dxy_slowdown(
                        on_slowdown_threshold_reached);
                ret.slowdown_threshold = slowdown_threshold;
                ret.most_recent_sample_weight = most_recent_sample_weight;
                return ret;
            }

            function new_MutationObserver(handler) {
                /*
                 * FIXME implemente with inheritence - currently triggers
                 * 'illegal invocation', possibly due to some interaction with
                 * requirejs
                 */
                // var o = new
                // window.MutationObserver(Mutation_Observer.handler);
                // var ret = Object.create(o);
                // ret. = undefined;
                // return ret;
                var for_each_mutaion = function(m_set) {
                    m_set.forEach(function(m) {
                        handler.handle_mutation(m);
                    })
                };

                return new MutationObserver(for_each_mutaion);
            }

            return {
                new_MutationObserver : new_MutationObserver,
                new_Mutation_Handler__on_dxy_slowdown : new_Mutation_Handler__on_dxy_slowdown,
            };
        });