Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >图形编辑器基于Paper.js教程16:在Paper.js canvas画布中实现花贝塞尔曲线的功能,创建并编辑贝塞尔曲线,包括添加、删除曲线的节点,以及调整曲线的控制柄

图形编辑器基于Paper.js教程16:在Paper.js canvas画布中实现花贝塞尔曲线的功能,创建并编辑贝塞尔曲线,包括添加、删除曲线的节点,以及调整曲线的控制柄

作者头像
拿我格子衫来
发布于 2024-11-21 05:52:20
发布于 2024-11-21 05:52:20
22604
代码可运行
举报
文章被收录于专栏:TopFETopFE
运行总次数:4
代码可运行
使用 Paper.js 实现花贝塞尔曲线的交互工具

在图形编辑中,贝塞尔曲线因其灵活的曲线控制而被广泛应用,特别是在设计软件和矢量绘图工具中。在本文中,我将深入解析一个基于 Paper.js 的交互式贝塞尔曲线编辑工具。通过这个工具,你可以在画布上创建并编辑贝塞尔曲线,包括添加、删除曲线的节点(称为“段”),以及调整曲线的控制柄(称为 handleIn 和 handleOut)。

Paper.js 初始化

程序首先利用 paper.setup() 函数将 Paper.js 初始化到 HTML 中的一个 <canvas> 元素中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
paper.setup(document.getElementById('myCanvas'));

这一步会将 Paper.js 绑定到特定的 <canvas>,从而让后续的所有绘制和交互操作都可以在这个画布上进行。

基本变量的定义

在工具功能实现之前,定义了一些基本的全局变量用于保存当前的编辑状态和交互对象:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var options = {};
tool = new paper.Tool();
var path;
var currentSegment;
var mode;
var type;
var hoveredItem = null;
  • path:当前操作的贝塞尔曲线对象。
  • currentSegment:当前正在操作的曲线段。
  • modetype:保存操作的类型和模式,比如添加、删除或者调整控制柄。
  • hoveredItem:鼠标悬停的对象,用于交互时提供即时反馈。
鼠标事件处理

接下来,我们来看核心的鼠标事件处理器,这些处理器负责用户的交互操作,如点击、拖动和松开鼠标时的响应。

onMouseDown - 创建和选择段

tool.onMouseDown 事件处理器负责在画布上添加新的贝塞尔曲线段或选中已有的段。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 原创由CSDN@拿我格子衫来
tool.onMouseDown = function (event) {
  if (event.event.button > 0) return;

  if (currentSegment) {
    currentSegment.selected = false;
  }
  mode = type = currentSegment = null;

  if (!path) {
    if (!hoveredItem) {
      path = new paper.Path();
    } else {
      if (!hoveredItem.item.closed) {
        mode = 'continue';
        path = hoveredItem.item;
        currentSegment = hoveredItem.segment;
        if (hoveredItem.item.lastSegment !== hoveredItem.segment) {
          path.reverse();
        }
      } else {
        path = hoveredItem.item;
      }
    }
  }
  
  // 查找当前段并进行相应操作
  var result = findHandle(path, event.point);
  if (result && mode !== 'continue') {
    currentSegment = result.segment;
    type = result.type;
    if (result.type === 'point') {
      if (result.segment.index === 0 && path.segments.length > 1 && !path.closed) {
        mode = 'close';
        path.closed = true;
        path.firstSegment.selected = true;
      } else {
        mode = 'remove';
        result.segment.remove();
      }
    }
  }
  // 原创由CSDN@拿我格子衫来
  if (!currentSegment) {
    if (hoveredItem) {
      if (hoveredItem.type === 'segment' && !hoveredItem.item.closed) {
        var hoverPath = hoveredItem.item;
        if (hoverPath.firstSegment !== hoveredItem.segment) {
          hoverPath.reverse();
        }
        path.join(hoverPath);
        path = null;
      } else if (hoveredItem.type === 'curve' || hoveredItem.type === 'stroke') {
        mode = 'add';
        var location = hoveredItem.location;
        currentSegment = path.insert(location.index + 1, event.point);
        currentSegment.selected = true;
      }
    } else {
      mode = 'add';
      currentSegment = path.add(event.point);
      currentSegment.selected = true;
    }
  }
};

