2017-12-18 22:04:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
namespace pxsim.visuals {
|
|
|
|
|
|
|
|
export class DistanceSliderControl extends ControlView<UltrasonicSensorNode> {
|
|
|
|
private group: SVGGElement;
|
|
|
|
private gradient: SVGLinearGradientElement;
|
|
|
|
private slider: SVGGElement;
|
|
|
|
|
2017-12-28 01:30:42 +01:00
|
|
|
private reporter: SVGTextElement;
|
|
|
|
|
|
|
|
private static SLIDER_HANDLE_HEIGHT = 26;
|
|
|
|
private static SLIDER_SIDE_PADDING = 6;
|
2017-12-18 22:04:17 +01:00
|
|
|
|
|
|
|
getInnerView(parent: SVGSVGElement, globalDefs: SVGDefsElement) {
|
|
|
|
let gid = "gradient-slider-" + this.getId();
|
|
|
|
this.group = svg.elt("g") as SVGGElement;
|
|
|
|
this.gradient = createGradient(gid, this.getGradientDefinition());
|
2017-12-27 08:23:26 +01:00
|
|
|
this.gradient.setAttribute('x1', '0%');
|
|
|
|
this.gradient.setAttribute('y1', '0%');
|
|
|
|
this.gradient.setAttribute('x2', '0%');
|
|
|
|
this.gradient.setAttribute('y2', '100%');
|
|
|
|
// this.gradient.setAttribute('gradientTransform', 'matrix(50, 0, 0, -110, 21949.45, 46137.67)');
|
|
|
|
// this.gradient.setAttribute('gradientUnits', 'userSpaceOnUse');
|
2017-12-18 22:04:17 +01:00
|
|
|
globalDefs.appendChild(this.gradient);
|
|
|
|
|
|
|
|
this.group = svg.elt("g") as SVGGElement;
|
|
|
|
|
2017-12-28 01:30:42 +01:00
|
|
|
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;
|
|
|
|
|
2017-12-18 22:04:17 +01:00
|
|
|
const sliderGroup = pxsim.svg.child(this.group, "g");
|
2017-12-28 01:30:42 +01:00
|
|
|
sliderGroup.setAttribute("transform", `translate(${this.getWidth() / 2 - this.getSliderWidth() / 2}, ${this.getReporterHeight()})`)
|
2017-12-18 22:04:17 +01:00
|
|
|
|
2017-12-28 01:30:42 +01:00
|
|
|
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})` });
|
2017-12-18 22:04:17 +01:00
|
|
|
|
|
|
|
this.slider = pxsim.svg.child(sliderGroup, "g", { "transform": "translate(0,0)" }) as SVGGElement;
|
|
|
|
const sliderInner = pxsim.svg.child(this.slider, "g");
|
2017-12-28 01:30:42 +01:00
|
|
|
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' });
|
2017-12-18 22:04:17 +01:00
|
|
|
|
|
|
|
const dragSurface = svg.child(this.group, "rect", {
|
|
|
|
x: 0,
|
|
|
|
y: 0,
|
|
|
|
width: this.getInnerWidth(),
|
|
|
|
height: this.getInnerHeight(),
|
|
|
|
opacity: 0,
|
|
|
|
cursor: '-webkit-grab'
|
|
|
|
})
|
|
|
|
|
|
|
|
let pt = parent.createSVGPoint();
|
|
|
|
let captured = false;
|
|
|
|
|
|
|
|
touchEvents(dragSurface, ev => {
|
|
|
|
if (captured && (ev as MouseEvent).clientY != undefined) {
|
|
|
|
ev.preventDefault();
|
|
|
|
this.updateSliderValue(pt, parent, ev as MouseEvent);
|
|
|
|
}
|
|
|
|
}, ev => {
|
|
|
|
captured = true;
|
|
|
|
if ((ev as MouseEvent).clientY != undefined) {
|
|
|
|
this.updateSliderValue(pt, parent, ev as MouseEvent);
|
|
|
|
}
|
|
|
|
}, () => {
|
|
|
|
captured = false;
|
|
|
|
}, () => {
|
|
|
|
captured = false;
|
|
|
|
})
|
|
|
|
|
|
|
|
return this.group;
|
|
|
|
}
|
|
|
|
|
2017-12-28 01:30:42 +01:00
|
|
|
getInnerHeight() {
|
|
|
|
return 192;
|
|
|
|
}
|
|
|
|
|
|
|
|
getInnerWidth() {
|
|
|
|
return 111;
|
|
|
|
}
|
|
|
|
|
|
|
|
private getReporterHeight() {
|
|
|
|
return 50;
|
2017-12-18 22:04:17 +01:00
|
|
|
}
|
|
|
|
|
2017-12-28 01:30:42 +01:00
|
|
|
private getSliderHeight() {
|
|
|
|
return 110;
|
2017-12-18 22:04:17 +01:00
|
|
|
}
|
|
|
|
|
2017-12-28 01:30:42 +01:00
|
|
|
private getSliderWidth() {
|
|
|
|
return 62;
|
2017-12-18 22:04:17 +01:00
|
|
|
}
|
|
|
|
|
2017-12-19 23:55:43 +01:00
|
|
|
updateState() {
|
2017-12-27 08:23:26 +01:00
|
|
|
if (!this.visible) {
|
2017-12-18 22:04:17 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
const node = this.state;
|
2017-12-19 05:30:56 +01:00
|
|
|
const percentage = node.getValue() / 10; /* convert back to cm */
|
2017-12-28 01:30:42 +01:00
|
|
|
const y = this.getSliderHeight() * percentage / this.getMax();
|
2017-12-18 22:04:17 +01:00
|
|
|
this.slider.setAttribute("transform", `translate(0, ${y - DistanceSliderControl.SLIDER_HANDLE_HEIGHT / 2})`);
|
2017-12-28 01:30:42 +01:00
|
|
|
// Update reporter text
|
|
|
|
this.reporter.textContent = `${parseFloat((percentage).toString()).toFixed(0)}`;
|
2017-12-18 22:04:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private updateSliderValue(pt: SVGPoint, parent: SVGSVGElement, ev: MouseEvent) {
|
|
|
|
let cur = svg.cursorPoint(pt, parent, ev);
|
2017-12-28 01:30:42 +01:00
|
|
|
const height = this.getSliderHeight();
|
2017-12-22 23:00:23 +01:00
|
|
|
const bBox = this.content.getBoundingClientRect();
|
2017-12-28 01:30:42 +01:00
|
|
|
let t = Math.max(0, Math.min(1, (DistanceSliderControl.SLIDER_HANDLE_HEIGHT + height + bBox.top / this.scaleFactor - cur.y / this.scaleFactor) / height))
|
2017-12-18 22:04:17 +01:00
|
|
|
|
|
|
|
const state = this.state;
|
2017-12-19 05:30:56 +01:00
|
|
|
state.setDistance((1 - t) * (this.getMax()));
|
|
|
|
}
|
|
|
|
|
|
|
|
private getMin() {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
private getMax() {
|
|
|
|
return 250; //cm
|
2017-12-18 22:04:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private getGradientDefinition(): LinearGradientDefinition {
|
|
|
|
return {
|
|
|
|
stops: [
|
|
|
|
{ offset: 0, color: '#626262' },
|
2017-12-27 08:23:26 +01:00
|
|
|
{ offset: 100, color: "#ddd" }
|
2017-12-18 22:04:17 +01:00
|
|
|
]
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|