UNPKG

mskalign-canvas

Version:

一个用于图片标注的javascript库,基于canvas,简单轻量,支持矩形、多边形、点、折线、圆形。

349 lines (251 loc) 7.32 kB
# 面向对象脊椎曲线系统库 基于 NURBS 曲线的脊椎模拟系统,采用面向对象设计,便于在其他项目中集成和使用。 ## 特性 - 🎯 **面向对象设计**:清晰的类结构,易于扩展和维护 - 🔧 **灵活配置**:支持多种参数配置,适应不同需求 - 🖱️ **交互式操作**:支持鼠标拖拽、悬停等交互 - 📊 **状态管理**:支持导出/导入状态,便于数据持久化 - 🎨 **可视化效果**:支持网格、连接线、发光效果等视觉元素 - 🔄 **实时物理约束**:模拟真实脊椎的物理特性 ## 快速开始 ### 1. 引入依赖 ```html <!-- 引入 verb-nurbs 库 --> <script src="https://unpkg.com/verb-nurbs"></script> <!-- 引入脊椎系统库 --> <script src="spine-system.js"></script> ``` ### 2. 创建 HTML 结构 ```html <canvas id="spineCanvas" width="400" height="600"></canvas> ``` ### 3. 初始化脊椎系统 ```javascript // 脊椎点数据:[x, y] 坐标数组 const spineData = [ [200, 50], [201, 70], [202, 90], [203, 110], [204, 130], [205, 150], [206, 170], [207, 190], [208, 210], [209, 230], ]; // 获取canvas元素 const canvas = document.getElementById("spineCanvas"); // 创建脊椎系统实例 const spineSystem = new SpineSystem(canvas, spineData, { influence: 1.5, // 影响强度 curveDegree: 2, // 曲线次数 smoothness: 0.3, // 平滑度 influenceRange: 4, // 影响范围 showGrid: true, // 显示网格 }); // 渲染系统 spineSystem.render(); ``` ## 核心类介绍 ### SpineSystem - 主系统类 主要的脊椎系统类,协调所有组件的工作。 #### 构造函数 ```javascript new SpineSystem(canvas, initialData, options); ``` - `canvas`: HTML Canvas 元素 - `initialData`: 初始脊椎点数据,格式为 `[[x1, y1], [x2, y2], ...]` - `options`: 配置选项对象 #### 配置选项 ```javascript const options = { influence: 1.5, // 影响强度 (0.1 - 2.5) curveDegree: 2, // 曲线次数 (2 - 5) smoothness: 0.3, // 平滑度 (0.1 - 2.0) influenceRange: 4, // 影响范围 (3 - 12) showGrid: true, // 显示网格 }; ``` #### 主要方法 ```javascript // 更新配置 spineSystem.updateConfig(newConfig); // 重置到初始状态 spineSystem.reset(); // 获取当前点位置 const points = spineSystem.getPoints(); // 获取原始点位置 const originalPoints = spineSystem.getOriginalPoints(); // 导出当前状态 const state = spineSystem.exportState(); // 导入状态 spineSystem.importState(state); // 手动渲染 spineSystem.render(); // 销毁实例 spineSystem.destroy(); ``` ### SpinePoint - 脊椎点类 表示脊椎上的一个点。 #### 属性 ```javascript point.x, point.y; // 当前坐标 point.originalX, point.originalY; // 原始坐标 point.index; // 点的索引 point.isEndPoint; // 是否为端点 point.isHovered; // 是否被悬停 point.isDragged; // 是否被拖拽 point.influenceState; // 影响状态:'normal' | 'influenced' | 'lightlyFollowing' ``` #### 方法 ```javascript // 重置到原始位置 point.reset(); // 计算到指定坐标的距离 const distance = point.distanceTo(x, y); // 获取点的颜色 const color = point.getColor(); // 获取点的半径 const radius = point.getRadius(); ``` ### SpinePhysics - 物理系统类 处理脊椎的物理约束和影响计算。 #### 方法 ```javascript // 应用物理约束 physics.applyConstraints(points, smoothness); // 应用影响效果 physics.applyInfluence(points, dragIndex, dragOffset, config); // 计算三点间的角度 const angle = physics.calculateAngle(p1, p2, p3); ``` ### SpineRenderer - 渲染器类 负责所有的绘制工作。 #### 方法 ```javascript // 清空画布 renderer.clear(); // 绘制网格 renderer.drawGrid(); // 绘制NURBS曲线 renderer.drawNurbsCurve(curve, smoothness); // 绘制连接线 renderer.drawConnectionLines(points); // 绘制脊椎点 renderer.drawPoints(points); // 绘制悬停信息 renderer.drawHoverInfo(point, mouseX, mouseY); ``` ### SpineInteraction - 交互处理类 处理鼠标交互逻辑。 #### 方法 ```javascript // 获取鼠标位置 const pos = interaction.getMousePosition(); // 获取悬停的点 const hoveredPoint = interaction.getHoveredPoint(); ``` ## 使用示例 ### 基本使用 ```javascript const spineSystem = new SpineSystem(canvas, spineData); spineSystem.render(); ``` ### 动态更新配置 ```javascript // 监听滑块变化 document.getElementById("influenceSlider").addEventListener("input", (e) => { spineSystem.updateConfig({ influence: parseFloat(e.target.value) }); }); ``` ### 状态管理 ```javascript // 保存状态 const currentState = spineSystem.exportState(); localStorage.setItem("spineState", JSON.stringify(currentState)); // 恢复状态 const savedState = JSON.parse(localStorage.getItem("spineState")); spineSystem.importState(savedState); ``` ### 多实例使用 ```javascript // 创建多个独立的脊椎系统 const spineSystem1 = new SpineSystem(canvas1, spineData1, config1); const spineSystem2 = new SpineSystem(canvas2, spineData2, config2); // 各自独立运行 spineSystem1.render(); spineSystem2.render(); ``` ## 高级用法 ### 自定义物理约束 ```javascript // 继承并扩展物理系统 class CustomSpinePhysics extends SpinePhysics { applyConstraints(points, smoothness) { // 先应用基础约束 super.applyConstraints(points, smoothness); // 添加自定义约束 this.applyCustomConstraints(points); } applyCustomConstraints(points) { // 自定义约束逻辑 } } // 使用自定义物理系统 const customSpineSystem = new SpineSystem(canvas, spineData); customSpineSystem.physics = new CustomSpinePhysics(); ``` ### 自定义渲染效果 ```javascript // 继承并扩展渲染器 class CustomSpineRenderer extends SpineRenderer { drawPoints(points) { // 先绘制基础点 super.drawPoints(points); // 添加自定义效果 this.drawCustomEffects(points); } drawCustomEffects(points) { // 自定义绘制逻辑 } } // 使用自定义渲染器 const customSpineSystem = new SpineSystem(canvas, spineData); customSpineSystem.renderer = new CustomSpineRenderer(canvas); ``` ## 事件监听 ```javascript // 可以通过覆盖交互处理方法来添加自定义事件 class CustomSpineInteraction extends SpineInteraction { handleMouseDown(e) { // 调用原始处理 super.handleMouseDown(e); // 添加自定义逻辑 console.log("点击了脊椎点"); } } ``` ## 性能优化建议 1. **避免频繁重绘**:只在必要时调用 `render()` 方法 2. **合理设置参数**:过高的平滑度会影响性能 3. **控制点数量**:建议脊椎点数量在 10-20 个之间 4. **使用 requestAnimationFrame**:对于动画效果,使用 RAF 优化 5. **及时销毁**:页面卸载时调用 `destroy()` 方法 ## 浏览器兼容性 - Chrome 60+ - Firefox 55+ - Safari 12+ - Edge 79+ ## 依赖库 - [verb-nurbs](https://github.com/pboyer/verb): NURBS 曲线计算库 ## 许可证 MIT License ## 贡献 欢迎提交 Issue 和 Pull Request 来改进这个库。 ## 更新日志 ### v1.0.0 - 初始版本发布 - 支持基本的脊椎曲线模拟 - 面向对象设计 - 完整的 API 文档