Update to make it more like a crank

This commit is contained in:
Sam El-Husseini 2018-01-10 13:47:39 -08:00
parent 10cd39a4ec
commit 8357372fb5
2 changed files with 52 additions and 84 deletions

View File

@ -96,8 +96,16 @@ namespace pxsim {
this.started = true; this.started = true;
} }
setSpeedAsInput(speed: number) { manualMotorDown() {
this.speed = speed;
}
manualMotorMove(angle: number) {
}
manualMotorUp() {
} }
updateState(elapsed: number) { updateState(elapsed: number) {

View File

@ -9,7 +9,7 @@ namespace pxsim.visuals {
private reporter: SVGTextElement; private reporter: SVGTextElement;
private circleBar: SVGCircleElement; // private circleBar: SVGCircleElement;
private dial: SVGGElement; private dial: SVGGElement;
private static SLIDER_RADIUS = 100; private static SLIDER_RADIUS = 100;
@ -18,7 +18,6 @@ namespace pxsim.visuals {
getInnerView(parent: SVGSVGElement, globalDefs: SVGDefsElement) { getInnerView(parent: SVGSVGElement, globalDefs: SVGDefsElement) {
this.group = svg.elt("g") as SVGGElement; this.group = svg.elt("g") as SVGGElement;
const sliderHeight = 250;
const slider = pxsim.svg.child(this.group, 'g', { 'transform': 'translate(25,25)' }) const slider = pxsim.svg.child(this.group, 'g', { 'transform': 'translate(25,25)' })
const outerCircle = pxsim.svg.child(slider, "circle", { const outerCircle = pxsim.svg.child(slider, "circle", {
@ -26,14 +25,9 @@ namespace pxsim.visuals {
'cx': 100, 'cy': 100, 'r': '90', 'style': `fill:transparent;`, 'cx': 100, 'cy': 100, 'r': '90', 'style': `fill:transparent;`,
'stroke': '#a8aaa8', 'stroke-width': '1rem' 'stroke': '#a8aaa8', 'stroke-width': '1rem'
}) as SVGCircleElement; }) 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", { 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', 'text-anchor': 'middle', 'alignment-baseline': 'middle',
'style': 'font-size: 50px', 'style': 'font-size: 50px',
'class': 'sim-text inverted number' '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': 30, 'style': 'fill: #f12a21;' });
pxsim.svg.child(handleInner, "circle", { 'cx': 0, 'cy': 0, 'r': 29.5, 'style': 'fill: none;stroke: #b32e29' }); pxsim.svg.child(handleInner, "circle", { 'cx': 0, 'cy': 0, 'r': 29.5, 'style': 'fill: none;stroke: #b32e29' });
// Add move buttons this.updateDial();
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();
let pt = parent.createSVGPoint(); let pt = parent.createSVGPoint();
let captured = false; let captured = false;
@ -110,7 +47,7 @@ namespace pxsim.visuals {
x: 0, x: 0,
y: 0, y: 0,
width: this.getInnerWidth(), width: this.getInnerWidth(),
height: sliderHeight, height: this.getInnerHeight(),
opacity: 0, opacity: 0,
cursor: '-webkit-grab' cursor: '-webkit-grab'
}) })
@ -119,19 +56,20 @@ namespace pxsim.visuals {
if (captured && (ev as MouseEvent).clientY != undefined) { if (captured && (ev as MouseEvent).clientY != undefined) {
ev.preventDefault(); ev.preventDefault();
this.updateSliderValue(pt, parent, ev as MouseEvent); this.updateSliderValue(pt, parent, ev as MouseEvent);
this.handleSliderDown();
} }
}, ev => { }, ev => {
captured = true; captured = true;
if ((ev as MouseEvent).clientY != undefined) { if ((ev as MouseEvent).clientY != undefined) {
this.dial.setAttribute('cursor', '-webkit-grabbing');
this.updateSliderValue(pt, parent, ev as MouseEvent); this.updateSliderValue(pt, parent, ev as MouseEvent);
this.handleSliderMove();
} }
}, () => { }, () => {
captured = false; captured = false;
this.dial.setAttribute('cursor', '-webkit-grab'); this.handleSliderUp();
}, () => { }, () => {
captured = false; captured = false;
this.dial.setAttribute('cursor', '-webkit-grab'); this.handleSliderUp();
}) })
return this.group; return this.group;
@ -142,7 +80,7 @@ namespace pxsim.visuals {
} }
getInnerHeight() { getInnerHeight() {
return 330; return 250;
} }
private lastPosition: number; private lastPosition: number;
@ -169,24 +107,35 @@ namespace pxsim.visuals {
const value = Math.abs(Math.ceil((deg % 360) / 360 * this.getMax())); const value = Math.abs(Math.ceil((deg % 360) / 360 * this.getMax()));
this.internalSpeed = value; this.internalSpeed = value;
this.updateInternalSpeed(); this.updateDial();
this.prevVal = deg; this.prevVal = deg;
this.lastPosition = cur.x; 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; 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 // Update dial position
const deg = speed / this.getMax() * 360; // degrees const deg = speed / this.getMax() * 360; // degrees
const radius = MotorSliderControl.SLIDER_RADIUS; const radius = MotorSliderControl.SLIDER_RADIUS;
@ -196,6 +145,17 @@ namespace pxsim.visuals {
this.dial.setAttribute('transform', `translate(${x}, ${y})`); 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() { private getMin() {
return 0; return 0;
} }