- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一条线,一端位于固定点,用户可以旋转或拉伸(stretch)它。
jsfiddle here
似乎在 fabricJS 中选择要旋转的线/对象的唯一方法是中间的小选择框。另外,一条线很窄,所以很难选择。通常,必须将一个矩形选择框拖过直线以将其选中,然后捕获未标记的旋转框。
我想将其简化为:单击线上的任意位置并拖动以旋转。
想法?
谢谢。
代码片段:
var canvas = new fabric.Canvas("c", {stateful: true});
var line1 = new fabric.Line([ 100, 200, 330, 200 ], {
fill: 'red',
stroke: 'red',
strokeWidth: 3,
selectable: true,
evented: false,
minScaleLimit: 0.25,
lockRotation: false,
centeredRotation: false,
centeredScaling: false,
originX: "left", // origin of rotation/transformation.
originY: "bottom", // origin of rotation/transformation.
lockMovementX: true,
lockMovementY: true,
lockScalingFlip: true,
lockScalingX: false,
lockScalingY: false,
lockSkewingX: false,
lockSkewingY: false,
lockUniScaling: true
});
最佳答案
这里有一种方法可以满足您的需求。
我们的想法是,在每个 scale
事件中,我们将使用 fabric 的内部 fabric.canvas._rotateObject()
旋转线条,为其提供当前指针位置。然后,立即调整线的长度以匹配比例并将线的比例重置为 1。
就是这样,但是虽然您的示例相对容易实现(线是水平的),但如果您想初始化对 Angular 线,它会变得更加棘手。想象一条以 [0, 0, 100, 100]
作为坐标的线。这将呈现一个矩形 100x100 边界框。您可以旋转线条,但巨大的边界框显然不是您想要的。
因此,我们需要初始化直线,就好像它旋转回水平位置一样,然后设置它应该具有的 Angular 。为此,我们扩展内置的 fabric.Line
类并修改构造函数以进行计算。而且,由于我们已经有了新类,我们还将向其中添加 scale
处理程序和默认选项。构造函数签名保持不变 - new fabric.RotatingLine([x1, y1, x2, y2], options)
,其中 x1, y1
- 定点, x2, y2
- 可拖动提示。
最后,我们正在更改一些属性。例如。 evented: false
是您无法在点击时选择该行的原因。
以下是带有更多评论的代码段,以防万一。
const canvas = new fabric.Canvas("c", {stateful: true})
fabric.RotatingLine = fabric.util.createClass(fabric.Line, {
minLength: 50, // we need to set this thing in px now
initialize: function (points, options) {
const a = new fabric.Point(points[0], points[1])
const b = new fabric.Point(points[2], points[3])
// find this line's vector
const vectorB = b.subtract(a)
// find angle between line's vector and x axis
let angleRad = Math.atan2(vectorB.y, vectorB.x)
if (angleRad < 0) {
angleRad = 2 * Math.PI + angleRad
}
const angleDeg = fabric.util.radiansToDegrees(angleRad)
// find initial horizontal position by rotating the tip back
const c = fabric.util.rotatePoint(b.clone(), a, -angleRad)
options = options || {}
// finally, initialize using transform points to make a horizontal line
this.callSuper('initialize', [a.x, a.y, c.x, c.y], {
noScaleCache: false, // false to force cache update while scaling (doesn't redraw parts of line otherwise)
selectable: true,
evented: true, // true because you want to select line on click
//minScaleLimit: 0.25, // has no effect now because we're resetting scale on each scale event
lockRotation: false,
hasRotatingPoint: false, // to disable rotation control
centeredRotation: false,
centeredScaling: false,
originX: "left", // origin of rotation/transformation.
originY: "bottom", // origin of rotation/transformation.
lockMovementX: true,
lockMovementY: true,
lockScalingFlip: true,
lockScalingX: false,
lockScalingY: false,
lockSkewingX: false,
lockSkewingY: false,
lockUniScaling: true,
...options,
angle: angleDeg // note that we use the calculated angle no matter what
})
this.setControlsVisibility({
tr: false,
tl: false,
bl: false,
mt: false, // middle top disable
mb: false, // midle bottom
ml: false, // middle left
mr: false, // I think you get it
})
this.on('scaling', function (e) {
// rotate to the pointer's x,y
this.canvas._rotateObject(e.pointer.x, e.pointer.y)
// while _rotateObject() tries to keep left/top at initial value,
// it sometimes fails because of rounding errors (?)
// so we need to do it manually again
this.set({left: this.x1, top: this.y1})
// calculate new length before resetting scale
const xOffset = (this.x2 - this.x1) * this.scaleX
const newLength = Math.max(this.minLength, xOffset)
// reset scaleX/scaleY and set new x coord for the tip point
this.set({
scaleX: 1,
scaleY: 1,
x2: this.x1 + newLength
})
})
}
})
const line1 = new fabric.RotatingLine([ 200, 200, 330, 200 ], {
fill: 'red',
stroke: 'red',
strokeWidth: 3,
});
const line2 = new fabric.RotatingLine([ 200, 200, 100, 100 ], {
fill: 'blue',
stroke: 'blue',
strokeWidth: 3,
});
canvas.add(line1, line2)
// Disables group selection.
canvas.on('selection:created', (e) => {
if(e.target.type === 'activeSelection') {
canvas.discardActiveObject();
} else {
//do nothing
}
})
// Keeps objects inside canvas. undos move/rotate/scale out of canvas.
canvas.on('object:modified', function (options) {
let obj = options.target;
let boundingRect = obj.getBoundingRect(true);
if (boundingRect.left < 0
|| boundingRect.top < 0
|| boundingRect.left + boundingRect.width > canvas.getWidth()
|| boundingRect.top + boundingRect.height > canvas.getHeight()) {
obj.top = obj._stateProperties.top;
obj.left = obj._stateProperties.left;
obj.angle = obj._stateProperties.angle;
obj.scaleX = obj._stateProperties.scaleX;
obj.scaleY = obj._stateProperties.scaleY;
obj.setCoords();
obj.saveState();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.3/fabric.min.js"></script>
<canvas id='c' width="500" height="400"></canvas>
关于javascript - 如何通过单击任意点选择/拖动来旋转 fabricjs 中的线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53379861/
我需要向现有对象属性集引入一些其他属性。 喜欢: ID 地理位置 等 每当我绘制形状时,都需要向该形状添加其他属性,并且需要从toDataLessJSON()获取 最佳答案 从1.7.0版开始,lev
有什么方法可以防止在缩放对象组时发生翻转? 我尝试了“lockScalingFlip”属性。但它仅在缩放单个对象时受支持。 最佳答案 在版本 1.4.11 中,设置 lockScalingFlip=t
我正在使用 fabric js。今天我遇到了这个问题“如何检查 fabricjs 文本是多行的?”。请帮我解决这个问题。提前致谢。 最佳答案 fabricjs 文本有一个 _textLines 属性。
clipTo 函数自 2.0 起已被弃用,是否有任何替代品或该功能刚刚被删除? 最佳答案 他们仍在努力(Clipping API) https://github.com/fabricjs/fabric
如果使用clone()方法克隆fabric.Path对象,则路径对象不会重复。我在这里看到了这个问题 https://github.com/kangax/fabric.js/issues/330但Fa
我正在尝试将文本显式设置为文本框,在较旧的 fabricjs 版本中 object.setText("something") 在fabric js版本2中工作但不工作。这个版本中引入了其他任何方式吗?
我有一个 fabricjs Canvas ,我需要输入 PDF,类似于加载图像的方式。我希望在加载到 Canvas 上之前我需要通过 PDFjs 将 PDF 转换为 PNG 吗? docume
我可以上传背景图片。但我不知道如何拉伸(stretch)才能覆盖整个 Canvas 。示例代码 var fr = new FileReader; fr.onload = function() {
我正在尝试在 FabricJs Canvas 内绘制按钮的网格/数组(p*p)。我能够创建所需的网格/数组。 但我无法在相同高度和宽度的 block 内绘制/放置按钮。 HTML: Create
我有一个 fabricjs Canvas ,上面有一个可以打开和关闭绘图的按钮。如何将自定义控件应用于我绘制的任何/所有绘制对象;例如,我想选择我画的任何一条线,并且只能旋转它们。我已阅读 the e
我想在移动/调整大小/缩放/拖动时将对象的不透明度设置为 0.5。 我们确实为所有这些事件处理程序提供了事件处理程序,但是当其中任何一个启动时,它们只会被触发一次。我想在事件完成后使对象不透明度=1。
我正在使用 fabric js 来调整对象大小,我希望用户在最小和最大限制内调整对象大小。如何使用fabric js做到这一点。 我尝试过类似的属性 lockScalingX,lockScalingY
我已在 SVG 对象和 SVG 对象内的路径上设置自定义属性。 我添加到 Canvas 的每个对象也被分配了一个“id”属性,以及我用来与应用程序中的对象交互的其他一些属性。 到目前为止,当我克隆这些
如何在fabricjs中获取对象标识符? 例如 var text = new fabric.IText('hello world', { left: mouse1X, top: mouse1Y });
Fabric.js 2.3.6 我正在尝试将对象剪辑到使用自由绘图灌木绘制的路径上。代码无法在路径内显示图像,我不确定我做错了什么。 可以剪裁多个对象,因此我无法将路径应用于 Canvas 本身。 l
有没有办法只在 Canvas 对象的一侧给笔画?例如,我只想为顶部提供笔划。 当我申请时"strokeWidth:1" ,它适用于所有方面。我还没有找到任何属性或方法来解决我的问题。 最佳答案 对于已
我正在使用 Fabric.js 在 Canvas 上绘制一些矩形。默认行为是在矩形内单击以选择它。如何更改行为,使其仅在单击矩形边框时才被选中? 单击矩形内部而不是边框应该什么都不做。 您可以通过
据我所知,当使用角控件调整对象的大小时,无论用户将鼠标移到何处,高度和宽度都会按比例更改,以保持对象的长宽比。我的客户希望用户在使用角控件时能够独立于宽高比调整高度和宽度。是否有允许设置的设置? 最佳
如何将组内三角形的 Canvas 相对位置(顶部,左侧)作为波纹管图像? 我关注了这个话题:How to get the canvas-relative position of an object t
我正在创建一个简单的组,其中包含圆圈和文本,我希望文本位于圆圈的中心。 (就像 Fabricjs.com 首页上的小组演示一样!) var text = new fabric.Text('hello
我是一名优秀的程序员,十分优秀!