1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | 53× 53× 53× 53× 7× 7× 53× 3× 1× 1× 7× 7× 7× 7× 7× 7× 7× 7× 7× 28× 7× 28× 28× 1× 10× 1× 1× 7× 7× 7× | import { assign } from 'min-dash'; import { toPoint } from '../../util/Event'; /** * Initiates canvas scrolling if current cursor point is close to a border. * Cancelled when current point moves back inside the scrolling borders * or cancelled manually. * * Default options : * scrollThresholdIn: [ 20, 20, 20, 20 ], * scrollThresholdOut: [ 0, 0, 0, 0 ], * scrollRepeatTimeout: 15, * scrollStep: 10 * * Threshold order: * [ left, top, right, bottom ] */ export default function AutoScroll(config, eventBus, canvas) { this._canvas = canvas; this._opts = assign({ scrollThresholdIn: [ 20, 20, 20, 20 ], scrollThresholdOut: [ 0, 0, 0, 0 ], scrollRepeatTimeout: 15, scrollStep: 10 }, config); var self = this; eventBus.on('drag.move', function(e) { var point = self._toBorderPoint(e); self.startScroll(point); }); eventBus.on([ 'drag.cleanup' ], function() { self.stopScroll(); }); } AutoScroll.$inject = [ 'config.autoScroll', 'eventBus', 'canvas' ]; /** * Starts scrolling loop. * Point is given in global scale in canvas container box plane. * * @param {Object} point { x: X, y: Y } */ AutoScroll.prototype.startScroll = function(point) { var canvas = this._canvas; var opts = this._opts; var self = this; var clientRect = canvas.getContainer().getBoundingClientRect(); var diff = [ point.x, point.y, clientRect.width - point.x, clientRect.height - point.y ]; this.stopScroll(); var dx = 0, dy = 0; for (var i = 0; i < 4; i++) { Iif (between(diff[i], opts.scrollThresholdOut[i], opts.scrollThresholdIn[i])) { if (i === 0) { dx = opts.scrollStep; } else if (i == 1) { dy = opts.scrollStep; } else if (i == 2) { dx = -opts.scrollStep; } else if (i == 3) { dy = -opts.scrollStep; } } } Iif (dx !== 0 || dy !== 0) { canvas.scroll({ dx: dx, dy: dy }); this._scrolling = setTimeout(function() { self.startScroll(point); }, opts.scrollRepeatTimeout); } }; function between(val, start, end) { Iif (start < val && val < end) { return true; } return false; } /** * Stops scrolling loop. */ AutoScroll.prototype.stopScroll = function() { clearTimeout(this._scrolling); }; /** * Overrides defaults options. * * @param {Object} options */ AutoScroll.prototype.setOptions = function(options) { this._opts = assign({}, this._opts, options); }; /** * Converts event to a point in canvas container plane in global scale. * * @param {Event} event * @return {Point} */ AutoScroll.prototype._toBorderPoint = function(event) { var clientRect = this._canvas._container.getBoundingClientRect(); var globalPosition = toPoint(event.originalEvent); return { x: globalPosition.x - clientRect.left, y: globalPosition.y - clientRect.top }; }; |