返回介绍

自定义控件 API

发布于 2024-11-08 20:02:01 字数 4714 浏览 0 评论 0 收藏 0

这个 api 是针对 FabricJS4.0 的,api 和文本目前处于测试阶段。为了使命名和选项尽可能简单,在发布之前可能会发生一些小的变化。

Introduction

此 API​ 允许开发人员创建自己的自定义控件,而不必对标准 fabricJS 控件方法使用重写。这使得自定义支持,容易,并使更新到最新版本总是可能的。

FabricJS 在内部使用 api 来定义标准控件集,这些控件集具有与版本 3 及更低版本中相同的功能和定制。

How does it work.

现在 fabric.Object prototype 有一个控制集,控制集只是一个普通的 js 对象,它有一组键,每个键的值都是一个 fabric.Control class。为简化标准控件集,键保留了旧名称 tl、mt、tr、mr、br、mb、bl、ml 和 mtr。

不同的是,绘制控件的代码不再知道任何关于控件的信息,而是将循环到此控件集的键并绘制每个控件。

默认情况下,所有 fabricJS 对象共享相同的控件集,但 textbox 有不同的控件,可以更改宽度而不是缩放。

没有什么可以阻止您为每个子类创建不同的控件集,或者在每个地方都有相同的控件集,并根据当前渲染的对象使控件可见/隐藏。

Structure of a control

control 是定位函数、渲染函数、样式函数、可见性函数、actionHandler 和一组其他属性的集合,这些属性从 fabricJS 以正确的顺序调用和使用。有些属性是可选的,取决于控件的实现。

让我们看看 fabricJS 控件是如何在库本身中定义的,以标准对象的控件 mr 为例:

objectControls.mr = new fabric.Control({
  x: 0.5,
  y: 0,
  cursorStyleHandler: scaleSkewStyleHandler,
  actionHandler: scalingXOrSkewingY,
  getActionName: scaleOrSkewActionName,
});

该控件是完全可配置的,可以提供处理程序,也可以提供默认处理程序的值。

默认控件在此处定义: 标准控件定义

visible and getVisibility

在 FabricJS 4.0 之前,控件可以设置为不可见,可以忽略。现在控件可以存在,也可以不存在,但也可以是临时不可变的,具体取决于对象状态。

控件的默认 getVisibility 函数将返回标准的 object_controlsVisibility 属性,该属性由于兼容性的原因而被忽略,如果未设置,则返控件 .visible 值。

控件通常在实例之间共享,因此将控件设置为.visible=false 将对所有对象隐藏它,而将对象方法用于控件可见性将对每个对象隐藏。

actioname and getActionName

属性 actionName 给出了控件可能执行的操作的名称。这用于在操作期间触发事件,FabricJS 也用于标识用户在进行一些额外的优化时正在做的事情。如果您正在编写自定义控件,并且想知道代码中其他地方的情况,则可以在此处使用此字符串并监听结果事件。

事件的旧命名约定仍然受到尊重。因此,缩放操作仍将触发事件缩放和 object:scaling。但也会触发额外的事件 scale 或 scaleX,因为这是动作名称。因此,在创建自定义动作处理程序时(如果需要),您可以选择是否在动作处理程序中以您想要的名称显式触发事件,还是让 Fabric 触发与动作名称相同的事件。

请注意,不要对正在使用的默认 fabricJS 事件进行 namig 操作。

如果控件根据某些外部状态运行多个操作,还可以提供自定义 getActionName。

例如,旧的 mr 控件可以用于 2 个动作,缩放或倾斜,结果取决于修改器键。

angle

标准 fabricJS 函数中未使用角度,如果需要具有方向的控件,并且在此处希望将其复用为不同的方向来使用它,请在此处将其编写为一个选项,以使其可以查找控件的角度。

请勿将其用于其他用途,在将来的版本中,我们可能会决定使用它来旋转控件。

x and y

