From 8be4bb11d895917a6c4714b4b1a2e09f3c8e5e4a Mon Sep 17 00:00:00 2001 From: Sam El-Husseini Date: Wed, 27 Dec 2017 16:30:42 -0800 Subject: [PATCH] Fix resizing in controls to work for all sizes including full screen --- sim/visuals/board.ts | 9 ++++- sim/visuals/controlView.ts | 18 ++++++++-- sim/visuals/controls/colorGrid.ts | 31 +++++++++++------ sim/visuals/controls/colorWheel.ts | 10 +++++- sim/visuals/controls/distanceSlider.ts | 47 ++++++++++++++++++-------- 5 files changed, 85 insertions(+), 30 deletions(-) diff --git a/sim/visuals/board.ts b/sim/visuals/board.ts index 5c3d5146..b3f92cc4 100644 --- a/sim/visuals/board.ts +++ b/sim/visuals/board.ts @@ -33,11 +33,18 @@ namespace pxsim.visuals { font-family:"Lucida Console", Monaco, monospace; font-size:8px; fill:#fff; - pointer-events: none; user-select: none; + pointer-events: none; + user-select: none; } .sim-text.small { font-size:6px; } + .sim-text.large { + font-size:30px; + } + .sim-text.number { + font-family: Lato, Work Sans, PT Serif, Source Serif Pro; + } .sim-text.inverted { fill:#000; } diff --git a/sim/visuals/controlView.ts b/sim/visuals/controlView.ts index e8fdbc4f..4bcebe92 100644 --- a/sim/visuals/controlView.ts +++ b/sim/visuals/controlView.ts @@ -5,6 +5,8 @@ namespace pxsim.visuals { export const CONTROL_WIDTH = 87.5; export const CONTROL_HEIGHT = 175; + export const CONTROL_TEXT_COLOR = '#000'; + export abstract class ControlView extends SimView implements LayoutElement { protected content: SVGSVGElement; @@ -36,7 +38,7 @@ namespace pxsim.visuals { } buildDom(): SVGElement { - this.content = svg.elt("svg", { viewBox: `0 0 ${this.getInnerWidth()} ${this.getInnerHeight()}`}) as SVGSVGElement; + this.content = svg.elt("svg", { viewBox: `0 0 ${this.getInnerWidth()} ${this.getInnerHeight()}` }) as SVGSVGElement; this.content.appendChild(this.getInnerView(this.parent, this.globalDefs)); return this.content; } @@ -52,8 +54,18 @@ namespace pxsim.visuals { const currentHeight = this.getInnerHeight(); const newHeight = currentHeight / currentWidth * width; const newWidth = currentWidth / currentHeight * height; - this.content.setAttribute('width', `${width}`); - this.content.setAttribute('height', `${newHeight}`); + if (newHeight > height) { + // scale width instead + this.content.setAttribute('width', `${newWidth}`); + this.content.setAttribute('height', `${height}`); + // translate to the middle (width) + this.translate(width / 2 - newWidth / 2, 0); + } else { + this.content.setAttribute('width', `${width}`); + this.content.setAttribute('height', `${newHeight}`); + // translate to the middle (height) + this.translate(0, height / 2 - newHeight / 2); + } } } diff --git a/sim/visuals/controls/colorGrid.ts b/sim/visuals/controls/colorGrid.ts index c1d6b6fc..ea5823a9 100644 --- a/sim/visuals/controls/colorGrid.ts +++ b/sim/visuals/controls/colorGrid.ts @@ -7,35 +7,46 @@ namespace pxsim.visuals { getInnerView() { this.group = svg.elt("g") as SVGGElement; - this.group.setAttribute("transform", `translate(17, ${20 + this.getHeight() / 4}) scale(5)`) + const innerHeight = 13; + const innerWidth = 11; + this.group.setAttribute("transform", `translate(1.02, 1.5) scale(0.8)`) - const colorIds = ['red', 'yellow', 'blue', 'green', 'black', 'grey']; - const colors = ['#f12a21', '#ffd01b', '#006db3', '#00934b', '#000', '#6c2d00']; + const colorIds = ['red', 'yellow', 'blue', 'green', undefined, 'grey']; + const colors = ['#f12a21', '#ffd01b', '#006db3', '#00934b', undefined, '#6c2d00']; const colorValue = [5, 4, 2, 3, 1, 7]; let cy = -4; for (let c = 0; c < colorIds.length; c++) { const cx = c % 2 == 0 ? 2.2 : 8.2; if (c % 2 == 0) cy += 5; - const circle = pxsim.svg.child(this.group, "circle", { 'class': 'sim-color-grid-circle', 'cx': cx, 'cy': cy, 'r': '2', 'style': `fill: ${colors[c]}` }); - circle.addEventListener(pointerEvents.down, ev => { - this.setColor(colorValue[c]); - }) + if (colorIds[c]) { + const circle = pxsim.svg.child(this.group, "circle", { 'class': 'sim-color-grid-circle', 'cx': cx, 'cy': cy, 'r': '2', 'style': `fill: ${colors[c]}` }); + circle.addEventListener(pointerEvents.down, ev => { + this.setColor(colorValue[c]); + }) + } } const whiteCircleWrapper = pxsim.svg.child(this.group, "g", { 'id': 'white-cirlce-wrapper' }); - pxsim.svg.child(whiteCircleWrapper, "circle", { 'class': 'sim-color-grid-circle', 'cx': 2.2, 'cy': '16', 'r': '2', 'style': `fill: #fff` }); - pxsim.svg.child(whiteCircleWrapper, "circle", { 'cx': 2.2, 'cy': '16', 'r': '2', 'style': `fill: none;stroke: #94989b;stroke-width: 0.5px` }); + pxsim.svg.child(whiteCircleWrapper, "circle", { 'class': 'sim-color-grid-circle', 'cx': 2.2, 'cy': '11', 'r': '2', 'style': `fill: #fff` }); + pxsim.svg.child(whiteCircleWrapper, "circle", { 'cx': 2.2, 'cy': '11', 'r': '2', 'style': `fill: none;stroke: #94989b;stroke-width: 0.1px` }); whiteCircleWrapper.addEventListener(pointerEvents.down, ev => { this.setColor(6); }) return this.group; } + getInnerWidth() { + return 10.2; + } + + getInnerHeight() { + return 15; + } + private setColor(color: number) { const state = this.state; state.setColor(color); } } - } \ No newline at end of file diff --git a/sim/visuals/controls/colorWheel.ts b/sim/visuals/controls/colorWheel.ts index 0d20763f..f0ff4adb 100644 --- a/sim/visuals/controls/colorWheel.ts +++ b/sim/visuals/controls/colorWheel.ts @@ -10,7 +10,7 @@ namespace pxsim.visuals { getInnerView(parent: SVGSVGElement) { this.defs = svg.child(this.element, "defs", {}); this.group = svg.elt("g") as SVGGElement; - this.group.setAttribute("transform", `translate(12, ${this.getHeight() / 2 - 15}) scale(2)`) + this.group.setAttribute("transform", `translate(12, 0) scale(2)`) let gc = "gradient-color"; this.colorGradient = svg.linearGradient(this.defs, gc, true); @@ -53,6 +53,14 @@ namespace pxsim.visuals { return this.group; } + getInnerWidth() { + return CONTROL_WIDTH; + } + + getInnerHeight() { + return CONTROL_WIDTH; + } + updateState() { if (!this.visible) { return; diff --git a/sim/visuals/controls/distanceSlider.ts b/sim/visuals/controls/distanceSlider.ts index b6d07ba2..a4542ab6 100644 --- a/sim/visuals/controls/distanceSlider.ts +++ b/sim/visuals/controls/distanceSlider.ts @@ -7,7 +7,10 @@ namespace pxsim.visuals { private gradient: SVGLinearGradientElement; private slider: SVGGElement; - private static SLIDER_HANDLE_HEIGHT = 31; + private reporter: SVGTextElement; + + private static SLIDER_HANDLE_HEIGHT = 26; + private static SLIDER_SIDE_PADDING = 6; getInnerView(parent: SVGSVGElement, globalDefs: SVGDefsElement) { let gid = "gradient-slider-" + this.getId(); @@ -23,15 +26,19 @@ namespace pxsim.visuals { this.group = svg.elt("g") as SVGGElement; - const sliderGroup = pxsim.svg.child(this.group, "g"); - sliderGroup.setAttribute("transform", `translate(0, ${10 + this.getTopPadding()})`) + const reporterGroup = pxsim.svg.child(this.group, "g"); + reporterGroup.setAttribute("transform", `translate(31, 42)`); + this.reporter = pxsim.svg.child(reporterGroup, "text", { 'x': 0, 'y': '0', 'class': 'sim-text number large inverted' }) as SVGTextElement; - const rect = pxsim.svg.child(sliderGroup, "rect", { 'x': this.getLeftPadding(), 'y': 2, 'width': this.getWidth() - this.getLeftPadding() * 2, 'height': this.getContentHeight(), 'style': `fill: url(#${gid})` }); + const sliderGroup = pxsim.svg.child(this.group, "g"); + sliderGroup.setAttribute("transform", `translate(${this.getWidth() / 2 - this.getSliderWidth() / 2}, ${this.getReporterHeight()})`) + + const rect = pxsim.svg.child(sliderGroup, "rect", { 'x': DistanceSliderControl.SLIDER_SIDE_PADDING, 'y': 2, 'width': this.getSliderWidth() - DistanceSliderControl.SLIDER_SIDE_PADDING * 2, 'height': this.getSliderHeight(), 'style': `fill: url(#${gid})` }); this.slider = pxsim.svg.child(sliderGroup, "g", { "transform": "translate(0,0)" }) as SVGGElement; const sliderInner = pxsim.svg.child(this.slider, "g"); - pxsim.svg.child(sliderInner, "rect", { 'width': this.getWidth(), 'height': DistanceSliderControl.SLIDER_HANDLE_HEIGHT, 'rx': '2', 'ry': '2', 'style': 'fill: #f12a21' }); - pxsim.svg.child(sliderInner, "rect", { 'x': '0.5', 'y': '0.5', 'width': this.getWidth() - 1, 'height': DistanceSliderControl.SLIDER_HANDLE_HEIGHT - 1, 'rx': '1.5', 'ry': '1.5', 'style': 'fill: none;stroke: #b32e29' }); + pxsim.svg.child(sliderInner, "rect", { 'width': this.getSliderWidth(), 'height': DistanceSliderControl.SLIDER_HANDLE_HEIGHT, 'rx': '2', 'ry': '2', 'style': 'fill: #f12a21' }); + pxsim.svg.child(sliderInner, "rect", { 'x': '0.5', 'y': '0.5', 'width': this.getSliderWidth() - 1, 'height': DistanceSliderControl.SLIDER_HANDLE_HEIGHT - 1, 'rx': '1.5', 'ry': '1.5', 'style': 'fill: none;stroke: #b32e29' }); const dragSurface = svg.child(this.group, "rect", { x: 0, @@ -64,16 +71,24 @@ namespace pxsim.visuals { return this.group; } - private getLeftPadding() { - return this.getInnerWidth() * 0.12; + getInnerHeight() { + return 192; } - private getTopPadding() { - return this.getInnerHeight() / 4; + getInnerWidth() { + return 111; } - private getContentHeight() { - return this.getInnerHeight() * 0.6; + private getReporterHeight() { + return 50; + } + + private getSliderHeight() { + return 110; + } + + private getSliderWidth() { + return 62; } updateState() { @@ -82,15 +97,17 @@ namespace pxsim.visuals { } const node = this.state; const percentage = node.getValue() / 10; /* convert back to cm */ - const y = this.getContentHeight() * percentage / this.getMax(); + const y = this.getSliderHeight() * percentage / this.getMax(); this.slider.setAttribute("transform", `translate(0, ${y - DistanceSliderControl.SLIDER_HANDLE_HEIGHT / 2})`); + // Update reporter text + this.reporter.textContent = `${parseFloat((percentage).toString()).toFixed(0)}`; } private updateSliderValue(pt: SVGPoint, parent: SVGSVGElement, ev: MouseEvent) { let cur = svg.cursorPoint(pt, parent, ev); - const height = this.getContentHeight(); //DistanceSliderControl.SLIDER_HEIGHT; + const height = this.getSliderHeight(); const bBox = this.content.getBoundingClientRect(); - let t = Math.max(0, Math.min(1, (this.getTopPadding() + height + bBox.top / this.scaleFactor - cur.y / this.scaleFactor) / height)) + let t = Math.max(0, Math.min(1, (DistanceSliderControl.SLIDER_HANDLE_HEIGHT + height + bBox.top / this.scaleFactor - cur.y / this.scaleFactor) / height)) const state = this.state; state.setDistance((1 - t) * (this.getMax()));