网站地图    收藏   

主页 > canvas引擎 > Fabricjs >

fabric.js·自定义控件 API

来源:未知    时间:2023-08-31 14:03 作者:小飞侠 阅读:

[导读] Custom controls api自定义控件 API This api is for fabricJS 4.0, the api and the text is currently in beta. Some little change could happen before release, in order to keep naming and options as simple as possible. 此 API 适用于 fab...

Custom controls api 自定义控件 API

This api is for fabricJS 4.0, the api and the text is currently in beta. Some little change could happen before release, in order to keep naming and options as simple as possible.
此 API 适用于 fabricJS 4.0,API 和文本目前处于测试阶段。在发布之前可能会发生一些小的变化,以使命名和选项尽可能简单。

Introduction 介绍

This api lets the developer create its own custom controls without having to use overrides on standard fabricJS controls method. This makes customizaion supported, easy and makes update to the latest version always possible.
此 API 允许开发人员创建自己的自定义控件,而无需对标准 fabricJS 控件方法使用覆盖。这使得自定义支持,变得容易,并使更新到最新版本始终成为可能。

FabricJS uses the api internally to define the standard controls set with the same feature and customization that was possible in version 3 and below.
FabricJS 在内部使用 API 来定义标准控件集,这些控件集具有与版本 3 及更低版本相同的功能和自定义功能。

How does it work.
它是如何工作的。

Now fabric.Object prototype has a control set, and a control set is simply a plain js object that has a set of keys, for each key the value is a fabric.Control class. For simplicity in the standard control set the keys are keeping the old names tl, mt, tr, mr, br, mb, bl, ml and mtr.
现在面料。对象原型有一个控件集,而控件集只是一个具有一组键的普通 js 对象,对于每个键的值都是一个 fabric.Control 类。为简单起见,标准控件集中的键保留旧名称 tl 、 mt tr mr br mb bl ml 和 mtr 。

The difference is that the code that draws the controls does not know anything anymore about the controls, but will loop over the keys of this controlset and draw each control.
不同之处在于,绘制控件的代码不再了解控件的任何信息,但将循环访问此控件集的键并绘制每个控件。

By default all fabricJS objects share the same controls set, exception made for the textbox that has different controls that make possible changing the width rather than scaling.
默认情况下,所有 fabricJS 对象共享相同的控件集,对于具有不同控件的文本框例外,这些控件可以更改宽度而不是缩放。

Nothing stops you from creating a different controls set for each subClass, or having the same control set everywhere and make controls visible/hidden depending on the object that is currently rendering.
没有什么能阻止您为每个子类创建不同的控件集,或者在任何地方设置相同的控件,并根据当前呈现的对象使控件可见/隐藏。

Structure of a control
控件的结构

A control is a collection of a positioning function, rendering function, style function, visibility function, an actionHandler and a bunch of other properties, called and used in the right order from fabricJS. Some of properties are optional and depends on the implementation of the control.
控件是定位函数、呈现函数、样式函数、可见性函数、actionHandler 和一堆其他属性的集合,这些属性以正确的顺序从 fabricJS 调用和使用。某些属性是可选的,取决于控件的实现。

Let’s see how fabricJS controls are defined in the library itself, let’s take for example the control mr of the standard object:
让我们看看 fabricJS 控件是如何在函数库本身中定义的,让我们以标准对象的控件 mr 为例:

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

The control is completely configurable, either providing handlers or providing values for the default handlers.
该控件是完全可配置的,可以提供处理程序或为默认处理程序提供值。

Default controls are defined here: standard controls definition.
此处定义了默认控件:标准控件定义。

visible and getVisibility
可见和获取可见性

Before FabricJS 4.0 controls could be set as non visible, to be ignored. Now controls can either exist, non exist, but also be temporary invsisible depending on object status.
在 FabricJS 4.0 控件可以设置为不可见之前,要忽略。现在,控件可以存在,也可以不存在,但也可以根据对象状态暂时不可入侵。

The default getVisibility function of the control will either return the standard object _controlsVisibility property that has been mantained for compatibility reason, or in case that is not set will return the control .visible value.
控件的默认 getVisibility 函数将返回出于兼容性原因而保留的标准对象 _controlsVisibility 属性,如果未设置,则将返回控件 .visible 值。

