Update to make it more like a crank
This commit is contained in:
		@@ -96,8 +96,16 @@ namespace pxsim {
 | 
			
		||||
            this.started = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        setSpeedAsInput(speed: number) {
 | 
			
		||||
            this.speed = speed;
 | 
			
		||||
        manualMotorDown() {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        manualMotorMove(angle: number) {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        manualMotorUp() {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        updateState(elapsed: number) {
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@ namespace pxsim.visuals {
 | 
			
		||||
 | 
			
		||||
        private reporter: SVGTextElement;
 | 
			
		||||
 | 
			
		||||
        private circleBar: SVGCircleElement;
 | 
			
		||||
        // private circleBar: SVGCircleElement;
 | 
			
		||||
        private dial: SVGGElement;
 | 
			
		||||
 | 
			
		||||
        private static SLIDER_RADIUS = 100;
 | 
			
		||||
@@ -18,7 +18,6 @@ namespace pxsim.visuals {
 | 
			
		||||
 | 
			
		||||
        getInnerView(parent: SVGSVGElement, globalDefs: SVGDefsElement) {
 | 
			
		||||
            this.group = svg.elt("g") as SVGGElement;
 | 
			
		||||
            const sliderHeight = 250;
 | 
			
		||||
 | 
			
		||||
            const slider = pxsim.svg.child(this.group, 'g', { 'transform': 'translate(25,25)' })
 | 
			
		||||
            const outerCircle = pxsim.svg.child(slider, "circle", {
 | 
			
		||||
@@ -26,14 +25,9 @@ namespace pxsim.visuals {
 | 
			
		||||
                'cx': 100, 'cy': 100, 'r': '90', 'style': `fill:transparent;`,
 | 
			
		||||
                'stroke': '#a8aaa8', 'stroke-width': '1rem'
 | 
			
		||||
            }) as SVGCircleElement;
 | 
			
		||||
            this.circleBar = pxsim.svg.child(slider, "circle", {
 | 
			
		||||
                'stroke-dasharray': '565.48', 'stroke-dashoffset': '0',
 | 
			
		||||
                'cx': 100, 'cy': 100, 'r': '90', 'style': `fill:transparent;`,
 | 
			
		||||
                'stroke': '#f12a21', 'stroke-width': '1rem', 'transform': 'rotate(-90 100 100)'
 | 
			
		||||
            }) as SVGCircleElement;
 | 
			
		||||
 | 
			
		||||
            this.reporter = pxsim.svg.child(this.group, "text", {
 | 
			
		||||
                'x': this.getInnerWidth() / 2, 'y': sliderHeight / 2,
 | 
			
		||||
                'x': this.getInnerWidth() / 2, 'y': this.getInnerHeight() / 2,
 | 
			
		||||
                'text-anchor': 'middle', 'alignment-baseline': 'middle',
 | 
			
		||||
                'style': 'font-size: 50px',
 | 
			
		||||
                'class': 'sim-text inverted number'
 | 
			
		||||
@@ -44,64 +38,7 @@ namespace pxsim.visuals {
 | 
			
		||||
            pxsim.svg.child(handleInner, "circle", { 'cx': 0, 'cy': 0, 'r': 30, 'style': 'fill: #f12a21;' });
 | 
			
		||||
            pxsim.svg.child(handleInner, "circle", { 'cx': 0, 'cy': 0, 'r': 29.5, 'style': 'fill: none;stroke: #b32e29' });
 | 
			
		||||
 | 
			
		||||
            // Add move buttons
 | 
			
		||||
            const leftMoveG = pxsim.svg.child(this.group, 'g', {'class': 'sim-motor-btn', 'transform': `translate(${1}, ${sliderHeight - 2}) scale(2.5)`});
 | 
			
		||||
            const leftMove = pxsim.svg.child(leftMoveG, 'circle', {
 | 
			
		||||
                'cx': 16, 'cy': 16, 'r': 16, 'style': 'fill: #a8aaa8', 'class': 'btn'
 | 
			
		||||
            });
 | 
			
		||||
            const semiCircleLeft = pxsim.svg.child(leftMoveG, 'g');
 | 
			
		||||
            pxsim.svg.child(semiCircleLeft, 'circle', { 'cx': 16, 'cy': 16, 'r': 9, 'style': 'fill: none'});
 | 
			
		||||
            pxsim.svg.child(semiCircleLeft, 'circle', { 'cx': 16, 'cy': 16, 'r': 8, 'style': 'fill: none;stroke: #fff;stroke-width: 2px'});
 | 
			
		||||
            pxsim.svg.child(leftMoveG, 'path', {'d': 'M501,382.33l-6.62-2.28-2.28,6.62,6.62,2.28Z', 'transform': 'translate(-472 -368)', 'fill': '#a8aaa8'});
 | 
			
		||||
            pxsim.svg.child(leftMoveG, 'path', {'d': 'M497.93,377.62c-.57,2.09-1.14,4.11-1.71,6.18l-6.06-2Z', 'transform': 'translate(-472 -368)', 'fill': '#fff'});
 | 
			
		||||
 | 
			
		||||
            let leftMoveFrame: number;
 | 
			
		||||
            touchEvents(leftMove, ev => {
 | 
			
		||||
                // move
 | 
			
		||||
            }, ev => {
 | 
			
		||||
                if (leftMoveFrame) cancelAnimationFrame(leftMoveFrame);
 | 
			
		||||
                let setSpeed = () => {
 | 
			
		||||
                    leftMoveFrame = requestAnimationFrame(() => {
 | 
			
		||||
                        this.state.setSpeedAsInput(-1 * this.internalSpeed);
 | 
			
		||||
                        setSpeed();
 | 
			
		||||
                    })
 | 
			
		||||
                }
 | 
			
		||||
                setSpeed();
 | 
			
		||||
            }, () => {
 | 
			
		||||
                if (leftMoveFrame) cancelAnimationFrame(leftMoveFrame);
 | 
			
		||||
            }, () => {
 | 
			
		||||
                if (leftMoveFrame) cancelAnimationFrame(leftMoveFrame);
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
            const rightMoveG = pxsim.svg.child(this.group, 'g', {'class': 'sim-motor-btn', 'transform': `translate(${42}, ${sliderHeight - 2}) scale(2.5)`});
 | 
			
		||||
            const rightMove = pxsim.svg.child(rightMoveG, 'circle', {
 | 
			
		||||
                'cx': 67, 'cy': 16, 'r': 16, 'style': 'fill: #a8aaa8', 'class': 'btn'
 | 
			
		||||
            });
 | 
			
		||||
            const semiCircleRight = pxsim.svg.child(rightMoveG, 'g');
 | 
			
		||||
            pxsim.svg.child(semiCircleRight, 'circle', { 'cx': 67, 'cy': 17, 'r': 9, 'style': 'fill: none'});
 | 
			
		||||
            pxsim.svg.child(semiCircleRight, 'circle', { 'cx': 67, 'cy': 17, 'r': 8, 'style': 'fill: none;stroke: #fff;stroke-width: 2px'});
 | 
			
		||||
            pxsim.svg.child(rightMoveG, 'rect', {'x': 527, 'y': 380, 'width': 7, 'height': 7, 'transform': 'translate(-567.95 -174.39) rotate(-19)', 'style': 'fill: #a8aaa8'});
 | 
			
		||||
            pxsim.svg.child(rightMoveG, 'path', {'d': 'M529.08,376.63c.57,2.09,1.14,4.11,1.7,6.18l6.06-2Z', 'transform': 'translate(-472 -368)', 'fill': '#fff'});
 | 
			
		||||
 | 
			
		||||
            let rightMoveFrame: number;
 | 
			
		||||
            touchEvents(rightMove, ev => {
 | 
			
		||||
                // move
 | 
			
		||||
            }, ev => {
 | 
			
		||||
                if (rightMoveFrame) cancelAnimationFrame(rightMoveFrame);
 | 
			
		||||
                let setSpeed = () => {
 | 
			
		||||
                    rightMoveFrame = requestAnimationFrame(() => {
 | 
			
		||||
                        this.state.setSpeedAsInput(this.internalSpeed);
 | 
			
		||||
                        setSpeed();
 | 
			
		||||
                    })
 | 
			
		||||
                }
 | 
			
		||||
                setSpeed();
 | 
			
		||||
            }, () => {
 | 
			
		||||
                if (rightMoveFrame) cancelAnimationFrame(rightMoveFrame);
 | 
			
		||||
            }, () => {
 | 
			
		||||
                if (rightMoveFrame) cancelAnimationFrame(rightMoveFrame);
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
            this.updateInternalSpeed();
 | 
			
		||||
            this.updateDial();
 | 
			
		||||
 | 
			
		||||
            let pt = parent.createSVGPoint();
 | 
			
		||||
            let captured = false;
 | 
			
		||||
@@ -110,7 +47,7 @@ namespace pxsim.visuals {
 | 
			
		||||
                x: 0,
 | 
			
		||||
                y: 0,
 | 
			
		||||
                width: this.getInnerWidth(),
 | 
			
		||||
                height: sliderHeight,
 | 
			
		||||
                height: this.getInnerHeight(),
 | 
			
		||||
                opacity: 0,
 | 
			
		||||
                cursor: '-webkit-grab'
 | 
			
		||||
            })
 | 
			
		||||
@@ -119,19 +56,20 @@ namespace pxsim.visuals {
 | 
			
		||||
                if (captured && (ev as MouseEvent).clientY != undefined) {
 | 
			
		||||
                    ev.preventDefault();
 | 
			
		||||
                    this.updateSliderValue(pt, parent, ev as MouseEvent);
 | 
			
		||||
                    this.handleSliderDown();
 | 
			
		||||
                }
 | 
			
		||||
            }, ev => {
 | 
			
		||||
                captured = true;
 | 
			
		||||
                if ((ev as MouseEvent).clientY != undefined) {
 | 
			
		||||
                    this.dial.setAttribute('cursor', '-webkit-grabbing');
 | 
			
		||||
                    this.updateSliderValue(pt, parent, ev as MouseEvent);
 | 
			
		||||
                    this.handleSliderMove();
 | 
			
		||||
                }
 | 
			
		||||
            }, () => {
 | 
			
		||||
                captured = false;
 | 
			
		||||
                this.dial.setAttribute('cursor', '-webkit-grab');
 | 
			
		||||
                this.handleSliderUp();
 | 
			
		||||
            }, () => {
 | 
			
		||||
                captured = false;
 | 
			
		||||
                this.dial.setAttribute('cursor', '-webkit-grab');
 | 
			
		||||
                this.handleSliderUp();
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
            return this.group;
 | 
			
		||||
@@ -142,7 +80,7 @@ namespace pxsim.visuals {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        getInnerHeight() {
 | 
			
		||||
            return 330;
 | 
			
		||||
            return 250;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private lastPosition: number;
 | 
			
		||||
@@ -169,24 +107,35 @@ namespace pxsim.visuals {
 | 
			
		||||
            const value = Math.abs(Math.ceil((deg % 360) / 360 * this.getMax()));
 | 
			
		||||
 | 
			
		||||
            this.internalSpeed = value;
 | 
			
		||||
            this.updateInternalSpeed();
 | 
			
		||||
            this.updateDial();
 | 
			
		||||
 | 
			
		||||
            this.prevVal = deg;
 | 
			
		||||
            this.lastPosition = cur.x;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private updateInternalSpeed() {
 | 
			
		||||
        private handleSliderDown() {
 | 
			
		||||
            const state = this.state;
 | 
			
		||||
            state.manualMotorDown();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private handleSliderMove() {
 | 
			
		||||
            this.dial.setAttribute('cursor', '-webkit-grabbing');
 | 
			
		||||
            const state = this.state;
 | 
			
		||||
            state.manualMotorMove(this.internalSpeed);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private handleSliderUp() {
 | 
			
		||||
            this.dial.setAttribute('cursor', '-webkit-grab');
 | 
			
		||||
            const state = this.state;
 | 
			
		||||
            state.manualMotorUp();
 | 
			
		||||
 | 
			
		||||
            this.internalSpeed = 0;
 | 
			
		||||
            this.updateDial();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private updateDial() {
 | 
			
		||||
            let speed = this.internalSpeed;
 | 
			
		||||
 | 
			
		||||
            // Update speed on circle bar
 | 
			
		||||
            let c = Math.PI * (90 * 2);
 | 
			
		||||
            speed = Math.abs(speed);
 | 
			
		||||
            let pct = ((100 - speed) / 100) * c;
 | 
			
		||||
            this.circleBar.setAttribute('stroke-dashoffset', `${pct}`);
 | 
			
		||||
 | 
			
		||||
            // Update reporter text
 | 
			
		||||
            this.reporter.textContent = `${speed}`;
 | 
			
		||||
 | 
			
		||||
            // Update dial position
 | 
			
		||||
            const deg = speed / this.getMax() * 360; // degrees
 | 
			
		||||
            const radius = MotorSliderControl.SLIDER_RADIUS;
 | 
			
		||||
@@ -196,6 +145,17 @@ namespace pxsim.visuals {
 | 
			
		||||
            this.dial.setAttribute('transform', `translate(${x}, ${y})`);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        updateState() {
 | 
			
		||||
            if (!this.visible) {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            const node = this.state;
 | 
			
		||||
            const speed = node.getSpeed();
 | 
			
		||||
 | 
			
		||||
            // Update reporter
 | 
			
		||||
            this.reporter.textContent = `${speed}`;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private getMin() {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user