From 41968aadf711b0106ca05ad59602dccdae906c5e Mon Sep 17 00:00:00 2001 From: zhongjinfeng Date: Tue, 12 Mar 2019 20:12:09 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AF=B9=E7=A7=BB?= =?UTF-8?q?=E5=8A=A8=E7=AB=AF=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/component/range.js | 391 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 391 insertions(+) diff --git a/src/component/range.js b/src/component/range.js index d4f133a..8822472 100644 --- a/src/component/range.js +++ b/src/component/range.js @@ -8,6 +8,397 @@ const { Group } = G; const { DomUtil } = Util; const OFFSET = 5; +/** + * @fileOverview The class of slider + * @author sima.zhang + */ +const G2 = window && window.G2; +const { Util, G } = G2; +const { Group } = G; +const { DomUtil } = Util; +const OFFSET = 5; + +const UA = navigator.userAgent.toLowerCase(); +const isMobile = UA.indexOf('iphone') !== -1 || UA.indexOf('android') !== -1; + + +class Range extends Group { + getDefaultCfg() { + return { + /** + * 范围 + * @type {Array} + */ + range: null, + /** + * 中滑块属性 + * @type {ATTRS} + */ + middleAttr: null, + /** + * 背景 + * @type {G-Element} + */ + backgroundElement: null, + /** + * 下滑块 + * @type {G-Element} + */ + minHandleElement: null, + /** + * 上滑块 + * @type {G-Element} + */ + maxHandleElement: null, + /** + * 中块 + * @type {G-Element} + */ + middleHandleElement: null, + /** + * 当前的激活的元素 + * @type {G-Element} + */ + currentTarget: null, + /** + * 布局方式: horizontal,vertical + * @type {String} + */ + layout: 'vertical', + /** + * 宽 + * @type {Number} + */ + width: null, + /** + * 高 + * @type {Number} + */ + height: null, + /** + * 当前的PageX + * @type {Number} + */ + pageX: null, + /** + * 当前的PageY + * @type {Number} + */ + pageY: null + }; + } + + _initHandle(type) { + const handle = this.addGroup(); + const layout = this.get('layout'); + const handleStyle = this.get('handleStyle'); + const img = handleStyle.img; + const iconWidth = handleStyle.width; + const iconHeight = handleStyle.height; + + let text; + let handleIcon; + let triggerCursor; + + + if (layout === 'horizontal') { + const iconWidth = handleStyle.width; + triggerCursor = 'ew-resize'; + handleIcon = handle.addShape('Image', { + attrs: { + x: -iconWidth / 2, + y: 0, + width: iconWidth, + height: iconHeight, + img, + cursor: triggerCursor + } + }); + text = handle.addShape('Text', { + attrs: Util.mix({ + x: (type === 'min') ? -(iconWidth / 2 + OFFSET) : iconWidth / 2 + OFFSET, + y: iconHeight / 2, + textAlign: (type === 'min') ? 'end' : 'start', + textBaseline: 'middle', + text: type === 'min' ? this.get('minText') : this.get('maxText'), + cursor: triggerCursor + }, this.get('textStyle')) + }); + } else { + triggerCursor = 'ns-resize'; + handleIcon = handle.addShape('Image', { + attrs: { + x: 0, + y: -iconHeight / 2, + width: iconWidth, + height: iconHeight, + img, + cursor: triggerCursor + } + }); + text = handle.addShape('Text', { + attrs: Util.mix({ + x: iconWidth / 2, + y: (type === 'min') ? (iconHeight / 2 + OFFSET) : -(iconHeight / 2 + OFFSET), + textAlign: 'center', + textBaseline: 'middle', + text: type === 'min' ? this.get('minText') : this.get('maxText'), + cursor: triggerCursor + }, this.get('textStyle')) + }); + } + + this.set(type + 'TextElement', text); + this.set(type + 'IconElement', handleIcon); + return handle; + } + + _initSliderBackground() { + const backgroundElement = this.addGroup(); + backgroundElement.initTransform(); + backgroundElement.translate(0, 0); + backgroundElement.addShape('Rect', { + attrs: Util.mix({ + x: 0, + y: 0, + width: this.get('width'), + height: this.get('height') + }, this.get('backgroundStyle')) + }); + return backgroundElement; + } + + _beforeRenderUI() { + const backgroundElement = this._initSliderBackground(); + const minHandleElement = this._initHandle('min'); + const maxHandleElement = this._initHandle('max'); + const middleHandleElement = this.addShape('rect', { + attrs: this.get('middleAttr') + }); + + this.set('middleHandleElement', middleHandleElement); + this.set('minHandleElement', minHandleElement); + this.set('maxHandleElement', maxHandleElement); + this.set('backgroundElement', backgroundElement); + backgroundElement.set('zIndex', 0); + middleHandleElement.set('zIndex', 1); + minHandleElement.set('zIndex', 2); + maxHandleElement.set('zIndex', 2); + middleHandleElement.attr('cursor', 'move'); + this.sort(); + } + + _renderUI() { + if (this.get('layout') === 'horizontal') { + this._renderHorizontal(); + } else { + this._renderVertical(); + } + } + + _transform(layout) { + const range = this.get('range'); + const minRatio = range[0] / 100; + const maxRatio = range[1] / 100; + const width = this.get('width'); + const height = this.get('height'); + const minHandleElement = this.get('minHandleElement'); + const maxHandleElement = this.get('maxHandleElement'); + const middleHandleElement = this.get('middleHandleElement'); + if (minHandleElement.resetMatrix) { + minHandleElement.resetMatrix(); + maxHandleElement.resetMatrix(); + } else { + minHandleElement.initTransform(); + maxHandleElement.initTransform(); + } + if (layout === 'horizontal') { + middleHandleElement.attr({ + x: width * minRatio, + y: 0, + width: (maxRatio - minRatio) * width, + height + }); + + minHandleElement.translate(minRatio * width, 0); + maxHandleElement.translate(maxRatio * width, 0); + } else { + middleHandleElement.attr({ + x: 0, + y: height * (1 - maxRatio), + width, + height: (maxRatio - minRatio) * height + }); + minHandleElement.translate(0, (1 - minRatio) * height); + maxHandleElement.translate(0, (1 - maxRatio) * height); + } + } + + _renderHorizontal() { + this._transform('horizontal'); + } + + _renderVertical() { + this._transform('vertical'); + } + + _bindUI() { + if(isMobile){ + this.on('touchstart', Util.wrapBehavior(this, '_onMouseDown')); + }else{ + this.on('mousedown', Util.wrapBehavior(this, '_onMouseDown')); + } + } + + _isElement(target, name) { // 判断是否是该元素 + const element = this.get(name); + if (target === element) { + return true; + } + if (element.isGroup) { + const elementChildren = element.get('children'); + return elementChildren.indexOf(target) > -1; + } + return false; + } + + _getRange(diff, range) { + let rst = diff + range; + rst = rst > 100 ? 100 : rst; + rst = rst < 0 ? 0 : rst; + return rst; + } + + _limitRange(diff, limit, range) { + range[0] = this._getRange(diff, range[0]); + range[1] = range[0] + limit; + if (range[1] > 100) { + range[1] = 100; + range[0] = range[1] - limit; + } + } + + _updateStatus(dim, ev) { + const totalLength = dim === 'x' ? this.get('width') : this.get('height'); + dim = Util.upperFirst(dim); + const range = this.get('range'); + const page = this.get('page' + dim); + const currentTarget = this.get('currentTarget'); + const rangeStash = this.get('rangeStash'); + const layout = this.get('layout'); + const sign = layout === 'vertical' ? -1 : 1; + const currentPage = ev[ 'page' + dim ]; + const diffPage = currentPage - page; + const diffRange = (diffPage / totalLength) * 100 * sign; + let diffStashRange; + + const minRange = this.get('minRange'); + const maxRange = this.get('maxRange'); + + if (range[1] <= range[0]) { + if (this._isElement(currentTarget, 'minHandleElement') || this._isElement(currentTarget, 'maxHandleElement')) { + range[0] = this._getRange(diffRange, range[0]); + range[1] = this._getRange(diffRange, range[0]); + } + } else { + if (this._isElement(currentTarget, 'minHandleElement')) { + range[0] = this._getRange(diffRange, range[0]); + if (minRange) { // 设置了最小范围 + if ((range[1] - range[0]) <= minRange) { + this._limitRange(diffRange, minRange, range); + } + } + + if (maxRange) { // 设置了最大范围 + if (range[1] - range[0] >= maxRange) { + this._limitRange(diffRange, maxRange, range); + } + } + } + if (this._isElement(currentTarget, 'maxHandleElement')) { + range[1] = this._getRange(diffRange, range[1]); + + if (minRange) { // 设置了最小范围 + if ((range[1] - range[0]) <= minRange) { + this._limitRange(diffRange, minRange, range); + } + } + + if (maxRange) { // 设置了最大范围 + if (range[1] - range[0] >= maxRange) { + this._limitRange(diffRange, maxRange, range); + } + } + } + } + + if (this._isElement(currentTarget, 'middleHandleElement')) { + diffStashRange = (rangeStash[1] - rangeStash[0]); + this._limitRange(diffRange, diffStashRange, range); + } + + this.emit('sliderchange', { + range + }); + + this.set('page' + dim, currentPage); + this._renderUI(); + this.get('canvas').draw(); // need delete + return; + } + + _onMouseDown(ev) { + const currentTarget = ev.currentTarget; + const originEvent = ev.event; + const range = this.get('range'); + if(isMobile){ + ev.stopPropagation(); + ev.preventDefault(); + }else{ + originEvent.stopPropagation(); + originEvent.preventDefault(); + } + this.set('pageX', originEvent.pageX); + this.set('pageY', originEvent.pageY); + this.set('currentTarget', currentTarget); + this.set('rangeStash', [ range[0], range[1] ]); + this._bindCanvasEvents(); + } + + _bindCanvasEvents() { + const containerDOM = this.get('canvas').get('containerDOM'); + if(isMobile){ + this.onMouseMoveListener = DomUtil.addEventListener(containerDOM, 'touchmove', Util.wrapBehavior(this, '_onCanvasMouseMove')); + this.onMouseUpListener = DomUtil.addEventListener(containerDOM, 'touchend', Util.wrapBehavior(this, '_onCanvasMouseUp')); + }else{ + this.onMouseMoveListener = DomUtil.addEventListener(containerDOM, 'mousemove', Util.wrapBehavior(this, '_onCanvasMouseMove')); + this.onMouseUpListener = DomUtil.addEventListener(containerDOM, 'mouseup', Util.wrapBehavior(this, '_onCanvasMouseUp')); + // @2018-06-06 by blue.lb 添加mouseleave事件监听,让用户在操作出滑块区域后有一个“正常”的效果,可以正常重新触发滑块的操作流程 + this.onMouseLeaveListener = DomUtil.addEventListener(containerDOM, 'mouseleave', Util.wrapBehavior(this, '_onCanvasMouseUp')); + } + } + + _onCanvasMouseMove(ev) { + const layout = this.get('layout'); + if (layout === 'horizontal') { + this._updateStatus('x', ev); + } else { + this._updateStatus('y', ev); + } + } + + _onCanvasMouseUp() { + this._removeDocumentEvents(); + } + + _removeDocumentEvents() { + this.onMouseMoveListener.remove(); + this.onMouseUpListener.remove(); + this.onMouseLeaveListener.remove(); + } +} + +module.exports = Range; class Range extends Group { getDefaultCfg() { From 7177032a9571332367befb03c7af0e54f6fc12c0 Mon Sep 17 00:00:00 2001 From: zjfjiayou Date: Tue, 12 Mar 2019 20:33:50 +0800 Subject: [PATCH 2/2] Update range.js --- src/component/range.js | 386 +---------------------------------------- 1 file changed, 6 insertions(+), 380 deletions(-) diff --git a/src/component/range.js b/src/component/range.js index 8822472..b6bb36e 100644 --- a/src/component/range.js +++ b/src/component/range.js @@ -8,16 +8,6 @@ const { Group } = G; const { DomUtil } = Util; const OFFSET = 5; -/** - * @fileOverview The class of slider - * @author sima.zhang - */ -const G2 = window && window.G2; -const { Util, G } = G2; -const { Group } = G; -const { DomUtil } = Util; -const OFFSET = 5; - const UA = navigator.userAgent.toLowerCase(); const isMobile = UA.indexOf('iphone') !== -1 || UA.indexOf('android') !== -1; @@ -243,9 +233,9 @@ class Range extends Group { } _bindUI() { - if(isMobile){ + if (isMobile) { this.on('touchstart', Util.wrapBehavior(this, '_onMouseDown')); - }else{ + } else { this.on('mousedown', Util.wrapBehavior(this, '_onMouseDown')); } } @@ -351,10 +341,10 @@ class Range extends Group { const currentTarget = ev.currentTarget; const originEvent = ev.event; const range = this.get('range'); - if(isMobile){ + if (isMobile) { ev.stopPropagation(); ev.preventDefault(); - }else{ + } else { originEvent.stopPropagation(); originEvent.preventDefault(); } @@ -367,10 +357,10 @@ class Range extends Group { _bindCanvasEvents() { const containerDOM = this.get('canvas').get('containerDOM'); - if(isMobile){ + if (isMobile) { this.onMouseMoveListener = DomUtil.addEventListener(containerDOM, 'touchmove', Util.wrapBehavior(this, '_onCanvasMouseMove')); this.onMouseUpListener = DomUtil.addEventListener(containerDOM, 'touchend', Util.wrapBehavior(this, '_onCanvasMouseUp')); - }else{ + } else { this.onMouseMoveListener = DomUtil.addEventListener(containerDOM, 'mousemove', Util.wrapBehavior(this, '_onCanvasMouseMove')); this.onMouseUpListener = DomUtil.addEventListener(containerDOM, 'mouseup', Util.wrapBehavior(this, '_onCanvasMouseUp')); // @2018-06-06 by blue.lb 添加mouseleave事件监听,让用户在操作出滑块区域后有一个“正常”的效果,可以正常重新触发滑块的操作流程 @@ -399,367 +389,3 @@ class Range extends Group { } module.exports = Range; - -class Range extends Group { - getDefaultCfg() { - return { - /** - * 范围 - * @type {Array} - */ - range: null, - /** - * 中滑块属性 - * @type {ATTRS} - */ - middleAttr: null, - /** - * 背景 - * @type {G-Element} - */ - backgroundElement: null, - /** - * 下滑块 - * @type {G-Element} - */ - minHandleElement: null, - /** - * 上滑块 - * @type {G-Element} - */ - maxHandleElement: null, - /** - * 中块 - * @type {G-Element} - */ - middleHandleElement: null, - /** - * 当前的激活的元素 - * @type {G-Element} - */ - currentTarget: null, - /** - * 布局方式: horizontal,vertical - * @type {String} - */ - layout: 'vertical', - /** - * 宽 - * @type {Number} - */ - width: null, - /** - * 高 - * @type {Number} - */ - height: null, - /** - * 当前的PageX - * @type {Number} - */ - pageX: null, - /** - * 当前的PageY - * @type {Number} - */ - pageY: null - }; - } - - _initHandle(type) { - const handle = this.addGroup(); - const layout = this.get('layout'); - const handleStyle = this.get('handleStyle'); - const img = handleStyle.img; - const iconWidth = handleStyle.width; - const iconHeight = handleStyle.height; - - let text; - let handleIcon; - let triggerCursor; - - - if (layout === 'horizontal') { - const iconWidth = handleStyle.width; - triggerCursor = 'ew-resize'; - handleIcon = handle.addShape('Image', { - attrs: { - x: -iconWidth / 2, - y: 0, - width: iconWidth, - height: iconHeight, - img, - cursor: triggerCursor - } - }); - text = handle.addShape('Text', { - attrs: Util.mix({ - x: (type === 'min') ? -(iconWidth / 2 + OFFSET) : iconWidth / 2 + OFFSET, - y: iconHeight / 2, - textAlign: (type === 'min') ? 'end' : 'start', - textBaseline: 'middle', - text: type === 'min' ? this.get('minText') : this.get('maxText'), - cursor: triggerCursor - }, this.get('textStyle')) - }); - } else { - triggerCursor = 'ns-resize'; - handleIcon = handle.addShape('Image', { - attrs: { - x: 0, - y: -iconHeight / 2, - width: iconWidth, - height: iconHeight, - img, - cursor: triggerCursor - } - }); - text = handle.addShape('Text', { - attrs: Util.mix({ - x: iconWidth / 2, - y: (type === 'min') ? (iconHeight / 2 + OFFSET) : -(iconHeight / 2 + OFFSET), - textAlign: 'center', - textBaseline: 'middle', - text: type === 'min' ? this.get('minText') : this.get('maxText'), - cursor: triggerCursor - }, this.get('textStyle')) - }); - } - - this.set(type + 'TextElement', text); - this.set(type + 'IconElement', handleIcon); - return handle; - } - - _initSliderBackground() { - const backgroundElement = this.addGroup(); - backgroundElement.initTransform(); - backgroundElement.translate(0, 0); - backgroundElement.addShape('Rect', { - attrs: Util.mix({ - x: 0, - y: 0, - width: this.get('width'), - height: this.get('height') - }, this.get('backgroundStyle')) - }); - return backgroundElement; - } - - _beforeRenderUI() { - const backgroundElement = this._initSliderBackground(); - const minHandleElement = this._initHandle('min'); - const maxHandleElement = this._initHandle('max'); - const middleHandleElement = this.addShape('rect', { - attrs: this.get('middleAttr') - }); - - this.set('middleHandleElement', middleHandleElement); - this.set('minHandleElement', minHandleElement); - this.set('maxHandleElement', maxHandleElement); - this.set('backgroundElement', backgroundElement); - backgroundElement.set('zIndex', 0); - middleHandleElement.set('zIndex', 1); - minHandleElement.set('zIndex', 2); - maxHandleElement.set('zIndex', 2); - middleHandleElement.attr('cursor', 'move'); - this.sort(); - } - - _renderUI() { - if (this.get('layout') === 'horizontal') { - this._renderHorizontal(); - } else { - this._renderVertical(); - } - } - - _transform(layout) { - const range = this.get('range'); - const minRatio = range[0] / 100; - const maxRatio = range[1] / 100; - const width = this.get('width'); - const height = this.get('height'); - const minHandleElement = this.get('minHandleElement'); - const maxHandleElement = this.get('maxHandleElement'); - const middleHandleElement = this.get('middleHandleElement'); - if (minHandleElement.resetMatrix) { - minHandleElement.resetMatrix(); - maxHandleElement.resetMatrix(); - } else { - minHandleElement.initTransform(); - maxHandleElement.initTransform(); - } - if (layout === 'horizontal') { - middleHandleElement.attr({ - x: width * minRatio, - y: 0, - width: (maxRatio - minRatio) * width, - height - }); - - minHandleElement.translate(minRatio * width, 0); - maxHandleElement.translate(maxRatio * width, 0); - } else { - middleHandleElement.attr({ - x: 0, - y: height * (1 - maxRatio), - width, - height: (maxRatio - minRatio) * height - }); - minHandleElement.translate(0, (1 - minRatio) * height); - maxHandleElement.translate(0, (1 - maxRatio) * height); - } - } - - _renderHorizontal() { - this._transform('horizontal'); - } - - _renderVertical() { - this._transform('vertical'); - } - - _bindUI() { - this.on('mousedown', Util.wrapBehavior(this, '_onMouseDown')); - } - - _isElement(target, name) { // 判断是否是该元素 - const element = this.get(name); - if (target === element) { - return true; - } - if (element.isGroup) { - const elementChildren = element.get('children'); - return elementChildren.indexOf(target) > -1; - } - return false; - } - - _getRange(diff, range) { - let rst = diff + range; - rst = rst > 100 ? 100 : rst; - rst = rst < 0 ? 0 : rst; - return rst; - } - - _limitRange(diff, limit, range) { - range[0] = this._getRange(diff, range[0]); - range[1] = range[0] + limit; - if (range[1] > 100) { - range[1] = 100; - range[0] = range[1] - limit; - } - } - - _updateStatus(dim, ev) { - const totalLength = dim === 'x' ? this.get('width') : this.get('height'); - dim = Util.upperFirst(dim); - const range = this.get('range'); - const page = this.get('page' + dim); - const currentTarget = this.get('currentTarget'); - const rangeStash = this.get('rangeStash'); - const layout = this.get('layout'); - const sign = layout === 'vertical' ? -1 : 1; - const currentPage = ev[ 'page' + dim ]; - const diffPage = currentPage - page; - const diffRange = (diffPage / totalLength) * 100 * sign; - let diffStashRange; - - const minRange = this.get('minRange'); - const maxRange = this.get('maxRange'); - - if (range[1] <= range[0]) { - if (this._isElement(currentTarget, 'minHandleElement') || this._isElement(currentTarget, 'maxHandleElement')) { - range[0] = this._getRange(diffRange, range[0]); - range[1] = this._getRange(diffRange, range[0]); - } - } else { - if (this._isElement(currentTarget, 'minHandleElement')) { - range[0] = this._getRange(diffRange, range[0]); - if (minRange) { // 设置了最小范围 - if ((range[1] - range[0]) <= minRange) { - this._limitRange(diffRange, minRange, range); - } - } - - if (maxRange) { // 设置了最大范围 - if (range[1] - range[0] >= maxRange) { - this._limitRange(diffRange, maxRange, range); - } - } - } - if (this._isElement(currentTarget, 'maxHandleElement')) { - range[1] = this._getRange(diffRange, range[1]); - - if (minRange) { // 设置了最小范围 - if ((range[1] - range[0]) <= minRange) { - this._limitRange(diffRange, minRange, range); - } - } - - if (maxRange) { // 设置了最大范围 - if (range[1] - range[0] >= maxRange) { - this._limitRange(diffRange, maxRange, range); - } - } - } - } - - if (this._isElement(currentTarget, 'middleHandleElement')) { - diffStashRange = (rangeStash[1] - rangeStash[0]); - this._limitRange(diffRange, diffStashRange, range); - } - - this.emit('sliderchange', { - range - }); - - this.set('page' + dim, currentPage); - this._renderUI(); - this.get('canvas').draw(); // need delete - return; - } - - _onMouseDown(ev) { - const currentTarget = ev.currentTarget; - const originEvent = ev.event; - const range = this.get('range'); - originEvent.stopPropagation(); - originEvent.preventDefault(); - this.set('pageX', originEvent.pageX); - this.set('pageY', originEvent.pageY); - this.set('currentTarget', currentTarget); - this.set('rangeStash', [ range[0], range[1] ]); - this._bindCanvasEvents(); - } - - _bindCanvasEvents() { - const containerDOM = this.get('canvas').get('containerDOM'); - this.onMouseMoveListener = DomUtil.addEventListener(containerDOM, 'mousemove', Util.wrapBehavior(this, '_onCanvasMouseMove')); - this.onMouseUpListener = DomUtil.addEventListener(containerDOM, 'mouseup', Util.wrapBehavior(this, '_onCanvasMouseUp')); - // @2018-06-06 by blue.lb 添加mouseleave事件监听,让用户在操作出滑块区域后有一个“正常”的效果,可以正常重新触发滑块的操作流程 - this.onMouseLeaveListener = DomUtil.addEventListener(containerDOM, 'mouseleave', Util.wrapBehavior(this, '_onCanvasMouseUp')); - } - - _onCanvasMouseMove(ev) { - const layout = this.get('layout'); - if (layout === 'horizontal') { - this._updateStatus('x', ev); - } else { - this._updateStatus('y', ev); - } - } - - _onCanvasMouseUp() { - this._removeDocumentEvents(); - } - - _removeDocumentEvents() { - this.onMouseMoveListener.remove(); - this.onMouseUpListener.remove(); - this.onMouseLeaveListener.remove(); - } -} - -module.exports = Range;