Controls are generally shared among instances, so setting a control to .visible = false will hide it for all the objects, while using the object methods for controls visibility will hide on a per object basis.
控件通常在实例之间共享,因此将控件设置为 将对所有对象隐藏它,而将对象方法用于控件可见性 .visible = false 将基于每个对象隐藏。

actioname and getActionName
actioname 和 getActionName

The property actionName gives the name of the action that the controll will likely execute. This is used to fire the event during the action, and also FabricJS uses to identify what the user is doing for some extra optimizations. If you are writing a custom control and you want to know somewhere else in the code what is going on, you can use this string here and listen to the resulting event.
属性 actionName 提供控件可能执行的操作的名称。这用于在操作期间触发事件,并且 FabricJS 也用于识别用户正在执行哪些操作以进行一些额外的优化。如果您正在编写自定义控件,并且想要了解代码中的其他位置发生了什么,则可以在此处使用此字符串并侦听生成的事件。

The old naming convention of events is still respected. So a scale action will still fire the event scaling and object:scaling. But will also fire an extra event scale or scaleX because that is the action name. So when creating your custom action handler ( if needed ) you can choose if explicitly fire an event with the name you want in your action handler or let fabric fire an event with the same name of the action name.
仍然遵守事件的旧命名约定。因此,规模操作仍将触发事件 scaling 和 object:scaling .但也会触发一个额外的事件 scale ,或者 scaleX 因为这是操作名称。因此,在创建自定义操作处理程序时(如果需要),您可以选择是在操作处理程序中显式触发具有所需名称的事件,还是让结构触发具有与操作名称相同的事件。

Be careful of not namig actions with default fabricJS event you are using.
请注意不要使用您正在使用的默认 fabricJS 事件进行命名操作。

You can also provide a custom getActionName if your control run multiple actions depending on some external state.
如果控件根据某些外部状态运行多个操作,还可以提供自定义 getActionName。

For example the old mr control can be used for 2 actions, scale or skew and the outcome is dependent from the modifier keys.
例如,旧 mr 控件可用于 2 个操作, scale 或者 skew 结果取决于修饰键。

angle 角度

Angle is not used from the standard fabricJS functions, is here as an option in case you need a control that has a direction, and you want to reuse your drawing function for different orientations, write it so that it can look up the control angle.
角度不是从标准的fabricJS函数中使用的,如果你需要一个有方向的控件,并且你想在不同的方向上重用你的绘图函数,在这里是一个选项,写它以便它可以查找控制角度。

Don’t use it for something different, in future version we may decide to use it to rotate controls.
不要将其用于其他用途,在将来的版本中,我们可能会决定使用它来旋转控件。

x and y x 和 y

X and y represent the position that is used by the default positionHandler. The default position handler is good enough for most of the controls placed on the object bounding box. The value of x and y represent the size of the bounding box, including padding.
X 和 y 表示默认位置处理程序使用的位置。默认位置处理程序对于放置在对象边界框上的大多数控件来说已经足够了。的值 x 和 y 表示边界框的大小,包括填充。

Those values range from -0.5 to 0.5 for the full bounding box, but can extend further if you need to postion them far away. {x: 0.5, y: 0} will align the control in the vertical center, on the right side of the bounding box.
对于整个边界框,这些值的范围从 -0.5 到 0.5,但如果需要将它们定位得很远,则可以进一步扩展。 {x: 0.5, y: 0} 将控件在边界框右侧的垂直中心对齐。

offsetX and offsetY 偏移量 X 和偏移量 Y

offsetX and offsetY let you offset the control position in screen pixels. A typical example is the standard rotation control, that is offseted from the bounding box by about 30px. Offsets are in place of the rotatingPointOffset of fabric 3.x and can now be applied to all controls. rotatingPointOffset is gone.
offsetX 和 offsetY 允许您以屏幕像素为单位偏移控制位置。一个典型的示例是标准旋转控件,它与边界框偏移约 30px。偏移量代替了 rotatingPointOffset 结构 3.x,现在可以应用于所有控件。 rotatingPointOffset 不见了。

withConnection 与连接

A boolean that indicates if the control, in case of offsets, is connected to the bounding box with a line to position point. Is just a graphic option and has no functionality.
一个布尔值,指示控件(如果存在偏移量)是否通过一条线连接到边界框到位置点。只是一个图形选项,没有任何功能。

cursorStyle and cursorStyleHandler
cursorStyle and cursorStyleHandler

cursorStyleHandler is a function that is responsible for the cursor displayed when the mouse is hovering over the control.
cursorStyleHandler 是一个函数,负责将鼠标悬停在控件上时显示的光标。

