@visactor/vrender-components
Version:
components library for dp visualization
204 lines (198 loc) • 11.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: !0
}), exports.ScrollBar = void 0;
const vrender_core_1 = require("@visactor/vrender-core"), vutils_1 = require("@visactor/vutils"), base_1 = require("../core/base"), register_1 = require("./register"), constant_1 = require("../constant"), event_1 = require("../util/event"), delayMap = {
debounce: vutils_1.debounce,
throttle: vutils_1.throttle
};
(0, register_1.loadScrollbarComponent)();
class ScrollBar extends base_1.AbstractComponent {
constructor(attributes, options) {
super((null == options ? void 0 : options.skipDefault) ? attributes : (0, vutils_1.merge)({}, ScrollBar.defaultAttributes, attributes)),
this.name = "scrollbar", this._handleTouchMove = e => {
(0, vutils_1.isValid)(this._prePos) && e.preventDefault();
}, this._onRailPointerDown = e => {
const {viewX: viewX, viewY: viewY} = e, {direction: direction, width: width, height: height, range: range} = this.attribute, sliderSize = this._sliderSize, [min, max] = this._getScrollRange();
let currentScrollValue;
if ("vertical" === direction) {
const relativeY = viewY - this._viewPosition.y, currentYPos = (0, vutils_1.clamp)(relativeY - sliderSize / 2, min, max);
currentScrollValue = relativeY / height, this._slider.setAttribute("y", currentYPos, !0);
} else {
const relativeX = viewX - this._viewPosition.x, currentXPos = (0, vutils_1.clamp)(relativeX - sliderSize / 2, min, max);
currentScrollValue = relativeX / width, this._slider.setAttribute("x", currentXPos, !0);
}
this.setScrollRange([ currentScrollValue - (range[1] - range[0]) / 2, currentScrollValue + (range[1] - range[0]) / 2 ], !1),
this.stage && !this.stage.autoRender && this.stage.renderNextFrame();
}, this._onSliderPointerDown = e => {
this._clearDragEvents();
const {stopSliderDownPropagation: stopSliderDownPropagation = !0} = this.attribute;
stopSliderDownPropagation && e.stopPropagation();
const {direction: direction} = this.attribute, {x: x, y: y} = this.stage.eventPointTransform(e);
this._prePos = "horizontal" === direction ? x : y, this._dispatchEvent(constant_1.SCROLLBAR_START_EVENT, {
pos: this._prePos,
event: e
});
const triggers = (0, event_1.getEndTriggersOfDrag)(), obj = "browser" === vrender_core_1.vglobal.env ? vrender_core_1.vglobal : this.stage;
obj.addEventListener("pointermove", this._onSliderPointerMoveWithDelay, {
capture: !0
}), triggers.forEach((trigger => {
obj.addEventListener(trigger, this._onSliderPointerUp);
}));
}, this._computeScrollValue = e => {
const {direction: direction} = this.attribute, {x: x, y: y} = this.stage.eventPointTransform(e);
let currentScrollValue, currentPos, delta = 0;
const {width: width, height: height} = this.getSliderRenderBounds();
return "vertical" === direction ? (currentPos = y, delta = currentPos - this._prePos,
currentScrollValue = delta / height) : (currentPos = x, delta = currentPos - this._prePos,
currentScrollValue = delta / width), [ currentPos, currentScrollValue ];
}, this._onSliderPointerMove = e => {
const {stopSliderMovePropagation: stopSliderMovePropagation = !0} = this.attribute;
stopSliderMovePropagation && e.stopPropagation();
const preScrollRange = this.getScrollRange(), [currentPos, currentScrollValue] = this._computeScrollValue(e);
this.setScrollRange([ preScrollRange[0] + currentScrollValue, preScrollRange[1] + currentScrollValue ], !0),
this._prePos = currentPos;
}, this._onSliderPointerMoveWithDelay = 0 === this.attribute.delayTime ? this._onSliderPointerMove : delayMap[this.attribute.delayType](this._onSliderPointerMove, this.attribute.delayTime),
this._onSliderPointerUp = e => {
const {range: preRange, limitRange: limitRange = [ 0, 1 ]} = this.attribute, preScrollRange = this.getScrollRange(), [currentPos, currentScrollValue] = this._computeScrollValue(e), range = [ preScrollRange[0] + currentScrollValue, preScrollRange[1] + currentScrollValue ];
this._prePos = null, this._dispatchEvent(constant_1.SCROLLBAR_END_EVENT, {
pre: preRange,
value: (0, vutils_1.clampRange)(range, limitRange[0], limitRange[1])
}), this._clearDragEvents();
};
}
setScrollRange(range, render = !0) {
const {direction: direction = "horizontal", limitRange: limitRange = [ 0, 1 ], range: preRange, realTime: realTime = !0} = this.attribute, currScrollRange = (0,
vutils_1.clampRange)(range, limitRange[0], limitRange[1]);
if (render) {
const sliderPos = this._getSliderPos(currScrollRange);
if (this._slider) {
const sliderSize = sliderPos[1] - sliderPos[0];
this._sliderSize = sliderSize, "horizontal" === direction ? this._slider.setAttributes({
x: sliderPos[0],
width: sliderSize
}, !0) : this._slider.setAttributes({
y: sliderPos[0],
height: sliderSize
}, !0), this.stage && !this.stage.autoRender && this.stage.renderNextFrame();
}
}
this.attribute.range = currScrollRange, realTime && this._dispatchEvent(constant_1.SCROLLBAR_EVENT, {
pre: preRange,
value: currScrollRange
});
}
getScrollRange() {
return this.attribute.range;
}
bindEvents() {
if (this.attribute.disableTriggerEvent) return;
const {delayType: delayType = "throttle", delayTime: delayTime = 0} = this.attribute;
this._rail && this._rail.addEventListener("pointerdown", delayMap[delayType](this._onRailPointerDown, delayTime)),
this._slider && this._slider.addEventListener("pointerdown", this._onSliderPointerDown),
("browser" === vrender_core_1.vglobal.env ? vrender_core_1.vglobal : this.stage).addEventListener("touchmove", this._handleTouchMove, {
passive: !1
});
}
render() {
this._reset();
const {direction: direction = "horizontal", width: width, height: height, range: range, limitRange: limitRange = [ 0, 1 ], railStyle: railStyle, sliderStyle: sliderStyle, padding: padding = 2} = this.attribute, group = this.createOrUpdateChild("scrollbar-container", {}, "group"), rail = group.createOrUpdateChild("scrollbar-rail", Object.assign({
x: 0,
y: 0,
width: width,
height: height
}, railStyle), "rect");
this._rail = rail;
const sliderRenderBounds = this.getSliderRenderBounds(), sliderPos = this._getSliderPos((0,
vutils_1.clampRange)(range, limitRange[0], limitRange[1])), sliderSize = sliderPos[1] - sliderPos[0];
let sliderAttribute;
this._sliderSize = sliderSize, sliderAttribute = "horizontal" === direction ? {
x: sliderPos[0],
y: sliderRenderBounds.y1,
width: sliderSize,
height: sliderRenderBounds.height
} : {
x: sliderRenderBounds.x1,
y: sliderPos[0],
width: sliderRenderBounds.width,
height: sliderSize
};
const slider = group.createOrUpdateChild("slider", Object.assign(Object.assign(Object.assign(Object.assign({}, sliderAttribute), {
cornerRadius: this._getDefaultSliderCornerRadius()
}), sliderStyle), {
boundsPadding: (0, vutils_1.normalizePadding)(padding),
pickMode: "imprecise"
}), "rect");
this._slider = slider, this._container = group;
const containerAABBBounds = this._container.AABBBounds;
this._viewPosition = {
x: containerAABBBounds.x1,
y: containerAABBBounds.y1
};
}
getSliderRenderBounds() {
if (this._sliderRenderBounds) return this._sliderRenderBounds;
const {width: width, height: height, padding: padding = 2} = this.attribute, [top, right, bottom, left] = (0,
vutils_1.normalizePadding)(padding), renderBounds = {
x1: left,
y1: top,
x2: width - right,
y2: height - bottom,
width: Math.max(0, width - (left + right)),
height: Math.max(0, height - (top + bottom))
};
return this._sliderRenderBounds = renderBounds, renderBounds;
}
_getDefaultSliderCornerRadius() {
const {direction: direction, round: round} = this.attribute;
if (round) {
const {width: width, height: height} = this.getSliderRenderBounds();
return "horizontal" === direction ? height : width;
}
return 0;
}
_getSliderPos(range) {
const {direction: direction} = this.attribute, {width: width, height: height, x1: x1, y1: y1} = this.getSliderRenderBounds();
return "horizontal" === direction ? [ width * range[0] + x1, width * range[1] + x1 ] : [ height * range[0] + y1, height * range[1] + y1 ];
}
_getScrollRange() {
if (this._sliderLimitRange) return this._sliderLimitRange;
const {limitRange: limitRange = [ 0, 1 ], direction: direction} = this.attribute, [min, max] = (0,
vutils_1.clampRange)(limitRange, 0, 1), {width: width, height: height, x1: x1, y1: y1} = this.getSliderRenderBounds(), sliderSize = this._sliderSize;
return "horizontal" === direction ? (0, vutils_1.clampRange)([ x1 + min * width, x1 + max * width ], x1, width - sliderSize) : (0,
vutils_1.clampRange)([ y1 + min * height, y1 + max * height ], y1, height - sliderSize);
}
_clearDragEvents() {
const triggers = (0, event_1.getEndTriggersOfDrag)(), obj = "browser" === vrender_core_1.vglobal.env ? vrender_core_1.vglobal : this.stage;
obj.removeEventListener("pointermove", this._onSliderPointerMoveWithDelay, {
capture: !0
}), triggers.forEach((trigger => {
obj.removeEventListener(trigger, this._onSliderPointerUp);
}));
}
_reset() {
this._sliderRenderBounds = null, this._sliderLimitRange = null;
}
release(all) {
super.release(all), ("browser" === vrender_core_1.vglobal.env ? vrender_core_1.vglobal : this.stage).addEventListener("touchmove", this._handleTouchMove, {
passive: !1
}), this._clearDragEvents();
}
}
exports.ScrollBar = ScrollBar, ScrollBar.defaultAttributes = {
direction: "horizontal",
round: !0,
sliderSize: 20,
sliderStyle: {
fill: "rgba(0, 0, 0, .5)"
},
railStyle: {
fill: "rgba(0, 0, 0, .0)"
},
padding: 2,
scrollRange: [ 0, 1 ],
delayType: "throttle",
delayTime: 0,
realTime: !0
};
//# sourceMappingURL=scrollbar.js.map