UNPKG

@xiaomengqiang/charts

Version:

hcharts library for web visualization

246 lines (238 loc) 9.77 kB
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 };