UNPKG

@sanyueqi/web-components

Version:

Web components

179 lines (148 loc) 6.8 kB
(function (factory) { typeof define === 'function' && define.amd ? define(factory) : factory(); })((function () { 'use strict'; /** * 创建可拖动的Spine动画元素 * @param {Object} config - 配置对象 * @param {string} config.id - div元素的id,默认'drag-waifu' * @param {string} config.width - div宽度,默认'200px' * @param {string} config.height - div高度,默认'200px' * @param {string} config.top - 初始top位置 * @param {string} config.bottom - 初始bottom位置 * @param {string} config.left - 初始left位置 * @param {string} config.right - 初始right位置 * @param {Array} config.spineConfig - Spine动画配置数组 * @returns {Object} 返回包含销毁方法的对象 */ function createDraggableWaifu(config = {}) { const { position = 'fixed', id = 'drag-waifu', width = '200px', height = '200px', top, bottom = '0', left = '0', right, spineConfig } = config; // 创建可拖动的div元素 const draggableDiv = document.createElement('div'); draggableDiv.id = id; // 设置div样式 - 使用fixed布局 draggableDiv.style.width = width; draggableDiv.style.height = height; draggableDiv.style.position = position; draggableDiv.style.cursor = 'move'; draggableDiv.style.display = 'flex'; draggableDiv.style.alignItems = 'center'; draggableDiv.style.justifyContent = 'center'; draggableDiv.style.color = 'white'; draggableDiv.style.fontFamily = 'Arial, sans-serif'; draggableDiv.style.fontWeight = 'bold'; draggableDiv.style.userSelect = 'none'; draggableDiv.style.zIndex = '9999'; // 确保在其他元素之上 // 设置初始位置 if (top !== undefined) draggableDiv.style.top = top; if (bottom !== undefined) draggableDiv.style.bottom = bottom; if (left !== undefined) draggableDiv.style.left = left; if (right !== undefined) draggableDiv.style.right = right; // 添加到页面 document.body.appendChild(draggableDiv); // 拖拽功能变量 let isDragging = false; let offsetX, offsetY; // 鼠标按下事件处理函数 const mouseDownHandler = function(e) { isDragging = true; // 计算鼠标在元素内的位置 const rect = draggableDiv.getBoundingClientRect(); offsetX = e.clientX - rect.left; offsetY = e.clientY - rect.top; e.preventDefault(); }; // 鼠标移动事件处理函数 const mouseMoveHandler = function(e) { if (!isDragging) return; // 计算新位置 let newX = e.clientX - offsetX; let newY = e.clientY - offsetY; // 边界检查 - 确保不超出视口 const maxX = window.innerWidth - draggableDiv.offsetWidth; const maxY = window.innerHeight - draggableDiv.offsetHeight; newX = Math.max(0, Math.min(newX, maxX)); newY = Math.max(0, Math.min(newY, maxY)); // 应用新位置 draggableDiv.style.left = newX + 'px'; draggableDiv.style.top = newY + 'px'; // 清除其他定位属性 draggableDiv.style.bottom = ''; draggableDiv.style.right = ''; }; // 鼠标松开事件处理函数 const mouseUpHandler = function() { isDragging = false; }; // 窗口尺寸变化处理函数 const adjustPosition = function() { const rect = draggableDiv.getBoundingClientRect(); const windowWidth = window.innerWidth; const windowHeight = window.innerHeight; // 如果元素在屏幕外,则调整位置 if (rect.right < 0 || rect.bottom < 0 || rect.left > windowWidth || rect.top > windowHeight) { // 重置到右下角 draggableDiv.style.left = (windowWidth - draggableDiv.offsetWidth) + 'px'; draggableDiv.style.top = (windowHeight - draggableDiv.offsetHeight) + 'px'; draggableDiv.style.bottom = ''; draggableDiv.style.right = ''; } else { // 确保元素在视口内 let newX = parseFloat(draggableDiv.style.left) || 0; let newY = parseFloat(draggableDiv.style.top) || 0; const maxX = windowWidth - draggableDiv.offsetWidth; const maxY = windowHeight - draggableDiv.offsetHeight; newX = Math.max(0, Math.min(newX, maxX)); newY = Math.max(0, Math.min(newY, maxY)); draggableDiv.style.left = newX + 'px'; draggableDiv.style.top = newY + 'px'; } }; // 添加事件监听 draggableDiv.addEventListener('mousedown', mouseDownHandler); document.addEventListener('mousemove', mouseMoveHandler); document.addEventListener('mouseup', mouseUpHandler); window.addEventListener('resize', adjustPosition); // 初始化Spine动画 const spineManagerDrag = new SpineManager(`#${id}`, id); spineManagerDrag.init(spineConfig || [], true); // 返回销毁方法 return { destroy: function() { // 移除事件监听 draggableDiv.removeEventListener('mousedown', mouseDownHandler); document.removeEventListener('mousemove', mouseMoveHandler); document.removeEventListener('mouseup', mouseUpHandler); window.removeEventListener('resize', adjustPosition); // 移除元素 if (document.body.contains(draggableDiv)) { document.body.removeChild(draggableDiv); } // 销毁Spine管理器 if (spineManagerDrag && typeof spineManagerDrag.destroy === 'function') { spineManagerDrag.destroy(); } }, // 暴露调整位置方法供外部调用 adjustPosition: adjustPosition }; } // 导出函数 if (typeof module !== 'undefined' && module.exports) { module.exports = createDraggableWaifu; } if (typeof window !== 'undefined') { window.createDraggableWaifu = createDraggableWaifu; } }));