这个函数主要负责:

  • 创建新路径:当用户点击空白区域时,会创建一条新的贝塞尔路径。
  • 选中已有路径段:如果点击现有的曲线段,程序会选中该段,并允许用户进行编辑操作,如调整控制柄或删除该段。
  • 连接路径:当点击另一个未闭合的路径时,工具会自动反转路径并将其连接到当前路径。
onMouseMove - 悬停检测

tool.onMouseMove 处理器负责检测用户当前的鼠标位置是否悬停在某个路径段上,并实时更新交互反馈:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 原创由CSDN@拿我格子衫来
tool.onMouseMove = function (event) {
  var hitResult = paper.project.hitTest(event.point, hitOptions);
  if (hitResult && hitResult.item && hitResult.item.selected) {
    hoveredItem = hitResult;
  } else {
    hoveredItem = null;
  }
};

这里的 hitTest 函数是 Paper.js 提供的一个强大的检测工具,用于判断用户点击或悬停时是否命中了某个对象。hitOptions 设定了检测的范围和具体条件,例如是否检测线条、曲线或者段等。

onMouseDrag - 控制柄调整

当用户拖动鼠标时,tool.onMouseDrag 事件处理器会实时更新当前段的控制柄位置,从而改变曲线的形状。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
tool.onMouseDrag = function (event) {
  if (event.event.button > 0) return;

  var delta = event.delta.clone();
  if (type === 'handleOut' || mode === 'add') {
    delta = new paper.Point(0, 0).subtract(delta);
  }
  currentSegment.handleIn = currentSegment.handleIn.add(delta);
  currentSegment.handleOut = currentSegment.handleOut.subtract(delta);
};

该函数通过更新 handleInhandleOut 控制柄的坐标,使得用户能够对贝塞尔曲线的曲率进行细致调整。当拖动时,控制柄的移动方向会与鼠标的移动量 delta 同步,从而动态调整曲线的形状。

onMouseUp - 完成编辑

tool.onMouseUp 事件处理器用于在用户完成编辑操作时,重置一些状态并结束操作模式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
tool.onMouseUp = function (event) {
  if (event.event.button > 0) return;

  if (path && path.closed) {
    path = null;
  }
};

此函数简单但重要:当用户松开鼠标并且路径已经闭合时,重置 path,以便下次继续新的操作。

辅助函数:查找控制柄

一个关键的辅助函数 findHandle 用于判断用户当前点击的位置是否接近某个曲线段的控制柄或控制点:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function findHandle(path, point) {
  var types = ['point', 'handleIn', 'handleOut'];
  for (var i = 0, l = path.segments.length; i < l; i++) {
    for (var j = 0; j < 3; j++) {
      var type = types[j];
      var segment = path.segments[i];
      var segmentPoint = type === 'point'
        ? segment.point
        : segment.point.add(segment[type]);
      var distance = point.subtract(segmentPoint).length;
      if (distance < 6) {
        return {
          type: type,
          segment: segment
        };
      }
    }
  }
  // 原创由CSDN@拿我格子衫来
  return null;
}

这个函数遍历路径中的所有段,并检查鼠标点击点是否靠近某个控制点或控制柄(通过计算点与控制点之间的距离)。如果距离足够近(如小于 6 像素),则返回该控制点的信息,供后续处理使用。

总结

