SandboXP

Форк
0
/
mouse.js 
283 строки · 6.9 Кб
1
"use strict";
2

3
/**
4
 * @constructor
5
 *
6
 * @param {BusConnector} bus
7
 */
8
function MouseAdapter(bus, screen_container)
9
{
10
    /** @const */
11
    var SPEED_FACTOR = 0.15;
12

13
    var left_down = false,
14
        right_down = false,
15
        middle_down = false,
16

17
        last_x = 0,
18
        last_y = 0,
19

20
        mouse = this;
21

22
    // set by controller
23
    this.enabled = false;
24

25
    // set by emulator
26
    this.emu_enabled = true;
27

28
    this.bus = bus;
29

30
    this.bus.register("mouse-enable", function(enabled)
31
    {
32
        this.enabled = enabled;
33
    }, this);
34

35
    this.destroy = function()
36
    {
37
        if(typeof window === "undefined")
38
        {
39
            return;
40
        }
41
        window.removeEventListener("touchstart", touch_start_handler, false);
42
        window.removeEventListener("touchend", touch_end_handler, false);
43
        //window.removeEventListener("touchmove", mousemove_handler, false);
44
        //window.removeEventListener("mousemove", mousemove_handler, false);
45
        window.removeEventListener("mousedown", mousedown_handler, false);
46
        window.removeEventListener("mouseup", mouseup_handler, false);
47
        window.removeEventListener("DOMMouseScroll", mousewheel_handler, false);
48
        window.removeEventListener("mousewheel", mousewheel_handler, { passive: false });
49
    };
50

51
    this.init = function()
52
    {
53
        if(typeof window === "undefined")
54
        {
55
            return;
56
        }
57
        this.destroy();
58

59
        window.addEventListener("touchstart", touch_start_handler, false);
60
        window.addEventListener("touchend", touch_end_handler, false);
61
        //window.addEventListener("touchmove", mousemove_handler, false);
62
        //window.addEventListener("mousemove", mousemove_handler, false);
63
        window.addEventListener("mousedown", mousedown_handler, false);
64
        window.addEventListener("mouseup", mouseup_handler, false);
65
        window.addEventListener("DOMMouseScroll", mousewheel_handler, false);
66
        window.addEventListener("mousewheel", mousewheel_handler, { passive: false });
67
    };
68
    this.init();
69

70
    function is_child(child, parent)
71
    {
72
        while(child.parentNode)
73
        {
74
            if(child === parent)
75
            {
76
                return true;
77
            }
78
            child = child.parentNode;
79
        }
80

81
        return false;
82
    }
83

84
    function may_handle(e)
85
    {
86
        if(!mouse.enabled || !mouse.emu_enabled)
87
        {
88
            return false;
89
        }
90

91
        const MOVE_MOUSE_WHEN_OVER_SCREEN_ONLY = true;
92

93
        if(MOVE_MOUSE_WHEN_OVER_SCREEN_ONLY)
94
        {
95
            var parent = screen_container || document.body;
96
            return document.pointerLockElement || is_child(e.target, parent);
97
        }
98
        else
99
        {
100
            if(e.type === "mousemove" || e.type === "touchmove")
101
            {
102
                return true;
103
            }
104

105
            if(e.type === "mousewheel" || e.type === "DOMMouseScroll")
106
            {
107
                return is_child(e.target, parent);
108
            }
109

110
            return !e.target || e.target.nodeName !== "INPUT" && e.target.nodeName !== "TEXTAREA";
111
        }
112
    }
113

114
    function touch_start_handler(e)
115
    {
116
        if(may_handle(e))
117
        {
118
            var touches = e["changedTouches"];
119

120
            if(touches && touches.length)
121
            {
122
                var touch = touches[touches.length - 1];
123
                last_x = touch.clientX;
124
                last_y = touch.clientY;
125
            }
126
        }
127
    }
128

129
    function touch_end_handler(e)
130
    {
131
        if(left_down || middle_down || right_down)
132
        {
133
            mouse.bus.send("mouse-click", [false, false, false]);
134
            left_down = middle_down = right_down = false;
135
        }
136
    }
137

138
    function mousemove_handler(e)
139
    {
140
        if(!mouse.bus)
141
        {
142
            return;
143
        }
144

145
        if(!may_handle(e))
146
        {
147
            return;
148
        }
149

150
        var delta_x = 0;
151
        var delta_y = 0;
152

153
        var touches = e["changedTouches"];
154

155
        if(touches)
156
        {
157
            if(touches.length)
158
            {
159
                var touch = touches[touches.length - 1];
160
                delta_x = touch.clientX - last_x;
161
                delta_y = touch.clientY - last_y;
162

163
                last_x = touch.clientX;
164
                last_y = touch.clientY;
165

166
                e.preventDefault();
167
            }
168
        }
169
        else
170
        {
171
            if(typeof e["movementX"] === "number")
172
            {
173
                delta_x = e["movementX"];
174
                delta_y = e["movementY"];
175
            }
176
            else if(typeof e["webkitMovementX"] === "number")
177
            {
178
                delta_x = e["webkitMovementX"];
179
                delta_y = e["webkitMovementY"];
180
            }
181
            else if(typeof e["mozMovementX"] === "number")
182
            {
183
                delta_x = e["mozMovementX"];
184
                delta_y = e["mozMovementY"];
185
            }
186
            else
187
            {
188
                // Fallback for other browsers?
189
                delta_x = e.clientX - last_x;
190
                delta_y = e.clientY - last_y;
191

192
                last_x = e.clientX;
193
                last_y = e.clientY;
194
            }
195
        }
196

197
        delta_x *= SPEED_FACTOR;
198
        delta_y *= SPEED_FACTOR;
199

200
        //if(Math.abs(delta_x) > 100 || Math.abs(delta_y) > 100)
201
        //{
202
        //    // Large mouse delta, drop?
203
        //}
204

205
        delta_y = -delta_y;
206

207
        mouse.bus.send("mouse-delta", [delta_x, delta_y]);
208

209
        if(screen_container)
210
        {
211
            let absolute_x = e.pageX - screen_container.offsetLeft;
212
            let absolute_y = e.pageY - screen_container.offsetTop;
213
            mouse.bus.send("mouse-absolute", [
214
                absolute_x, absolute_y, screen_container.offsetWidth, screen_container.offsetHeight]);
215
        }
216
    }
217

218
    function mousedown_handler(e)
219
    {
220
        if(may_handle(e))
221
        {
222
            click_event(e, true);
223
        }
224
    }
225

226
    function mouseup_handler(e)
227
    {
228
        if(may_handle(e))
229
        {
230
            click_event(e, false);
231
        }
232
    }
233

234
    function click_event(e, down)
235
    {
236
        if(!mouse.bus)
237
        {
238
            return;
239
        }
240

241
        if(e.which === 1)
242
        {
243
            left_down = down;
244
        }
245
        else if(e.which === 2)
246
        {
247
            middle_down = down;
248
        }
249
        else if(e.which === 3)
250
        {
251
            right_down = down;
252
        }
253
        else
254
        {
255
            dbg_log("Unknown event.which: " + e.which);
256
        }
257
        mouse.bus.send("mouse-click", [left_down, middle_down, right_down]);
258
        e.preventDefault();
259
    }
260

261
    function mousewheel_handler(e)
262
    {
263
        if(!may_handle(e))
264
        {
265
            return;
266
        }
267

268
        var delta_x = e.wheelDelta || -e.detail;
269
        var delta_y = 0;
270

271
        if(delta_x < 0)
272
        {
273
            delta_x = -1;
274
        }
275
        else if(delta_x > 0)
276
        {
277
            delta_x = 1;
278
        }
279

280
        mouse.bus.send("mouse-wheel", [delta_x, delta_y]);
281
        e.preventDefault();
282
    }
283
}
284

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.