diff --git a/sim/visuals/controls/colorWheel.ts b/sim/visuals/controls/colorWheel.ts index f0ff4adb..26bd5962 100644 --- a/sim/visuals/controls/colorWheel.ts +++ b/sim/visuals/controls/colorWheel.ts @@ -1,64 +1,33 @@ - - namespace pxsim.visuals { export class ColorWheelControl extends ControlView { private group: SVGGElement; private colorGradient: SVGLinearGradientElement; - private defs: SVGDefsElement; - - getInnerView(parent: SVGSVGElement) { - this.defs = svg.child(this.element, "defs", {}); - this.group = svg.elt("g") as SVGGElement; - this.group.setAttribute("transform", `translate(12, 0) scale(2)`) - - let gc = "gradient-color"; - this.colorGradient = svg.linearGradient(this.defs, gc, true); - svg.setGradientValue(this.colorGradient, "50%"); - svg.setGradientColors(this.colorGradient, "black", "white"); - - const circle = pxsim.svg.child(this.group, "g"); - const innerCircle = pxsim.svg.child(circle, "circle", - {cursor: '-webkit-grab', - fill: `url(#${gc})`, - r: 17, - cx: 13, - cy: 20, - stroke: 'black', - 'stroke-width': 2 - }); - - let pt = parent.createSVGPoint(); - let captured = false; - touchEvents(circle, - ev => { - if (captured && (ev as MouseEvent).clientX) { - ev.preventDefault(); - this.setColor(pt, parent, ev as MouseEvent); - } - }, - ev => { - captured = true; - if ((ev as MouseEvent).clientX) { - this.setColor(pt, parent, ev as MouseEvent); - } - }, - ev => { - captured = false; - }, - ev => { - captured = false; - } - ) - return this.group; - } + private reporter: SVGTextElement; + private rect: SVGElement; getInnerWidth() { - return CONTROL_WIDTH; + return 111; } getInnerHeight() { - return CONTROL_WIDTH; + return 192; + } + + private getReporterHeight() { + return 58; + } + + private getSliderWidth() { + return 62; + } + + private getSliderHeight() { + return 111; + } + + private getMax() { + return 100; } updateState() { @@ -67,16 +36,68 @@ namespace pxsim.visuals { } const node = this.state; const percentage = node.getValue(); - svg.setGradientValue(this.colorGradient, percentage + "%"); + const inversePercentage = this.getMax() - percentage; + svg.setGradientValue(this.colorGradient, inversePercentage + "%"); + this.reporter.textContent = `${parseFloat((percentage).toString()).toFixed(0)}`; } - private setColor(pt: SVGPoint, parent: SVGSVGElement, ev: MouseEvent) { - const width = CONTROL_WIDTH; + updateColorLevel(pt: SVGPoint, parent: SVGSVGElement, ev: MouseEvent) { let cur = svg.cursorPoint(pt, parent, ev); - let t = Math.max(0, Math.min(1, (width + this.left / this.scaleFactor - cur.x / this.scaleFactor) / width)); + const bBox = this.rect.getBoundingClientRect(); + const height = bBox.height; + let t = Math.max(0, Math.min(1, (height + bBox.top / this.scaleFactor - cur.y / this.scaleFactor) / height)); const state = this.state; - state.setColor((1-t)*100); + state.setColor(t * this.getMax()); + } + + getInnerView(parent: SVGSVGElement, globalDefs: SVGDefsElement) { + this.group = svg.elt("g") as SVGGElement; + + let gc = "gradient-color"; + this.colorGradient = svg.linearGradient(globalDefs, gc, false); + svg.setGradientValue(this.colorGradient, "50%"); + svg.setGradientColors(this.colorGradient, "black", "yellow"); + + const reporterGroup = pxsim.svg.child(this.group, "g"); + reporterGroup.setAttribute("transform", `translate(${this.getWidth() / 2}, 50)`); + this.reporter = pxsim.svg.child(reporterGroup, "text", { 'text-anchor': 'middle', 'x': 0, 'y': '0', 'class': 'sim-text number large inverted' }) as SVGTextElement; + + 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": 0, + "y": 0, + "width": this.getSliderWidth(), + "height": this.getSliderHeight(), + "style": `fill: url(#${gc})` + } + ) + this.rect = rect; + + let pt = parent.createSVGPoint(); + let captured = false; + touchEvents(rect, ev => { + if (captured && (ev as MouseEvent).clientY) { + ev.preventDefault(); + this.updateColorLevel(pt, parent, ev as MouseEvent); + } + }, ev => { + captured = true; + if ((ev as MouseEvent).clientY) { + rect.setAttribute('cursor', '-webkit-grabbing'); + this.updateColorLevel(pt, parent, ev as MouseEvent); + } + }, () => { + captured = false; + rect.setAttribute('cursor', '-webkit-grab'); + }, () => { + captured = false; + rect.setAttribute('cursor', '-webkit-grab'); + }) + + return this.group; } } - } \ No newline at end of file