Mercurial > hg > orthanc-stone
comparison Platforms/WebAssembly/wasm-viewport.js @ 223:d30a10d574ec am
refactoring continued - not working
author | am@osimis.io |
---|---|
date | Thu, 14 Jun 2018 10:57:02 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
222:84844649a8fd | 223:d30a10d574ec |
---|---|
1 // http://stackoverflow.com/a/28900478/881731 | |
2 | |
3 function WebAssemblyViewport(module, canvasId) { | |
4 this.module = module; | |
5 | |
6 // Obtain a reference to the canvas element using its id | |
7 this.htmlCanvas = document.getElementById(canvasId); | |
8 | |
9 // Obtain a graphics context on the canvas element for drawing. | |
10 this.context = htmlCanvas.getContext('2d'); | |
11 | |
12 // ImageData structure that can be used to update the content of the canvas | |
13 this.imageData = null; | |
14 | |
15 // Temporary buffer in the WebAssembly heap that is used to render the pixels | |
16 this.renderingBuffer = null; | |
17 | |
18 // Get access to the WebAssembly functions | |
19 this.ViewportSetSize = this.module.cwrap('ViewportSetSize', null, [ 'number', 'number' ]); | |
20 this.ViewportRender = this.module.cwrap('ViewportRender', 'number', [ 'number', 'number', 'number' ]); | |
21 this.ViewportMouseDown = this.module.cwrap('ViewportMouseDown', null, [ 'number', 'number', 'number', 'number' ]); | |
22 this.ViewportMouseMove = this.module.cwrap('ViewportMouseMove', null, [ 'number', 'number' ]); | |
23 this.ViewportMouseUp = this.module.cwrap('ViewportMouseUp', null, [ ]); | |
24 this.ViewportMouseEnter = this.module.cwrap('ViewportMouseEnter', null, []); | |
25 this.ViewportMouseLeave = this.module.cwrap('ViewportMouseLeave', null, []); | |
26 this.ViewportMouseWheel = this.module.cwrap('ViewportMouseWheel', null, [ 'number', 'number', 'number', 'number' ]); | |
27 this.ViewportKeyPressed = this.module.cwrap('ViewportKeyPressed', null, [ 'string', 'number', 'number' ]); | |
28 | |
29 this.Redraw = function() { | |
30 if (this.imageData === null || | |
31 this.renderingBuffer === null || | |
32 ViewportRender(this.imageData.width, | |
33 this.imageData.height, | |
34 this.renderingBuffer) == 0) { | |
35 console.log('The rendering has failed'); | |
36 } else { | |
37 // Create an accessor to the rendering buffer (i.e. create a | |
38 // "window" above the heap of the WASM module), then copy it to | |
39 // the ImageData object | |
40 this.imageData.data.set(new Uint8ClampedArray( | |
41 this.module.buffer, | |
42 this.renderingBuffer, | |
43 this.imageData.width * this.imageData.height * 4)); | |
44 | |
45 this.context.putImageData(imageData, 0, 0); | |
46 } | |
47 } | |
48 | |
49 this.Resize = function() { | |
50 if (this.imageData != null && | |
51 (this.imageData.width != this.window.innerWidth || | |
52 this.imageData.height != this.window.innerHeight)) { | |
53 this.imageData = null; | |
54 } | |
55 | |
56 this.htmlCanvas.width = window.innerWidth; | |
57 this.htmlCanvas.height = window.innerHeight; | |
58 | |
59 if (this.imageData === null) { | |
60 this.imageData = context.getImageData(0, 0, this.htmlCanvas.width, this.htmlCanvas.height); | |
61 ViewportSetSize(this.htmlCanvas.width, this.htmlCanvas.height); | |
62 | |
63 if (this.renderingBuffer != null) { | |
64 this.module._free(this.renderingBuffer); | |
65 } | |
66 | |
67 renderingBuffer = this.module._malloc(this.imageData.width * this.imageData.height * 4); | |
68 } | |
69 | |
70 this.Redraw(); | |
71 } | |
72 | |
73 // Force the rendering of the viewport for the first time | |
74 this.Resize(); | |
75 | |
76 // Register an event listener to call the Resize() function | |
77 // each time the window is resized. | |
78 window.addEventListener('resize', this.Resize, false); | |
79 | |
80 var that = this; | |
81 | |
82 this.htmlCanvas.addEventListener('contextmenu', function(event) { | |
83 // Prevent right click on the canvas | |
84 event.preventDefault(); | |
85 }, false); | |
86 | |
87 this.htmlCanvas.addEventListener('mouseleave', function(event) { | |
88 that.ViewportMouseLeave(); | |
89 }); | |
90 | |
91 this.htmlCanvas.addEventListener('mouseenter', function(event) { | |
92 that.ViewportMouseEnter(); | |
93 }); | |
94 | |
95 this.htmlCanvas.addEventListener('mousedown', function(event) { | |
96 var x = event.pageX - this.offsetLeft; | |
97 var y = event.pageY - this.offsetTop; | |
98 that.ViewportMouseDown(event.button, x, y, 0 /* TODO */); | |
99 }); | |
100 | |
101 this.htmlCanvas.addEventListener('mousemove', function(event) { | |
102 var x = event.pageX - this.offsetLeft; | |
103 var y = event.pageY - this.offsetTop; | |
104 that.ViewportMouseMove(x, y); | |
105 }); | |
106 | |
107 this.htmlCanvas.addEventListener('mouseup', function(event) { | |
108 that.ViewportMouseUp(); | |
109 }); | |
110 | |
111 window.addEventListener('keydown', function(event) { | |
112 that.ViewportKeyPressed(event.key, event.shiftKey, event.ctrlKey, event.altKey); | |
113 }); | |
114 | |
115 this.htmlCanvas.addEventListener('wheel', function(event) { | |
116 var x = event.pageX - this.offsetLeft; | |
117 var y = event.pageY - this.offsetTop; | |
118 that.ViewportMouseWheel(event.deltaY, x, y, event.ctrlKey); | |
119 event.preventDefault(); | |
120 }); | |
121 | |
122 | |
123 // Touch events | |
124 this.touchTranslation = false; | |
125 this.touchZoom = false; | |
126 | |
127 this.ResetTouch = function() { | |
128 if (this.touchTranslation || | |
129 this.touchZoom) { | |
130 this.ViewportMouseUp(); | |
131 } | |
132 | |
133 this.touchTranslation = false; | |
134 this.touchZoom = false; | |
135 } | |
136 | |
137 this.GetTouchTranslation = function(event) { | |
138 var touch = event.targetTouches[0]; | |
139 return [ | |
140 touch.pageX, | |
141 touch.pageY | |
142 ]; | |
143 } | |
144 | |
145 this.GetTouchZoom = function(event) { | |
146 var touch1 = event.targetTouches[0]; | |
147 var touch2 = event.targetTouches[1]; | |
148 var dx = (touch1.pageX - touch2.pageX); | |
149 var dy = (touch1.pageY - touch2.pageY); | |
150 var d = Math.sqrt(dx * dx + dy * dy); | |
151 return [ | |
152 (touch1.pageX + touch2.pageX) / 2.0, | |
153 (touch1.pageY + touch2.pageY) / 2.0, | |
154 d | |
155 ]; | |
156 } | |
157 | |
158 this.htmlCanvas.addEventListener('touchstart', function(event) { | |
159 ResetTouch(); | |
160 }); | |
161 | |
162 this.htmlCanvas.addEventListener('touchend', function(event) { | |
163 ResetTouch(); | |
164 }); | |
165 | |
166 this.htmlCanvas.addEventListener('touchmove', function(event) { | |
167 if (that.touchTranslation.length == 2) { | |
168 var t = GetTouchTranslation(event); | |
169 that.ViewportMouseMove(t[0], t[1]); | |
170 } | |
171 else if (that.touchZoom.length == 3) { | |
172 var z0 = that.touchZoom; | |
173 var z1 = GetTouchZoom(event); | |
174 that.ViewportMouseMove(z0[0], z0[1] - z0[2] + z1[2]); | |
175 } | |
176 else { | |
177 // Realize the gesture event | |
178 if (event.targetTouches.length == 1) { | |
179 // Exactly one finger inside the canvas => Setup a translation | |
180 that.touchTranslation = GetTouchTranslation(event); | |
181 that.ViewportMouseDown(1 /* middle button */, | |
182 that.touchTranslation[0], | |
183 that.touchTranslation[1], 0); | |
184 } else if (event.targetTouches.length == 2) { | |
185 // Exactly 2 fingers inside the canvas => Setup a pinch/zoom | |
186 that.touchZoom = GetTouchZoom(event); | |
187 var z0 = that.touchZoom; | |
188 that.ViewportMouseDown(2 /* right button */, | |
189 z0[0], | |
190 z0[1], 0); | |
191 } | |
192 } | |
193 }); | |
194 | |
195 return this; | |
196 } | |
197 |