x 和 y 代表默认 positionHandler 使用的位置。对于放置在对象边界框上的大多数控件而言,默认位置处理程序已经足够好。 x 和 y 的值表示边界框的大小,包括填充。

对于整个边界框,这些值的范围从-0.5 到 0.5,但是如果您需要将它们放置在很远的地方,则可以进一步扩展。 {x:0.5,y:0}将使控件在边界框右侧的垂直中心对齐。

offsetX and offsetY

offsetX 和 offsetY 可让您以屏幕像素为单位偏移控件位置。一个典型的示例是标准旋转控件,该控件从边界框偏移了大约 30px。Offsets 代替 fabric3.x 的 rotationPointOffset,现在可以将其应用于所有控件。 rotationPointOffset 消失了。

withConnection

布尔值,指示控件(如果是偏移)是否与具有线到位置点的边界框连接。只是一个图形选项,没有功能。

cursorStyle and cursorStyleHandler

cursorStyleHandler 是一个函数,负责将鼠标悬停在控件上时显示的光标。

此特定功能需要显示一个不允许的光标,或者显示一个对齐的用于偏斜或缩放的光标。该函数需要为您可以使用的浏览器返回一个有效的游标。内联 url 编码的 SVG 也是可能的。

function changeWidth(eventData, transform, x, y) {
  var target = transform.target, localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y),
      strokePadding = target.strokeWidth / (target.strokeUniform ? target.scaleX : 1),
      newWidth = Math.abs(localPoint.x / target.scaleX) - strokePadding;
  target.set('width', Math.max(newWidth, 0));
  return true;
}

该函数获取鼠标事件数据,因此可以确定是否按下了某个热键,然后针对某个动作或其他动作运行特定逻辑。然后,skewCursorStyleHandler 或 scaleCursorStyleHandler 将处理一个动作或另一个动作的特定逻辑。现有的 fabricJS 功能的所有样式处理均已编写,并作为示例,以防您需要编写其他游标逻辑。

如果您的自定义控件始终显示相同的光标,则可以保留默认处理程序,并通过设置 cursorStyle 属性来更改该控件。

mouseUpHandler and mouseDownHandler

如果需要,您可以将控件用作一次单击按钮,而不是将其连接以使用鼠标拖动动作。一个经典的示例是删除对象或克隆对象的控件,如本例中更好地描述的那样: 自定义控件渲染和操作 。或另一种可能是翻转对象。

actionHandler

该功能绝对是掌握起来最复杂的功能,它使您可以编写自定义操作。我们可以看一下简单的宽度转换器功能:

function changeWidth(eventData, transform, x, y) {
  var target = transform.target, localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y),
      strokePadding = target.strokeWidth / (target.strokeUniform ? target.scaleX : 1),
      newWidth = Math.abs(localPoint.x / target.scaleX) - strokePadding;
  target.set('width', Math.max(newWidth, 0));
  return true;
}

参数:eventData 是鼠标事件对象,transform 是一个普通的 js 对象,其中包含 transform.target,我们要转换的对象 x 和 y 表示距转换锚点的像素距离。

此函数处理文本框的侧面控件,但也可以按原样使用在 rects 上,创建另一个用于更改高度的控件很简单,只需将与宽度相关的属性交换为与高度相关的属性即可。

另一个简单的扩展是使其更改椭圆的 rx,ry 或圆的半径。

进行缩放和倾斜计算会更加复杂。请注意,尽管 api 提供了完全的自由度,但为控件编写动作并不容易。当几何学发挥作用时,了解 fabricJS 内部结构非常重要。实际操作只是一个示例,但是由于必须支持,因此代码的方式变得更加复杂:scalingFlip,lockScaling,centerTransfrom,freeformScaling 和其他 fabricJS 属性。

如果您认为部分代码可用于您自己的操作(例如 wrapWithFixedAnchor),请打开一个 issue,要求将其分开并将其放在自己的函数中。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文