Mercurial > hg > orthanc-stone
comparison Platforms/WebAssembly/wasm-viewport.ts @ 226:1fa4c65c7e1b am
WasmViewport in ts
author | am@osimis.io |
---|---|
date | Thu, 14 Jun 2018 12:32:08 +0200 |
parents | |
children | c8f11437a6fd |
comparison
equal
deleted
inserted
replaced
225:930f98252ab9 | 226:1fa4c65c7e1b |
---|---|
1 | |
2 module Stone { | |
3 | |
4 // export declare type InitializationCallback = () => void; | |
5 | |
6 // export declare var StoneFrameworkModule : any; | |
7 | |
8 //const ASSETS_FOLDER : string = "assets/lib"; | |
9 //const WASM_FILENAME : string = "orthanc-framework"; | |
10 | |
11 export class WasmViewport { | |
12 | |
13 private module_ : any; | |
14 private canvasId_ : string; | |
15 private htmlCanvas_ : HTMLCanvasElement; | |
16 private context_ : CanvasRenderingContext2D; | |
17 private imageData_ : any = null; | |
18 private renderingBuffer_ : any = null; | |
19 private touchZoom_ : any = false; | |
20 private touchTranslation_ : any = false; | |
21 | |
22 private ViewportSetSize : Function; | |
23 private ViewportRender : Function; | |
24 private ViewportMouseDown : Function; | |
25 private ViewportMouseMove : Function; | |
26 private ViewportMouseUp : Function; | |
27 private ViewportMouseEnter : Function; | |
28 private ViewportMouseLeave : Function; | |
29 private ViewportMouseWheel : Function; | |
30 private ViewportKeyPressed : Function; | |
31 | |
32 public constructor(module: any, canvasId: string) { | |
33 this.module_ = module; | |
34 this.canvasId_ = canvasId; | |
35 this.htmlCanvas_ = document.getElementById(this.canvasId_) as HTMLCanvasElement; | |
36 this.context_ = this.htmlCanvas_.getContext('2d'); | |
37 | |
38 this.ViewportSetSize = this.module_.cwrap('ViewportSetSize', null, [ 'number', 'number' ]); | |
39 this.ViewportRender = this.module_.cwrap('ViewportRender', null, [ 'number', 'number', 'number', 'number' ]); | |
40 this.ViewportMouseDown = this.module_.cwrap('ViewportMouseDown', null, [ 'number', 'number', 'number', 'number' ]); | |
41 this.ViewportMouseMove = this.module_.cwrap('ViewportMouseMove', null, [ 'number', 'number' ]); | |
42 this.ViewportMouseUp = this.module_.cwrap('ViewportMouseUp', null, [ ]); | |
43 this.ViewportMouseEnter = this.module_.cwrap('ViewportMouseEnter', null, []); | |
44 this.ViewportMouseLeave = this.module_.cwrap('ViewportMouseLeave', null, []); | |
45 this.ViewportMouseWheel = this.module_.cwrap('ViewportMouseWheel', null, [ 'number', 'number', 'number', 'number' ]); | |
46 this.ViewportKeyPressed = this.module_.cwrap('ViewportKeyPressed', null, [ 'string', 'number', 'number' ]); | |
47 } | |
48 | |
49 public Redraw() { | |
50 if (this.imageData_ === null || | |
51 this.renderingBuffer_ === null || | |
52 this.ViewportRender(this.imageData_.width, | |
53 this.imageData_.height, | |
54 this.renderingBuffer_) == 0) { | |
55 console.log('The rendering has failed'); | |
56 } else { | |
57 // Create an accessor to the rendering buffer (i.e. create a | |
58 // "window" above the heap of the WASM module), then copy it to | |
59 // the ImageData object | |
60 this.imageData_.data.set(new Uint8ClampedArray( | |
61 this.module_.buffer, | |
62 this.renderingBuffer_, | |
63 this.imageData_.width * this.imageData_.height * 4)); | |
64 | |
65 this.context_.putImageData(this.imageData_, 0, 0); | |
66 } | |
67 } | |
68 | |
69 public Resize() { | |
70 if (this.imageData_ != null && | |
71 (this.imageData_.width != window.innerWidth || | |
72 this.imageData_.height != window.innerHeight)) { | |
73 this.imageData_ = null; | |
74 } | |
75 | |
76 this.htmlCanvas_.width = window.innerWidth; | |
77 this.htmlCanvas_.height = window.innerHeight; | |
78 | |
79 if (this.imageData_ === null) { | |
80 this.imageData_ = this.context_.getImageData(0, 0, this.htmlCanvas_.width, this.htmlCanvas_.height); | |
81 this.ViewportSetSize(this.htmlCanvas_.width, this.htmlCanvas_.height); | |
82 | |
83 if (this.renderingBuffer_ != null) { | |
84 this.module_._free(this.renderingBuffer_); | |
85 } | |
86 | |
87 this.renderingBuffer_ = this.module_._malloc(this.imageData_.width * this.imageData_.height * 4); | |
88 } | |
89 | |
90 this.Redraw(); | |
91 } | |
92 | |
93 public Initialize() { | |
94 | |
95 // Force the rendering of the viewport for the first time | |
96 this.Resize(); | |
97 | |
98 // Register an event listener to call the Resize() function | |
99 // each time the window is resized. | |
100 window.addEventListener('resize', this.Resize, false); | |
101 | |
102 var that = this; | |
103 | |
104 this.htmlCanvas_.addEventListener('contextmenu', function(event) { | |
105 // Prevent right click on the canvas | |
106 event.preventDefault(); | |
107 }, false); | |
108 | |
109 this.htmlCanvas_.addEventListener('mouseleave', function(event) { | |
110 that.ViewportMouseLeave(); | |
111 }); | |
112 | |
113 this.htmlCanvas_.addEventListener('mouseenter', function(event) { | |
114 that.ViewportMouseEnter(); | |
115 }); | |
116 | |
117 this.htmlCanvas_.addEventListener('mousedown', function(event) { | |
118 var x = event.pageX - this.offsetLeft; | |
119 var y = event.pageY - this.offsetTop; | |
120 that.ViewportMouseDown(event.button, x, y, 0 /* TODO */); | |
121 }); | |
122 | |
123 this.htmlCanvas_.addEventListener('mousemove', function(event) { | |
124 var x = event.pageX - this.offsetLeft; | |
125 var y = event.pageY - this.offsetTop; | |
126 that.ViewportMouseMove(x, y); | |
127 }); | |
128 | |
129 this.htmlCanvas_.addEventListener('mouseup', function(event) { | |
130 that.ViewportMouseUp(); | |
131 }); | |
132 | |
133 window.addEventListener('keydown', function(event) { | |
134 that.ViewportKeyPressed(event.key, event.shiftKey, event.ctrlKey, event.altKey); | |
135 }); | |
136 | |
137 this.htmlCanvas_.addEventListener('wheel', function(event) { | |
138 var x = event.pageX - this.offsetLeft; | |
139 var y = event.pageY - this.offsetTop; | |
140 that.ViewportMouseWheel(event.deltaY, x, y, event.ctrlKey); | |
141 event.preventDefault(); | |
142 }); | |
143 | |
144 var that = this; | |
145 this.htmlCanvas_.addEventListener('touchstart', function(event) { | |
146 that.ResetTouch(); | |
147 }); | |
148 | |
149 this.htmlCanvas_.addEventListener('touchend', function(event) { | |
150 that.ResetTouch(); | |
151 }); | |
152 | |
153 this.htmlCanvas_.addEventListener('touchmove', function(event) { | |
154 if (that.touchTranslation_.length == 2) { | |
155 var t = that.GetTouchTranslation(event); | |
156 that.ViewportMouseMove(t[0], t[1]); | |
157 } | |
158 else if (that.touchZoom_.length == 3) { | |
159 var z0 = that.touchZoom_; | |
160 var z1 = that.GetTouchZoom(event); | |
161 that.ViewportMouseMove(z0[0], z0[1] - z0[2] + z1[2]); | |
162 } | |
163 else { | |
164 // Realize the gesture event | |
165 if (event.targetTouches.length == 1) { | |
166 // Exactly one finger inside the canvas => Setup a translation | |
167 that.touchTranslation_ = that.GetTouchTranslation(event); | |
168 that.ViewportMouseDown(1 /* middle button */, | |
169 that.touchTranslation_[0], | |
170 that.touchTranslation_[1], 0); | |
171 } else if (event.targetTouches.length == 2) { | |
172 // Exactly 2 fingers inside the canvas => Setup a pinch/zoom | |
173 that.touchZoom_ = that.GetTouchZoom(event); | |
174 var z0 = that.touchZoom_; | |
175 that.ViewportMouseDown(2 /* right button */, | |
176 z0[0], | |
177 z0[1], 0); | |
178 } | |
179 } | |
180 }); | |
181 } | |
182 | |
183 public ResetTouch() { | |
184 if (this.touchTranslation_ || | |
185 this.touchZoom_) { | |
186 this.ViewportMouseUp(); | |
187 } | |
188 | |
189 this.touchTranslation_ = false; | |
190 this.touchZoom_ = false; | |
191 } | |
192 | |
193 public GetTouchTranslation(event) { | |
194 var touch = event.targetTouches[0]; | |
195 return [ | |
196 touch.pageX, | |
197 touch.pageY | |
198 ]; | |
199 } | |
200 | |
201 public GetTouchZoom(event) { | |
202 var touch1 = event.targetTouches[0]; | |
203 var touch2 = event.targetTouches[1]; | |
204 var dx = (touch1.pageX - touch2.pageX); | |
205 var dy = (touch1.pageY - touch2.pageY); | |
206 var d = Math.sqrt(dx * dx + dy * dy); | |
207 return [ | |
208 (touch1.pageX + touch2.pageX) / 2.0, | |
209 (touch1.pageY + touch2.pageY) / 2.0, | |
210 d | |
211 ]; | |
212 } | |
213 | |
214 } | |
215 } | |
216 |