通过以上代码,我们实现了一个功能完备的贝塞尔曲线编辑工具,用户可以创建新的曲线段、选中并修改现有的段、调整控制柄、甚至连接不同的路径。这种基于 Paper.js 的解决方案展示了其强大的图形处理能力以及灵活的事件系统。结合实际应用场景,该工具可以进一步扩展,满足更复杂的设计需求。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-10-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
图形编辑器基于Paper.js教程03:认识Paper.js中的所有类
Paper.js 中的项目对象通常被称为文档:它是顶级对象,包含场景图中的所有项目。由于文档一词在浏览器上下文中已被使用,因此它被称为 Project。
拿我格子衫来
2024/07/15
6170
图形编辑器基于Paper.js教程03:认识Paper.js中的所有类
图形编辑器基于Paper.js教程07:鼠标画直线或移动路径
在数字图形设计和Web应用开发中,提供一个直观和互动的界面供用户绘制图形是极为重要的。Paper.js是一款功能强大的JavaScript库,它使得在HTML5 Canvas上绘制矢量图形变得简单快捷。本文将介绍如何使用Paper.js实现一个基本的图形绘制工具,允许用户用鼠标画出直线和自由曲线(轨迹)。
拿我格子衫来
2024/07/15
2500
图形编辑器基于Paper.js教程07:鼠标画直线或移动路径
图形编辑器基于Paper.js教程04: Paper.js中的基础知识
paper.js 提供了两种编写方式,一种是纯粹的JavaScript编写,还有一种是使用官方提供的PaperScript。 区别就是在于,调用paper下的字对象是否需要加paper,以及向量的加减乘除。 下面看一下两种写法
拿我格子衫来
2024/07/15
2160
图形编辑器基于Paper.js教程04: Paper.js中的基础知识
图形编辑器基于Paper.js教程05:鼠标画矩形与正方形
在图形应用开发中,准确和高效地处理用户输入,如鼠标事件,是提升用户体验的关键。本文通过一个使用Paper.js的示例,展示如何优化矩形绘制过程,特别是处理不同方向的拖拽动作。
拿我格子衫来
2024/07/15
2120
图形编辑器基于Paper.js教程05:鼠标画矩形与正方形
图形编辑器基于Paper.js教程14:使用 Paper.js 绘制数学图形与交互的实现,画布缩放保持大小的圆,正弦,余弦,螺旋线
在现代Web开发中,动态图形和交互式视觉表现已成为提升用户体验的重要手段。通过一个详细的示例,我们将探索如何使用 Paper.js 进行数学图形(正弦曲线、余弦曲线和螺旋线)的绘制,并实现固定尺寸的圆形及其随视图缩放的调整。此外,本文将深入分析鼠标滚轮和拖动事件处理的缩放与视图移动实现。
拿我格子衫来
2024/08/15
2470
图形编辑器基于Paper.js教程14:使用 Paper.js 绘制数学图形与交互的实现,画布缩放保持大小的圆,正弦,余弦,螺旋线
图形编辑器基于Paper.js教程12:井身结构编辑器,多条完全平行的弯曲线,使用额外平行线来作为弯曲中心线的度量尺
对于弯曲的三条平行线,一开始我以为只需要使用中心线,然后复制两条,一个向右下角平移,一个向左上角平移,就能让三条线实现完全平行,每一处的距离都相等。后来仔细思考后,发现我想错了,因为弯曲处的平行距离是,x移动,y移动的平方根。后来想使用曲线的缩放加上平移来实现三条线段弯曲平行,曲线部分依然无法达到完全平行。
拿我格子衫来
2024/08/06
1690
图形编辑器基于Paper.js教程12:井身结构编辑器,多条完全平行的弯曲线,使用额外平行线来作为弯曲中心线的度量尺
图形编辑器开发:钢笔工具的实现
像是 SVG 的 Path 的元素,单段的线有直线、圆弧、椭圆弧、二阶贝塞尔曲线、三阶段贝塞尔曲线等。
前端西瓜哥
2024/04/19
2230
图形编辑器开发:钢笔工具的实现
图形编辑器基于Paper.js教程08:鼠标画封闭的自由多边形,靠近起点自动关闭
在这篇技术博客中,我们将深入探讨如何使用 Paper.js 实现一个基本的图形绘制应用,允许用户在画布上绘制封闭的多边形。Paper.js 是一个强大的向量图形脚本库,它简化了在网页上进行图形和交互式界面设计的过程。本文主要围绕上述代码进行解析,揭示其实现逻辑和关键技术点。
拿我格子衫来
2024/07/15
3190
图形编辑器基于Paper.js教程08:鼠标画封闭的自由多边形,靠近起点自动关闭
图形编辑器基于Paper.js教程09:鼠标拖动画布,以鼠标点为缩放中心进行视图的缩放
在Web开发中,利用Paper.js库进行图形的绘制和交互操作是一种常见的实践。Paper.js是一个强大的矢量图形库,可以让开发者通过简洁的API完成复杂的图形操作。在本文中,我们将详细探讨如何使用Paper.js来实现对画布的缩放和拖动功能,提供用户友好的交互体验。 (作者:CSDN@拿我格子衫来)
拿我格子衫来
2024/07/23
2910
图形编辑器基于Paper.js教程09:鼠标拖动画布,以鼠标点为缩放中心进行视图的缩放
图形编辑器基于Paper.js教程06:鼠标画圆与椭圆
在Web应用中实现交互式图形绘制功能,对于提高用户体验至关重要,尤其是在设计和艺术相关的应用中。Paper.js是一款强大的JavaScript库,专门用于处理矢量图形,它提供了一套简洁的API来操作HTML5的Canvas元素。本文通过一个实际例子,探讨如何使用Paper.js来实现椭圆和圆形的绘制。
拿我格子衫来
2024/07/15
1710
图形编辑器基于Paper.js教程06:鼠标画圆与椭圆
图形编辑器基于Paper.js教程26:如何在canvas上实现无线网格的功能,高性能,共用网格线
最近在重构TC的UI部分,新版的设计中有一个无限网格线的功能,简单理解就是你的画布上,每隔10px就有一条垂直线或水平线,参考 啄木鸟激光的 软件 LaserPecker 如下图:
拿我格子衫来
2025/04/15
1040
图形编辑器基于Paper.js教程26:如何在canvas上实现无线网格的功能,高性能,共用网格线
图形编辑器开发:钢笔工具功能说明书
只有理解了需求,尤其是复杂的需求,才能更好地进行功能开发,写出诗一样的高鲁棒性代码。
前端西瓜哥
2024/01/26
3270
图形编辑器开发:钢笔工具功能说明书
图形编辑器基于Paper.js教程15:在Paper.js中实现拖拽图片导入画布功能
在现代Web开发中,用户体验是至关重要的。而拖拽文件上传的功能,不仅直观易用,还提升了用户与界面的交互体验。在这篇文章中,我们将探讨如何使用Paper.js和HTML5的拖放API,来实现将图片文件直接拖拽并导入到Paper.js的画布中。本文将详细解释其中的关键代码段,并帮助您深入理解实现该功能的技术要点。
拿我格子衫来
2024/08/20
3530
图形编辑器基于Paper.js教程15:在Paper.js中实现拖拽图片导入画布功能
图形编辑器基于Paper.js教程13:基于 Paper.js 的自动重置圆形运动程序,按钮控制运动,按键控制运动,websocket控制运动
本技术博客详细分析了一个基于 Paper.js 库的动画实现代码。我们将逐一探讨代码的核心功能,包括实现动态圆形移动、用户交互、自动重置和视图调整的逻辑。
拿我格子衫来
2024/08/09
2510
图形编辑器基于Paper.js教程13:基于 Paper.js 的自动重置圆形运动程序,按钮控制运动,按键控制运动,websocket控制运动
图形编辑器基于Paper.js教程10:导入导出svg,导入导出json数据
Paper.js是一款强大的矢量绘图JavaScript库,非常适合用于复杂的图形处理和交互式网页应用。本文将详细介绍如何在Paper.js项目中实现SVG和JSON格式的导入导出功能,这对于开发动态图形编辑器等应用尤为重要。
拿我格子衫来
2024/08/06
4940
图形编辑器基于Paper.js教程10:导入导出svg,导入导出json数据
【计算机视觉】二、图像形成——实验:2D变换编辑器2.0(Pygame)
  几何基元是计算机图形学中最基本的图形对象,它们是构建更复杂图形的基础单元。常见的几何基元包括:
