pra*_*ehl 1 transform fabricjs kineticjs
我喜欢KineticJS,它的速度,与GSAP的结合,但是让我头脑旋转的方法有一种方法可以像FabricJS那样自由地转换KineticJS对象吗?以下是我想说的链接参考:http: //fabricjs.com/customization/我不想使用FabricJs,因为它非常慢,而且它的低性能可以从各种单元测试中看出来.
我真的很期待找到一种能够在KineticJS中自由变换物体的方法,因为它会让生活变得更加轻松.
有办法吗?
谢谢你的帮助,Praney
就像markE所说,Eric的(KineticJS的创建者)教程网站上的这个教程是KineticJS中所有自由变换的基础.
我将详细介绍实际的自由变换逻辑,主要有两个功能:
function addAnchor(group, x, y, name) {
var stage = group.getStage();
var layer = group.getLayer();
//Create the anchor shape
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: '#666',
fill: '#ddd',
strokeWidth: 2,
radius: 8,
name: name,
draggable: true,
dragOnTop: false
});
//Calls the update function which handles the transform logic
anchor.on('dragmove', function() {
update(this);
layer.draw();
});
//When the anchor is selected, we want to turn dragging off for the group
//This is so that only the anchor is draggable, and we can transform instead of drag
anchor.on('mousedown touchstart', function() {
group.setDraggable(false);
this.moveToTop();
});
//Turn back on draggable for the group
anchor.on('dragend', function() {
group.setDraggable(true);
layer.draw();
});
// add hover styling
anchor.on('mouseover', function() {
var layer = this.getLayer();
document.body.style.cursor = 'pointer';
this.setStrokeWidth(4);
layer.draw();
});
anchor.on('mouseout', function() {
var layer = this.getLayer();
document.body.style.cursor = 'default';
this.setStrokeWidth(2);
layer.draw();
});
group.add(anchor);
}
Run Code Online (Sandbox Code Playgroud)
该addAnchor函数与名称一样,将一个锚点(或自由变换句柄)添加到一个Kinetic.Group.默认情况下它使用a Kinetic.Circle但你真的可以使用你想要的任何形状.
group - 要添加锚点的组x - 锚点的x位置y - 锚的y位置name- 锚点的名称(通常描述锚点代表的位置,如topLeft或bottomRight你会注意到一堆events附加到新创建的锚点,其中大部分非常直接,但你要注意的是dragmove事件 - 这个事件是调用处理所有逻辑的update函数的事件.转换组/节点.值得注意的update是,为拖动锚点的每个像素调用该函数.
本教程使用4个角锚(因此为每个组/节点调用addAnchor 4次),但是如果你想要8个锚点(4个角--4个边),那么你只需要调整逻辑来正确定位锚点并移动锚点转换时正确.
顺便说一下,我们将Anchor添加到Group的原因是因为我们需要它们与相关节点分组,并通过拖动和转换坚持每个节点.
第二种方法是update功能:
function update(activeAnchor) {
var group = activeAnchor.getParent();
//Get each anchor inside the group, by name. Keep a standard set of names for every anchor you use and note they have to be names not ids because there will be multiple anchors named .topLeft in your app
var topLeft = group.get('.topLeft')[0];
var topRight = group.get('.topRight')[0];
var bottomRight = group.get('.bottomRight')[0];
var bottomLeft = group.get('.bottomLeft')[0];
var image = group.get('.image')[0];
var anchorX = activeAnchor.getX();
var anchorY = activeAnchor.getY();
// update anchor positions
switch (activeAnchor.getName()) {
case 'topLeft':
//When topLeft is being dragged, topRight has to update in the Y-axis
//And bottomLeft has to update in the X-axis
topRight.setY(anchorY);
bottomLeft.setX(anchorX);
break;
case 'topRight':
topLeft.setY(anchorY);
bottomRight.setX(anchorX);
break;
case 'bottomRight':
bottomLeft.setY(anchorY);
topRight.setX(anchorX);
break;
case 'bottomLeft':
bottomRight.setY(anchorY);
topLeft.setX(anchorX);
break;
}
image.setPosition(topLeft.getPosition());
//New height and width are calculated with a little math
//by calculating the distance between the update anchor positions.
var width = topRight.getX() - topLeft.getX();
var height = bottomLeft.getY() - topLeft.getY();
if(width && height) {
image.setSize(width, height);
}
}
Run Code Online (Sandbox Code Playgroud)
该update函数只接受一个参数:activeAnchor即被拖动的锚点.
之后,它选择组中的其他锚点(使用您需要为每个节点提供的静态名称并在整个应用程序中保持一致),以便我们可以activeAnchor在拖动时转换它们的位置.
如果使用8个锚而不是4个,则switch语句会变得非常大.这是因为您需要考虑在拖动其中一个锚时转换几乎所有其他锚.
对于8锚示例:如果拖动topLeft锚点,则需要更新锚点的y位置,topRight锚点的x位置bottomLeft,以及需要调整x和y值以保持在锚点topMid和leftMid锚点之间的锚点.其他锚点.
更新锚位置后,该函数处理逻辑以调整形状的大小.请注意,形状是通过选择var image = group.get('.image')[0];但是,你可以做的是使用get函数按类型选择并执行以下操作:
var shape = group.get('Shape')[0];
显然,如果每组只有1个形状(转换)+ 4或8个锚,这将最有效.
如果您有任何其他问题或意见,请与我们联系!祝好运!