This particular function needs to show either a not-allowed cursor, or an aligned one for skew or scale. The function needs to return a valid cursor for the browser you can use. Inline url encoded SVG are a possibility too.
此特定函数需要显示不允许的光标,或用于倾斜或缩放的对齐光标。该函数需要为可以使用的浏览器返回有效的光标。内联 url 编码的 SVG 也是一种可能性。

function scaleSkewStyleHandler(eventData, corner, fabricObject) {
  if (eventData[fabricObject.canvas.altActionKey]) {
    return controls.skewCursorStyleHandler(eventData, corner, fabricObject);
  }
  return controls.scaleCursorStyleHandler(eventData, corner, fabricObject);
}

The function gets the mouse event data, so it can determine whether some hotkey is pressed, then run some specfic logics for one action or the other. skewCursorStyleHandler or scaleCursorStyleHandler will then take care of the specific logic for one action or the other. All the style handling for the existing fabricJS functionalities are written and do serve as an example in case you need to write a different cursor logic.
该函数获取鼠标事件数据,因此它可以确定是否按下了某个热键,然后为一个操作或另一个操作运行一些特定的逻辑。 skewCursorStyleHandler 或者 scaleCursorStyleHandler 将处理一个操作或另一个操作的特定逻辑。现有 fabricJS 功能的所有样式处理都已编写完毕,并在您需要编写不同的游标逻辑时用作示例。

If your custom control always shows the same cursor, you can just keep the default handler and change that control by setting the property cursorStyle.
如果自定义控件始终显示相同的光标,则可以只保留默认处理程序并通过设置属性 cursorStyle 来更改该控件。

mouseUpHandler and mouseDownHandler
mouseUpHandler 和 mouseDownHandler

You can use controls as once time click buttons if you want, instead of connecting them to drag action with the mouse. A classic example is the control to delete an object or to clone it, as described better in this example here: custom control render and action. Or another possible one is flipping an object.
如果需要,您可以将控件用作一次单击按钮,而不是连接它们以使用鼠标拖动操作。一个典型的示例是用于删除对象或克隆对象的控件,如以下示例中所述:自定义控件呈现和操作。或者另一种可能的方法是翻转物体。

actionHandler 操作处理程序

This function, definitely the most complicated to master, allow you write your custom actions. We can look at the simple width changer function:
这个函数绝对是最复杂的,允许您编写自定义操作。我们可以看看简单的宽度转换器功能:


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;
}


arguments: eventData is the mouse event object transform is a plain js object that contains transform.target the object we are transforming x and y represent the distance in pixel from the anchor point of the transformation.
参数: eventData 是鼠标事件对象 transform 是一个普通的 js 对象,其中包含 transform.target 我们正在转换的对象,并 y 表示与转换 x 锚点的距离(以像素为单位)。

This function handles the side controls of the textbox, but can be also used on rects as it is, and creating another one to change the height is a simple as swapping the width related properties with they height related ones.
此函数处理文本框的侧面控件,但也可以按原样在矩形上使用,并且创建另一个来更改高度很简单,只需将与宽度相关的属性与高度相关的属换即可。

Another easy extension is to make it change the rx,ry of an ellipse or the radius of a circle.
另一个简单的扩展是让它改变椭圆的 rx,ry 或圆的半径。

Moving into scaling and skewing the calculations are way more complex. Please note that while the api provide full freedom, writing actions for controls is not easy. When geometry comes into play knowing fabricJS internals is very important. The actual actions serve as an example but the code is way more complicated of how it could be since it has to support: scalingFlip, lockScaling, centerTransfrom, freeformScaling and other fabricJS properties.
进入缩放和倾斜计算要复杂得多。请注意,虽然 api 提供了完全的自由,但为控件编写操作并不容易。当几何体发挥作用时,了解fabricJS内部非常重要。实际操作作为示例,但代码要复杂得多,因为它必须支持: scalingFlip 、 lockScaling 、、 centerTransfrom 和其他 freeformScaling fabricJS 属性。

If you think a portion of the code is reusable for your own action ( like it is wrapWithFixedAnchor) open an issue asking it to be separate and put it in its own function.
如果你认为代码的一部分可以重用于你自己的操作(就像它一样 wrapWithFixedAnchor ),请打开一个问题,要求它分开并把它放在自己的函数中。


自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论