Qomolangma
2024/07/30
1660
【计算机视觉】二、图像形成——实验:2D变换编辑器2.0(Pygame)
图形编辑器基于Paper.js教程11:使用Paper.js和Opentype.js加载自定义字体的技术实现解析
在现代Web开发中,字体处理和自定义显示成为了视觉设计的重要部分。本文将详细探讨如何使用Paper.js和Opentype.js在HTML5 canvas上实现自定义字体的加载与显示。我们将通过分析一段实际代码来理解关键技术实现及其难点。
拿我格子衫来
2024/08/06
3650
图形编辑器基于Paper.js教程11:使用Paper.js和Opentype.js加载自定义字体的技术实现解析
图形编辑器基于Paper.js教程21:在画布中创建一个不随视图缩放的矩形,并固定在视图的位置,标尺功能的实现
在图形编辑器中,一般都会有标尺的功能,标尺工具,能够让用户建立清晰的坐标系,能够知道原点在那里,并且能够大致估算出,尺寸,距离,和当前光标所在的位置。 如下图标尺所在的位置:
拿我格子衫来
2025/01/22
2320
图形编辑器基于Paper.js教程21:在画布中创建一个不随视图缩放的矩形,并固定在视图的位置,标尺功能的实现
图形编辑器基于Paper.js教程22:在图形矢量编辑器中,实现两个元素的差集,交集,并集,切割
像这种图形其实是基于相交的圆和矩形进行计算得出来的,这种操作大家一般叫做图形的布尔操作。 本片文章就教大家如何在图形编辑器中,实现 两个元素的差集,并集,合并,或者切割。
拿我格子衫来
2025/01/25
1340
图形编辑器基于Paper.js教程22:在图形矢量编辑器中,实现两个元素的差集,交集,并集,切割
一篇文章,Vue快速入门!!!
MVVM源自于经典的MVC(Model-View-Controller)模式。MVVM的核心是ViewModel层,负责转换Model中的数据对象来让数据变得更容易管理和使用。其作用如下:
全栈程序员站长
2022/08/19
1.9K0
一篇文章,Vue快速入门!!!
推荐阅读
图形编辑器基于Paper.js教程03:认识Paper.js中的所有类
6170
图形编辑器基于Paper.js教程07:鼠标画直线或移动路径
2500
图形编辑器基于Paper.js教程04: Paper.js中的基础知识
2160
图形编辑器基于Paper.js教程05:鼠标画矩形与正方形
2120
图形编辑器基于Paper.js教程14:使用 Paper.js 绘制数学图形与交互的实现,画布缩放保持大小的圆,正弦,余弦,螺旋线
2470
图形编辑器基于Paper.js教程12:井身结构编辑器,多条完全平行的弯曲线,使用额外平行线来作为弯曲中心线的度量尺
1690
图形编辑器开发:钢笔工具的实现
2230
图形编辑器基于Paper.js教程08:鼠标画封闭的自由多边形,靠近起点自动关闭
3190
图形编辑器基于Paper.js教程09:鼠标拖动画布,以鼠标点为缩放中心进行视图的缩放
2910
图形编辑器基于Paper.js教程06:鼠标画圆与椭圆
1710
图形编辑器基于Paper.js教程26:如何在canvas上实现无线网格的功能,高性能,共用网格线
1040
图形编辑器开发:钢笔工具功能说明书
3270
图形编辑器基于Paper.js教程15:在Paper.js中实现拖拽图片导入画布功能
3530
图形编辑器基于Paper.js教程13:基于 Paper.js 的自动重置圆形运动程序,按钮控制运动,按键控制运动,websocket控制运动
2510
图形编辑器基于Paper.js教程10:导入导出svg,导入导出json数据
4940
【计算机视觉】二、图像形成——实验:2D变换编辑器2.0(Pygame)
1660
图形编辑器基于Paper.js教程11:使用Paper.js和Opentype.js加载自定义字体的技术实现解析
3650
图形编辑器基于Paper.js教程21:在画布中创建一个不随视图缩放的矩形,并固定在视图的位置,标尺功能的实现
2320
图形编辑器基于Paper.js教程22:在图形矢量编辑器中,实现两个元素的差集,交集,并集,切割
1340
一篇文章,Vue快速入门!!!
1.9K0
相关推荐
图形编辑器基于Paper.js教程03:认识Paper.js中的所有类
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验