From 205073d4c689ed830289f644f1e8c8a24c5d4099 Mon Sep 17 00:00:00 2001 From: Roman Shuvaryk Date: Mon, 28 Oct 2019 15:44:47 -0700 Subject: [PATCH] + Added ThrottleVisualuze mode. Mode adds middleware between constant screen refresh and turned off screen refresh. With mode active, screen will refresh only once per X millisecond. X is confugurable parameter in Config.js --- src/Config.js | 6 +++- src/irma/Canvas.js | 80 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 65 insertions(+), 21 deletions(-) diff --git a/src/Config.js b/src/Config.js index 082f674..21c2e5b 100644 --- a/src/Config.js +++ b/src/Config.js @@ -210,6 +210,10 @@ module.exports = { * {Number} Amount of frequencies in a world. It uses with say/listen commands */ worldFrequency : 10, + /** + * {Number} Number of milliseconds between two screen refreshes. Used only when ThrottleVisualize mode is enabled. + */ + THROTTLE_VISUALIZE_DELAY : 5000, /** * {Boolean} Turns on\off usage of IndexedDB for storing organisms population * @constant @@ -253,4 +257,4 @@ module.exports = { * Plugins. Extends irma core by additional functionality */ plugins : ['Decay'] -}; \ No newline at end of file +}; diff --git a/src/irma/Canvas.js b/src/irma/Canvas.js index dabacaf..75a46bc 100644 --- a/src/irma/Canvas.js +++ b/src/irma/Canvas.js @@ -9,23 +9,26 @@ const Config = require('./../Config'); class Canvas { constructor() { - this._width = Config.WORLD_WIDTH; - this._height = Config.WORLD_HEIGHT; - this._canvasEl = this._createCanvas(); - this._headerEl = this._createHeader(); - this._ctx = this._canvasEl.getContext('2d'); - this._imgData = this._ctx.createImageData(this._width, this._height); - this._data = this._imgData.data; - this._animate = this._onAnimate.bind(this); - this._visualize = true; - this._panZoom = null; - this._zoomObserver = null; - this._fullEl = this._createFullScreenBtn(); - this._visualizeEl = this._createVisualizeBtn(); - this._xDataOffs = 0; - this._yDataOffs = 0; - this._visibleWidth = Config.WORLD_WIDTH; - this._visibleHeight = Config.WORLD_HEIGHT; + this._width = Config.WORLD_WIDTH; + this._height = Config.WORLD_HEIGHT; + this._canvasEl = this._createCanvas(); + this._headerEl = this._createHeader(); + this._ctx = this._canvasEl.getContext('2d'); + this._imgData = this._ctx.createImageData(this._width, this._height); + this._data = this._imgData.data; + this._animate = this._onAnimate.bind(this); + this._visualize = true; + this._panZoom = null; + this._zoomObserver = null; + this._fullEl = this._createFullScreenBtn(); + this._visualizeEl = this._createVisualizeBtn(); + this._throttledVisualizeEl = this._createThrottledVisualizeBtn(); + this._xDataOffs = 0; + this._yDataOffs = 0; + this._visibleWidth = Config.WORLD_WIDTH; + this._visibleHeight = Config.WORLD_HEIGHT; + this._throttledVisualize = false; + this._throttledVisualizeCancel = null; this._prepareDom(); this._initPanZoomLib(); @@ -41,11 +44,13 @@ class Canvas { parentNode.removeChild(this._canvasEl); parentNode.removeChild(this._fullEl); parentNode.removeChild(this._visualizeEl); + parentNode.removeChild(this._throttledVisualizeEl); parentNode.removeChild(this._headerEl); this._headerEl = null; this._canvasEl = null; this._fullEl = null; this._visualizeEl = null; + this._throttledVisualizeEl = null; this._ctx = null; this._imgData = null; this._data = null; @@ -176,6 +181,27 @@ class Canvas { return el; } + _createThrottledVisualizeBtn() { + const el = document.body.appendChild(Helper.setStyles('DIV', { + position : 'absolute', + width : '20px', + height : '20px', + top : '7px', + left : '60px', + border : '1px #FFEB3B solid', + backgroundSize : '8px 8px', + borderRadius : '6px', + background : 'radial-gradient(#F44336 15%, transparent 16%) 0 0, radial-gradient(#F44336 15%, transparent 16%) 4px 4px, radial-gradient(rgba(255,255,253,.1) 15%, transparent 20%) 0 1px, radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 8px 8px', + backgroundColor: '#000', + cursor : 'pointer' + })); + + el.title = 'throttled visualize (Ctrl-T)'; + el.onclick = this._onThrottledVizualize.bind(this); + + return el; + } + _onFullscreen() { this._panZoom.zoomAbs(0, 0, 1.0); this._panZoom.moveTo(0, 0); @@ -189,12 +215,26 @@ class Canvas { this._onAnimate(); } + _onThrottledVizualize(enableThrottling) { + this._throttledVisualize = typeof(enableThrottling) == 'boolean' ? enableThrottling : !this._throttledVisualize; + this._throttledVisualizeEl.style.backgroundColor = this._throttledVisualize ? '#FFEB3B' : '#000'; + if (!this._throttledVisualize && this._throttledVisualizeCancel) { + clearTimeout(this._throttledVisualizeCancel); + this._throttledVisualizeCancel = null; + } + this._onAnimate(); + } + _onAnimate() { if (!this._panZoom) {return} this._ctx.putImageData(this._imgData, 0, 0, this._xDataOffs, this._yDataOffs, this._visibleWidth, this._visibleHeight); - if (this._visualize === true) { - window.requestAnimationFrame(this._animate); + if (this._visualize === true && this._throttledVisualize === true) { + this._throttledVisualizeCancel = setTimeout(() => { + window.requestAnimationFrame(this._animate); + }, Config.THROTTLE_VISUALIZE_DELAY) + } else if (this._visualize === true) { + window.requestAnimationFrame(this._animate) } } @@ -310,4 +350,4 @@ class Canvas { } } -module.exports = Canvas; \ No newline at end of file +module.exports = Canvas;