UNPKG

@mhmdaljefri/revogrid

Version:

Virtual reactive data grid component - RevoGrid.

81 lines (80 loc) 2.96 kB
import { scaleValue } from '../utils/utils'; const initialParams = { contentSize: 0, clientSize: 0, virtualSize: 0, maxSize: 0, }; export default class LocalScrollService { constructor(cfg) { this.cfg = cfg; this.preventArtificialScroll = { rgRow: null, rgCol: null }; // to check if scroll changed this.previousScroll = { rgRow: 0, rgCol: 0 }; this.params = { rgRow: Object.assign({}, initialParams), rgCol: Object.assign({}, initialParams) }; } static getVirtualContentSize(contentSize, clientSize, virtualSize = 0) { return contentSize + (virtualSize ? clientSize - virtualSize : 0); } setParams(params, dimension) { const virtualContentSize = LocalScrollService.getVirtualContentSize(params.contentSize, params.clientSize, params.virtualSize); this.params[dimension] = Object.assign(Object.assign({}, params), { maxSize: virtualContentSize - params.clientSize, virtualContentSize }); } // apply scroll values after scroll done setScroll(e) { this.cancelScroll(e.dimension); this.preventArtificialScroll[e.dimension] = window.requestAnimationFrame(() => { const params = this.getParams(e.dimension); e.coordinate = Math.ceil(e.coordinate); this.previousScroll[e.dimension] = this.wrapCoordinate(e.coordinate, params); this.preventArtificialScroll[e.dimension] = null; this.cfg.afterScroll(Object.assign(Object.assign({}, e), { coordinate: params.virtualSize ? this.convert(e.coordinate, params, false) : e.coordinate })); }); } // initiate scrolling event scroll(coordinate, dimension, force = false, delta) { this.cancelScroll(dimension); if (!force && this.previousScroll[dimension] === coordinate) { this.previousScroll[dimension] = 0; return; } const param = this.getParams(dimension); this.cfg.beforeScroll({ dimension: dimension, coordinate: param.virtualSize ? this.convert(coordinate, param) : coordinate, delta, }); } getParams(dimension) { return this.params[dimension]; } // check if scroll outside of region to avoid looping wrapCoordinate(c, param) { if (c < 0) { return 0; } if (c > param.maxSize) { return param.maxSize; } return c; } // prevent already started scroll, performance optimization cancelScroll(dimension) { if (typeof this.preventArtificialScroll[dimension] === 'number') { window.cancelAnimationFrame(this.preventArtificialScroll[dimension]); this.preventArtificialScroll[dimension] = null; return true; } return false; } /* convert virtual to real and back, scale range */ convert(pos, param, toReal = true) { const minRange = param.clientSize; const from = [0, param.virtualContentSize - minRange]; const to = [0, param.contentSize - param.virtualSize]; if (toReal) { return scaleValue(pos, from, to); } return scaleValue(pos, to, from); } }