/** * R3.D3.Viewport.FixedAspect * * Respect the aspectRatio setting and adjust viewport x,y,width and height accordingly * - entire viewport remains visible at all times * - will have empty space above or below viewport depending on canvas size (if canvas ratio != viewport ratio) * - is centered around center of canvas * * @param apiComponent */ R3.D3.Viewport.FixedAspect = function( apiComponent, inherited ) { __INHERIT_AND_INSTANTIATE__; R3.D3.Viewport.call( this, true ) }; R3.D3.Viewport.FixedAspect.prototype = Object.create(R3.D3.Viewport.prototype); R3.D3.Viewport.FixedAspect.prototype.constructor = R3.D3.Viewport.FixedAspect; R3.D3.Viewport.FixedAspect.prototype.createInstance = function() { this.calculateDimensions(); this.instance = this.graphics.Vector4( this.x, this.y, this.width, this.height ); __CREATE_INSTANCE__; }; R3.D3.Viewport.FixedAspect.prototype.updateInstance = function(property) { /** * Viewports don't have an explicit size, but calling updateInstance with 'size' property will update its dimensions */ if ( property === 'aspectRatio' || property === 'size' ) { this.calculateDimensions(); this.instance.x = this.x; this.instance.y = this.y; this.instance.z = this.width; this.instance.w = this.height; return; } R3.D3.Viewport.prototype.updateInstance.call(this, property); }; /** * This calculates the dimensions of the viewport based on the following example info: * * aspect = width * ------ * height * * width = aspect * height; * height = width / aspect; * * aspect > 1 (width > height) (landscape) * aspect < 1 (height > width) (portrait) * * 4 / 3 = 1.33333 (1920 x 1440) * 16 / 9 = 1.77777 (1920 x 1080) * * w h w h * 9 / 16 = 0.5625 (1080 x 1920) - required * 3 / 4 = 0.75 (1440 x 1920) - current * * @returns {{left: number, right: number, top: number, bottom: number}} */ R3.D3.Viewport.FixedAspect.prototype.calculateDimensions = function() { var canvasSize = this.parent.getCanvasSize(); var canvasAspectRatio = canvasSize.aspectRatio; if (canvasAspectRatio > 1) { /** * Width is greater than height (landscape) */ if (this.aspectRatio < 1) { /** * The required aspect ratio is portrait mode - use the full Height of the canvas */ this.width = this.aspectRatio * canvasSize.height; this.height = canvasSize.height; } else { /** * The required aspect is also more wide than high - so we have another two possibilities: * a) The required aspect is greater than the current aspect - this means the required aspect is less high * than the current aspect - we can use the full width * * b) The required aspect is less than the current aspect - this means the required aspect is higher than * the current aspect - we need to determine a new width based on the current height */ if (this.aspectRatio > canvasAspectRatio) { /** * a) */ this.width = canvasSize.width; this.height = canvasSize.width / this.aspectRatio; } else { /** * b) */ this.height = canvasSize.height; this.width = this.aspectRatio * canvasSize.height; } } } else { /** * Width is less than height (portrait) */ if (this.aspectRatio > 1) { /** * The required aspect is landscape in a portrait mode - but we are in landscape - use the full width and * calculate the new height */ this.width = canvasSize.width; this.height = canvasSize.width / this.aspectRatio; } else { /** * The required aspect is also more high than wide (portrait) - we have again, two possibilities * a) The required aspect is greater than the current aspect - this means the required aspect does not fit * the full width of the current aspect - use the full width of the current size and determine a new height * * b) The required aspect is less than the current aspect - this means that the required aspect is less wide * than the current aspect, so we can use the full height of the current size and determine a new width */ if (this.aspectRatio > canvasAspectRatio) { /** * a) */ this.width = canvasSize.width; this.height = canvasSize.width / this.aspectRatio; } else { /** * b) */ this.height = canvasSize.height; this.width = canvasSize.height * this.aspectRatio; } } } /** * Clamp the values between 0 and 1 */ this.width = this.width / canvasSize.width; this.height = this.height / canvasSize.height; /** * Center the viewport */ if (this.height < 1) { this.y = (1 - this.height) / 2; } else { this.y = 0; } if (this.width < 1) { this.x = (1 - this.width) / 2; } else { this.x = 0; } this.x += this.offset.x; this.y += this.offset.y; };