@xiaomengqiang/charts
Version:
hcharts library for web visualization
246 lines (238 loc) • 9.77 kB
JavaScript
import { isParent } from '../../util/dom.js';
import { pointsDirection, getAngleByPoints } from '../../util/math.js';
/**
* Copyright (c) 2024 - present OpenTiny HUICharts Authors.
* Copyright (c) 2024 - present Huawei Cloud Computing Technologies Co., Ltd.
*
* Use of this source code is governed by an MIT-style license.
*
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
*
*/
var RotateManager = /*#__PURE__*/function () {
function RotateManager(dom, option, selected, nodeManager) {
this.currentTarget = null;
this.dom = dom;
this.data = option.data;
this.selected = selected;
this.nodeManager = nodeManager;
this.angles = this.nodeManager.angles;
this.drag = false;
if (option.autoRotate) {
this.autoRotate(option.autoRotate);
} else {
this.initWarppersEvent();
this.initNodesEvent(this.dom);
}
}
// 绑定转轮拖动事件
var _proto = RotateManager.prototype;
_proto.initWarppersEvent = function initWarppersEvent() {
var _this = this;
this.warppers = this.dom.getElementsByClassName('ozc_warpper');
Array.from(this.warppers).forEach(function (element, index) {
element.addEventListener('mousedown', function (e) {
var currentTargetRect = e.currentTarget.getBoundingClientRect();
_this.drag = false;
_this.currentTarget = {
dom: e.currentTarget,
// 旋转元素
index: index,
// 旋转层数
center: {
// 旋转中心位置
x: currentTargetRect.x + currentTargetRect.width / 2,
y: currentTargetRect.y + currentTargetRect.height / 2
},
startRotate: _this.getRotateDeg(e.currentTarget),
// 初始旋转角度
startTouchPosition: {
// 鼠标拖动的起始位置
x: e.clientX,
y: e.clientY
},
clockwise: undefined // true 表示顺时针方向
};
});
element.addEventListener('mousemove', function (e) {
if (_this.currentTarget) {
_this.drag = true;
// 当前拖动的层级
var curLevel = _this.currentTarget.index;
// 鼠标拖动的当前位置
_this.currentTarget.endTouchPosition = {
x: e.clientX,
y: e.clientY
};
// 是否为顺时针方向
var clockwise = pointsDirection(_this.currentTarget.center, _this.currentTarget.startTouchPosition, _this.currentTarget.endTouchPosition);
// 旋转夹角,计算结论<=180°,要结合顺逆时判断是否>180°
var angle = getAngleByPoints(_this.currentTarget.center, _this.currentTarget.startTouchPosition, _this.currentTarget.endTouchPosition)[1];
// 顺时针夹角为正,逆时针夹角为负
if (_this.currentTarget.clockwise === undefined) {
_this.currentTarget.clockwise = clockwise;
} else if (_this.currentTarget.clockwise !== clockwise) {
// 用户旋转超过180度后,继续旋转, 极限是转到 350
if (angle > 10) {
angle = 360 - angle;
// 用户向另一个方向旋转了
} else {
_this.currentTarget.clockwise = clockwise;
}
}
var rotate = angle;
rotate = angle * (_this.currentTarget.clockwise ? 1 : -1);
rotate = _this.currentTarget.startRotate + rotate;
// 旋转时产生的临时选中下标
var selected = _this.getSelected(rotate).selected;
// 旋转前选中的下标
var prevSelected = _this.selected[curLevel];
_this.setRotateDeg(_this.currentTarget.dom, curLevel, rotate, selected, prevSelected);
}
});
element.addEventListener('mouseup', function (e) {
if (_this.drag && _this.currentTarget) {
var curIndex = _this.currentTarget.index;
var endRotate = _this.getRotateDeg(_this.currentTarget.dom);
var result = _this.getSelected(endRotate, true);
endRotate = result.rotate;
_this.selected[curIndex] = result.selected;
// 刷新下层数据
_this.nodeManager.refreshWarpper(curIndex, _this.selected);
_this.setRotateDeg(_this.currentTarget.dom, curIndex, endRotate, _this.selected[curIndex], -1);
}
_this.currentTarget = null;
});
});
this.dom.addEventListener('mouseleave', function (e) {
if (_this.drag && _this.currentTarget) {
var mouseupEvent = new Event('mouseup');
_this.currentTarget.dom.dispatchEvent(mouseupEvent);
e.stopPropagation();
e.preventDefault();
}
});
}
// 绑定卡片点击事件
;
_proto.initNodesEvent = function initNodesEvent(container) {
var _this2 = this;
container.addEventListener('click', function (e) {
var parent = isParent(e.target, 'ozc_card');
if (!_this2.drag && parent) {
var warpperIndex = parseInt(parent.getAttribute('data-warpper-index'));
var nodeIndex = parseInt(parent.getAttribute('data-node-index'));
var warpperDom = _this2.nodeManager.warppers[warpperIndex];
var moveIndex = _this2.selected[warpperIndex] - nodeIndex;
var rotate = _this2.angles[warpperIndex] * moveIndex * -1;
rotate = _this2.getRotateDeg(warpperDom) + rotate;
_this2.selected[warpperIndex] = nodeIndex;
_this2.setRotateDeg(warpperDom, warpperIndex, rotate, nodeIndex, -1);
// 刷新下层数据
_this2.nodeManager.refreshWarpper(warpperIndex, _this2.selected);
}
});
}
/**
* 旋转 ozc_warpper
* dom: ozc_warpper元素
* domIndex: ozc_warpper下标
* rotate: ozc_warpper目标旋转角度
* selected: 当前选中的元素
* prevSelected: 拖拽过程前选中的元素(上一个选中元素)
*/;
_proto.setRotateDeg = function setRotateDeg(dom, domIndex, rotate, selected, prevSelected) {
var _this3 = this;
dom.style.transform = " translateX(-50%) translateY(-50%) rotate(" + rotate + "deg)";
var data = this.nodeManager.getDepthData(this.data, domIndex);
// 逆向旋转ozc_card
Array.from(dom.getElementsByClassName('ozc_card')).forEach(function (element, index) {
element.style.transform = "rotate(" + -rotate + "deg)";
// 清空ozc_card,并重新绘制 selected 状态
element.innerHTML = '';
_this3.nodeManager.render && _this3.nodeManager.render(element, data[index], {
boss: false,
selected: selected === index ? true : false,
prevSelected: prevSelected === index ? true : false
});
});
}
// 从DOM的内联样式上取出旋转角度
;
_proto.getRotateDeg = function getRotateDeg(element) {
var transform = element.style.transform;
var degIndex = transform.indexOf('deg)');
var rotateIndex = transform.indexOf('rotate(');
var targetRotate = parseFloat(transform.slice(rotateIndex + 'rotate('.length, degIndex));
return targetRotate;
}
// 根据当前旋转角度计算出选中的单位, correct = true时表示需要对角度进行修正
;
_proto.getSelected = function getSelected(rotate, correct) {
var curIndex = this.currentTarget.index;
var unitAngle = this.angles[curIndex];
// step1. 吸附到最近的 unitAngle 倍数上
if (Math.abs(rotate % unitAngle) >= unitAngle / 2) {
if (rotate >= 0) {
rotate = (Math.floor(rotate / unitAngle) + 1) * unitAngle;
} else {
rotate = (Math.ceil(rotate / unitAngle) - 1) * unitAngle;
}
} else {
if (rotate >= 0) {
rotate = Math.floor(rotate / unitAngle) * unitAngle;
} else {
rotate = Math.ceil(rotate / unitAngle) * unitAngle;
}
}
// step2. 进行超限修正
// 修正前旋转了多少位置
var dataLength = this.nodeManager.getDepthData(this.data, curIndex).length;
var changeIndex = (rotate - this.currentTarget.startRotate) / unitAngle;
var endIndex = parseInt(changeIndex.toFixed()) + this.selected[curIndex];
var selectedIndex = 0;
// 右侧超限需要回转
if (endIndex >= dataLength) {
selectedIndex = dataLength - 1;
correct && (rotate = rotate - (endIndex - (dataLength - 1)) * unitAngle);
// 左侧超限需要回转
} else if (endIndex < 0) {
selectedIndex = 0;
correct && (rotate = rotate + Math.abs(endIndex) * unitAngle);
// 正常范围内
} else {
selectedIndex = endIndex;
}
return {
rotate: rotate,
selected: selectedIndex
};
}
// 自动旋转
;
_proto.autoRotate = function autoRotate(option) {
var current = 0;
var speed = option.speed || 1;
var direction = option.direction || 'clockwise';
var warppers = this.dom.getElementsByClassName('ozc_warpper');
function rotate() {
if (direction === 'clockwise') {
current += speed;
} else {
current -= speed;
}
Array.from(warppers).forEach(function (element) {
element.style.transform = " translateX(-50%) translateY(-50%) rotate(" + current + "deg)";
Array.from(element.getElementsByClassName('ozc_card')).forEach(function (card) {
card.style.transform = "rotate(" + -current + "deg)";
});
});
window.requestAnimationFrame(rotate);
}
window.requestAnimationFrame(rotate);
};
return RotateManager;
}();
export { RotateManager as default };