# HG changeset patch # User am@osimis.io # Date 1528972328 -7200 # Node ID 1fa4c65c7e1b5816476e4bd8bf8b8b18e5c7fd1a # Parent 930f98252ab9af20c97f2383f58b788318227918 WasmViewport in ts diff -r 930f98252ab9 -r 1fa4c65c7e1b Platforms/WebAssembly/wasm-application.js --- a/Platforms/WebAssembly/wasm-application.js Thu Jun 14 11:22:03 2018 +0200 +++ b/Platforms/WebAssembly/wasm-application.js Thu Jun 14 12:32:08 2018 +0200 @@ -47,7 +47,8 @@ function InitializeWasmApplication(canvasId) { console.log("Initializing wasm-app"); - viewport = WebAssemblyViewport(StoneFrameworkModule, 'canvas'); + viewport = new Stone.WasmViewport(StoneFrameworkModule, 'canvas'); + viewport.Initialize(); /******************** */ SetStartupParameter = StoneFrameworkModule.cwrap('SetStartupParameter', null, [ 'string', 'string' ]); diff -r 930f98252ab9 -r 1fa4c65c7e1b Platforms/WebAssembly/wasm-application.ts --- a/Platforms/WebAssembly/wasm-application.ts Thu Jun 14 11:22:03 2018 +0200 +++ b/Platforms/WebAssembly/wasm-application.ts Thu Jun 14 12:32:08 2018 +0200 @@ -3,6 +3,8 @@ declare function InitializeWasmApplication() :void; // still in a js file + + // Wait for the Orthanc Framework to be initialized (this initializes // the WebAssembly environment) Stone.Framework.Initialize(true, function() { diff -r 930f98252ab9 -r 1fa4c65c7e1b Platforms/WebAssembly/wasm-viewport.js --- a/Platforms/WebAssembly/wasm-viewport.js Thu Jun 14 11:22:03 2018 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,197 +0,0 @@ -// http://stackoverflow.com/a/28900478/881731 - -function WebAssemblyViewport(module, canvasId) { - this.module = module; - - // Obtain a reference to the canvas element using its id - this.htmlCanvas = document.getElementById(canvasId); - - // Obtain a graphics context on the canvas element for drawing. - this.context = htmlCanvas.getContext('2d'); - - // ImageData structure that can be used to update the content of the canvas - this.imageData = null; - - // Temporary buffer in the WebAssembly heap that is used to render the pixels - this.renderingBuffer = null; - - // Get access to the WebAssembly functions - this.ViewportSetSize = this.module.cwrap('ViewportSetSize', null, [ 'number', 'number' ]); - this.ViewportRender = this.module.cwrap('ViewportRender', 'number', [ 'number', 'number', 'number' ]); - this.ViewportMouseDown = this.module.cwrap('ViewportMouseDown', null, [ 'number', 'number', 'number', 'number' ]); - this.ViewportMouseMove = this.module.cwrap('ViewportMouseMove', null, [ 'number', 'number' ]); - this.ViewportMouseUp = this.module.cwrap('ViewportMouseUp', null, [ ]); - this.ViewportMouseEnter = this.module.cwrap('ViewportMouseEnter', null, []); - this.ViewportMouseLeave = this.module.cwrap('ViewportMouseLeave', null, []); - this.ViewportMouseWheel = this.module.cwrap('ViewportMouseWheel', null, [ 'number', 'number', 'number', 'number' ]); - this.ViewportKeyPressed = this.module.cwrap('ViewportKeyPressed', null, [ 'string', 'number', 'number' ]); - - this.Redraw = function() { - if (this.imageData === null || - this.renderingBuffer === null || - ViewportRender(this.imageData.width, - this.imageData.height, - this.renderingBuffer) == 0) { - console.log('The rendering has failed'); - } else { - // Create an accessor to the rendering buffer (i.e. create a - // "window" above the heap of the WASM module), then copy it to - // the ImageData object - this.imageData.data.set(new Uint8ClampedArray( - this.module.buffer, - this.renderingBuffer, - this.imageData.width * this.imageData.height * 4)); - - this.context.putImageData(imageData, 0, 0); - } - } - - this.Resize = function() { - if (this.imageData != null && - (this.imageData.width != this.window.innerWidth || - this.imageData.height != this.window.innerHeight)) { - this.imageData = null; - } - - this.htmlCanvas.width = window.innerWidth; - this.htmlCanvas.height = window.innerHeight; - - if (this.imageData === null) { - this.imageData = context.getImageData(0, 0, this.htmlCanvas.width, this.htmlCanvas.height); - ViewportSetSize(this.htmlCanvas.width, this.htmlCanvas.height); - - if (this.renderingBuffer != null) { - this.module._free(this.renderingBuffer); - } - - renderingBuffer = this.module._malloc(this.imageData.width * this.imageData.height * 4); - } - - this.Redraw(); - } - - // Force the rendering of the viewport for the first time - this.Resize(); - - // Register an event listener to call the Resize() function - // each time the window is resized. - window.addEventListener('resize', this.Resize, false); - - var that = this; - - this.htmlCanvas.addEventListener('contextmenu', function(event) { - // Prevent right click on the canvas - event.preventDefault(); - }, false); - - this.htmlCanvas.addEventListener('mouseleave', function(event) { - that.ViewportMouseLeave(); - }); - - this.htmlCanvas.addEventListener('mouseenter', function(event) { - that.ViewportMouseEnter(); - }); - - this.htmlCanvas.addEventListener('mousedown', function(event) { - var x = event.pageX - this.offsetLeft; - var y = event.pageY - this.offsetTop; - that.ViewportMouseDown(event.button, x, y, 0 /* TODO */); - }); - - this.htmlCanvas.addEventListener('mousemove', function(event) { - var x = event.pageX - this.offsetLeft; - var y = event.pageY - this.offsetTop; - that.ViewportMouseMove(x, y); - }); - - this.htmlCanvas.addEventListener('mouseup', function(event) { - that.ViewportMouseUp(); - }); - - window.addEventListener('keydown', function(event) { - that.ViewportKeyPressed(event.key, event.shiftKey, event.ctrlKey, event.altKey); - }); - - this.htmlCanvas.addEventListener('wheel', function(event) { - var x = event.pageX - this.offsetLeft; - var y = event.pageY - this.offsetTop; - that.ViewportMouseWheel(event.deltaY, x, y, event.ctrlKey); - event.preventDefault(); - }); - - - // Touch events - this.touchTranslation = false; - this.touchZoom = false; - - this.ResetTouch = function() { - if (this.touchTranslation || - this.touchZoom) { - this.ViewportMouseUp(); - } - - this.touchTranslation = false; - this.touchZoom = false; - } - - this.GetTouchTranslation = function(event) { - var touch = event.targetTouches[0]; - return [ - touch.pageX, - touch.pageY - ]; - } - - this.GetTouchZoom = function(event) { - var touch1 = event.targetTouches[0]; - var touch2 = event.targetTouches[1]; - var dx = (touch1.pageX - touch2.pageX); - var dy = (touch1.pageY - touch2.pageY); - var d = Math.sqrt(dx * dx + dy * dy); - return [ - (touch1.pageX + touch2.pageX) / 2.0, - (touch1.pageY + touch2.pageY) / 2.0, - d - ]; - } - - this.htmlCanvas.addEventListener('touchstart', function(event) { - ResetTouch(); - }); - - this.htmlCanvas.addEventListener('touchend', function(event) { - ResetTouch(); - }); - - this.htmlCanvas.addEventListener('touchmove', function(event) { - if (that.touchTranslation.length == 2) { - var t = GetTouchTranslation(event); - that.ViewportMouseMove(t[0], t[1]); - } - else if (that.touchZoom.length == 3) { - var z0 = that.touchZoom; - var z1 = GetTouchZoom(event); - that.ViewportMouseMove(z0[0], z0[1] - z0[2] + z1[2]); - } - else { - // Realize the gesture event - if (event.targetTouches.length == 1) { - // Exactly one finger inside the canvas => Setup a translation - that.touchTranslation = GetTouchTranslation(event); - that.ViewportMouseDown(1 /* middle button */, - that.touchTranslation[0], - that.touchTranslation[1], 0); - } else if (event.targetTouches.length == 2) { - // Exactly 2 fingers inside the canvas => Setup a pinch/zoom - that.touchZoom = GetTouchZoom(event); - var z0 = that.touchZoom; - that.ViewportMouseDown(2 /* right button */, - z0[0], - z0[1], 0); - } - } - }); - - return this; - } - \ No newline at end of file diff -r 930f98252ab9 -r 1fa4c65c7e1b Platforms/WebAssembly/wasm-viewport.ts --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Platforms/WebAssembly/wasm-viewport.ts Thu Jun 14 12:32:08 2018 +0200 @@ -0,0 +1,216 @@ + +module Stone { + +// export declare type InitializationCallback = () => void; + +// export declare var StoneFrameworkModule : any; + + //const ASSETS_FOLDER : string = "assets/lib"; + //const WASM_FILENAME : string = "orthanc-framework"; + + export class WasmViewport { + + private module_ : any; + private canvasId_ : string; + private htmlCanvas_ : HTMLCanvasElement; + private context_ : CanvasRenderingContext2D; + private imageData_ : any = null; + private renderingBuffer_ : any = null; + private touchZoom_ : any = false; + private touchTranslation_ : any = false; + + private ViewportSetSize : Function; + private ViewportRender : Function; + private ViewportMouseDown : Function; + private ViewportMouseMove : Function; + private ViewportMouseUp : Function; + private ViewportMouseEnter : Function; + private ViewportMouseLeave : Function; + private ViewportMouseWheel : Function; + private ViewportKeyPressed : Function; + + public constructor(module: any, canvasId: string) { + this.module_ = module; + this.canvasId_ = canvasId; + this.htmlCanvas_ = document.getElementById(this.canvasId_) as HTMLCanvasElement; + this.context_ = this.htmlCanvas_.getContext('2d'); + + this.ViewportSetSize = this.module_.cwrap('ViewportSetSize', null, [ 'number', 'number' ]); + this.ViewportRender = this.module_.cwrap('ViewportRender', null, [ 'number', 'number', 'number', 'number' ]); + this.ViewportMouseDown = this.module_.cwrap('ViewportMouseDown', null, [ 'number', 'number', 'number', 'number' ]); + this.ViewportMouseMove = this.module_.cwrap('ViewportMouseMove', null, [ 'number', 'number' ]); + this.ViewportMouseUp = this.module_.cwrap('ViewportMouseUp', null, [ ]); + this.ViewportMouseEnter = this.module_.cwrap('ViewportMouseEnter', null, []); + this.ViewportMouseLeave = this.module_.cwrap('ViewportMouseLeave', null, []); + this.ViewportMouseWheel = this.module_.cwrap('ViewportMouseWheel', null, [ 'number', 'number', 'number', 'number' ]); + this.ViewportKeyPressed = this.module_.cwrap('ViewportKeyPressed', null, [ 'string', 'number', 'number' ]); + } + + public Redraw() { + if (this.imageData_ === null || + this.renderingBuffer_ === null || + this.ViewportRender(this.imageData_.width, + this.imageData_.height, + this.renderingBuffer_) == 0) { + console.log('The rendering has failed'); + } else { + // Create an accessor to the rendering buffer (i.e. create a + // "window" above the heap of the WASM module), then copy it to + // the ImageData object + this.imageData_.data.set(new Uint8ClampedArray( + this.module_.buffer, + this.renderingBuffer_, + this.imageData_.width * this.imageData_.height * 4)); + + this.context_.putImageData(this.imageData_, 0, 0); + } + } + + public Resize() { + if (this.imageData_ != null && + (this.imageData_.width != window.innerWidth || + this.imageData_.height != window.innerHeight)) { + this.imageData_ = null; + } + + this.htmlCanvas_.width = window.innerWidth; + this.htmlCanvas_.height = window.innerHeight; + + if (this.imageData_ === null) { + this.imageData_ = this.context_.getImageData(0, 0, this.htmlCanvas_.width, this.htmlCanvas_.height); + this.ViewportSetSize(this.htmlCanvas_.width, this.htmlCanvas_.height); + + if (this.renderingBuffer_ != null) { + this.module_._free(this.renderingBuffer_); + } + + this.renderingBuffer_ = this.module_._malloc(this.imageData_.width * this.imageData_.height * 4); + } + + this.Redraw(); + } + + public Initialize() { + + // Force the rendering of the viewport for the first time + this.Resize(); + + // Register an event listener to call the Resize() function + // each time the window is resized. + window.addEventListener('resize', this.Resize, false); + + var that = this; + + this.htmlCanvas_.addEventListener('contextmenu', function(event) { + // Prevent right click on the canvas + event.preventDefault(); + }, false); + + this.htmlCanvas_.addEventListener('mouseleave', function(event) { + that.ViewportMouseLeave(); + }); + + this.htmlCanvas_.addEventListener('mouseenter', function(event) { + that.ViewportMouseEnter(); + }); + + this.htmlCanvas_.addEventListener('mousedown', function(event) { + var x = event.pageX - this.offsetLeft; + var y = event.pageY - this.offsetTop; + that.ViewportMouseDown(event.button, x, y, 0 /* TODO */); + }); + + this.htmlCanvas_.addEventListener('mousemove', function(event) { + var x = event.pageX - this.offsetLeft; + var y = event.pageY - this.offsetTop; + that.ViewportMouseMove(x, y); + }); + + this.htmlCanvas_.addEventListener('mouseup', function(event) { + that.ViewportMouseUp(); + }); + + window.addEventListener('keydown', function(event) { + that.ViewportKeyPressed(event.key, event.shiftKey, event.ctrlKey, event.altKey); + }); + + this.htmlCanvas_.addEventListener('wheel', function(event) { + var x = event.pageX - this.offsetLeft; + var y = event.pageY - this.offsetTop; + that.ViewportMouseWheel(event.deltaY, x, y, event.ctrlKey); + event.preventDefault(); + }); + + var that = this; + this.htmlCanvas_.addEventListener('touchstart', function(event) { + that.ResetTouch(); + }); + + this.htmlCanvas_.addEventListener('touchend', function(event) { + that.ResetTouch(); + }); + + this.htmlCanvas_.addEventListener('touchmove', function(event) { + if (that.touchTranslation_.length == 2) { + var t = that.GetTouchTranslation(event); + that.ViewportMouseMove(t[0], t[1]); + } + else if (that.touchZoom_.length == 3) { + var z0 = that.touchZoom_; + var z1 = that.GetTouchZoom(event); + that.ViewportMouseMove(z0[0], z0[1] - z0[2] + z1[2]); + } + else { + // Realize the gesture event + if (event.targetTouches.length == 1) { + // Exactly one finger inside the canvas => Setup a translation + that.touchTranslation_ = that.GetTouchTranslation(event); + that.ViewportMouseDown(1 /* middle button */, + that.touchTranslation_[0], + that.touchTranslation_[1], 0); + } else if (event.targetTouches.length == 2) { + // Exactly 2 fingers inside the canvas => Setup a pinch/zoom + that.touchZoom_ = that.GetTouchZoom(event); + var z0 = that.touchZoom_; + that.ViewportMouseDown(2 /* right button */, + z0[0], + z0[1], 0); + } + } + }); + } + + public ResetTouch() { + if (this.touchTranslation_ || + this.touchZoom_) { + this.ViewportMouseUp(); + } + + this.touchTranslation_ = false; + this.touchZoom_ = false; + } + + public GetTouchTranslation(event) { + var touch = event.targetTouches[0]; + return [ + touch.pageX, + touch.pageY + ]; + } + + public GetTouchZoom(event) { + var touch1 = event.targetTouches[0]; + var touch2 = event.targetTouches[1]; + var dx = (touch1.pageX - touch2.pageX); + var dy = (touch1.pageY - touch2.pageY); + var d = Math.sqrt(dx * dx + dy * dy); + return [ + (touch1.pageX + touch2.pageX) / 2.0, + (touch1.pageY + touch2.pageY) / 2.0, + d + ]; + } + + } +} + \ No newline at end of file