386 lines
11 KiB
Java
386 lines
11 KiB
Java
|
|
var Util = require('../../util');
|
|||
|
|
|
|||
|
|
var G = require('../../renderer');
|
|||
|
|
|
|||
|
|
var Group = G.Group;
|
|||
|
|
var DomUtil = Util.DomUtil;
|
|||
|
|
var OFFSET = 5;
|
|||
|
|
|
|||
|
|
var Range = function Range(cfg) {
|
|||
|
|
Range.superclass.constructor.call(this, cfg);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
Util.extend(Range, Group);
|
|||
|
|
Util.augment(Range, {
|
|||
|
|
getDefaultCfg: function 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: function _initHandle(type) {
|
|||
|
|
var self = this;
|
|||
|
|
var handle = self.addGroup();
|
|||
|
|
var layout = self.get('layout');
|
|||
|
|
var handleStyle = self.get('handleStyle');
|
|||
|
|
var img = handleStyle.img;
|
|||
|
|
var iconWidth = handleStyle.width;
|
|||
|
|
var iconHeight = handleStyle.height;
|
|||
|
|
var text;
|
|||
|
|
var handleIcon;
|
|||
|
|
var triggerCursor;
|
|||
|
|
|
|||
|
|
if (layout === 'horizontal') {
|
|||
|
|
var _iconWidth = handleStyle.width;
|
|||
|
|
triggerCursor = 'ew-resize';
|
|||
|
|
handleIcon = handle.addShape('Image', {
|
|||
|
|
attrs: {
|
|||
|
|
x: -_iconWidth / 2,
|
|||
|
|
y: 0,
|
|||
|
|
width: _iconWidth,
|
|||
|
|
height: iconHeight,
|
|||
|
|
img: 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: 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: function _initSliderBackground() {
|
|||
|
|
var 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: function _beforeRenderUI() {
|
|||
|
|
var backgroundElement = this._initSliderBackground();
|
|||
|
|
|
|||
|
|
var minHandleElement = this._initHandle('min');
|
|||
|
|
|
|||
|
|
var maxHandleElement = this._initHandle('max');
|
|||
|
|
|
|||
|
|
var 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: function _renderUI() {
|
|||
|
|
if (this.get('layout') === 'horizontal') {
|
|||
|
|
this._renderHorizontal();
|
|||
|
|
} else {
|
|||
|
|
this._renderVertical();
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
_transform: function _transform(layout) {
|
|||
|
|
var range = this.get('range');
|
|||
|
|
var minRatio = range[0] / 100;
|
|||
|
|
var maxRatio = range[1] / 100;
|
|||
|
|
var width = this.get('width');
|
|||
|
|
var height = this.get('height');
|
|||
|
|
var minHandleElement = this.get('minHandleElement');
|
|||
|
|
var maxHandleElement = this.get('maxHandleElement');
|
|||
|
|
var 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: height
|
|||
|
|
});
|
|||
|
|
minHandleElement.translate(minRatio * width, 0);
|
|||
|
|
maxHandleElement.translate(maxRatio * width, 0);
|
|||
|
|
} else {
|
|||
|
|
middleHandleElement.attr({
|
|||
|
|
x: 0,
|
|||
|
|
y: height * (1 - maxRatio),
|
|||
|
|
width: width,
|
|||
|
|
height: (maxRatio - minRatio) * height
|
|||
|
|
});
|
|||
|
|
minHandleElement.translate(0, (1 - minRatio) * height);
|
|||
|
|
maxHandleElement.translate(0, (1 - maxRatio) * height);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
_renderHorizontal: function _renderHorizontal() {
|
|||
|
|
this._transform('horizontal');
|
|||
|
|
},
|
|||
|
|
_renderVertical: function _renderVertical() {
|
|||
|
|
this._transform('vertical');
|
|||
|
|
},
|
|||
|
|
_bindUI: function _bindUI() {
|
|||
|
|
this.on('mousedown', Util.wrapBehavior(this, '_onMouseDown'));
|
|||
|
|
},
|
|||
|
|
_isElement: function _isElement(target, name) {
|
|||
|
|
// 判断是否是该元素
|
|||
|
|
var element = this.get(name);
|
|||
|
|
|
|||
|
|
if (target === element) {
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (element.isGroup) {
|
|||
|
|
var elementChildren = element.get('children');
|
|||
|
|
return elementChildren.indexOf(target) > -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return false;
|
|||
|
|
},
|
|||
|
|
_getRange: function _getRange(diff, range) {
|
|||
|
|
var rst = diff + range;
|
|||
|
|
rst = rst > 100 ? 100 : rst;
|
|||
|
|
rst = rst < 0 ? 0 : rst;
|
|||
|
|
return rst;
|
|||
|
|
},
|
|||
|
|
_limitRange: function _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: function _updateStatus(dim, ev) {
|
|||
|
|
var totalLength = dim === 'x' ? this.get('width') : this.get('height');
|
|||
|
|
dim = Util.upperFirst(dim);
|
|||
|
|
var range = this.get('range');
|
|||
|
|
var page = this.get('page' + dim);
|
|||
|
|
var currentTarget = this.get('currentTarget');
|
|||
|
|
var rangeStash = this.get('rangeStash');
|
|||
|
|
var layout = this.get('layout');
|
|||
|
|
var sign = layout === 'vertical' ? -1 : 1;
|
|||
|
|
var currentPage = ev['page' + dim];
|
|||
|
|
var diffPage = currentPage - page;
|
|||
|
|
var diffRange = diffPage / totalLength * 100 * sign;
|
|||
|
|
var diffStashRange;
|
|||
|
|
var minRange = this.get('minRange');
|
|||
|
|
var 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: range
|
|||
|
|
});
|
|||
|
|
this.set('page' + dim, currentPage);
|
|||
|
|
|
|||
|
|
this._renderUI();
|
|||
|
|
|
|||
|
|
this.get('canvas').draw(); // need delete
|
|||
|
|
|
|||
|
|
return;
|
|||
|
|
},
|
|||
|
|
_onMouseDown: function _onMouseDown(ev) {
|
|||
|
|
var currentTarget = ev.currentTarget;
|
|||
|
|
var originEvent = ev.event;
|
|||
|
|
var 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: function _bindCanvasEvents() {
|
|||
|
|
var 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: function _onCanvasMouseMove(ev) {
|
|||
|
|
var layout = this.get('layout');
|
|||
|
|
|
|||
|
|
if (layout === 'horizontal') {
|
|||
|
|
this._updateStatus('x', ev);
|
|||
|
|
} else {
|
|||
|
|
this._updateStatus('y', ev);
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
_onCanvasMouseUp: function _onCanvasMouseUp() {
|
|||
|
|
this._removeDocumentEvents();
|
|||
|
|
},
|
|||
|
|
_removeDocumentEvents: function _removeDocumentEvents() {
|
|||
|
|
this.onMouseMoveListener.remove();
|
|||
|
|
this.onMouseUpListener.remove();
|
|||
|
|
this.onMouseLeaveListener.remove();
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
module.exports = Range;
|