使用KineticJS对齐多个对象

分享于 

7分钟阅读

Web开发

  繁體
Sample Image - maximum width is 600 pixels

介绍

本文构建在上一个,我们通过使用 KineticJS库拖动鼠标来创建一个选择框。 在本文中,我们将添加函数来允许这些对象沿左边缘。顶部或者底部。顶部或者底部以及中心或者中心对齐。

背景

如果你没有阅读以前的文章,请这样做。 本文假设你拥有前一篇文章中的所有部分。 如果你是 HTML5 Canvas 标签的新手,请访问 HTML5CanvasTutorials.com。 如果你是KineticJS库的新手,点击这里了解更多关于它们以及它们如何为网页浏览器创建全新的体验的方式。 本示例适用于库版本 4.7.4,可以在这里找到 本文是一系列使用KineticJS库选择和操作 HTML5 Canvas 对象的第二部分中的第二部分。

使用代码

在许多图形编辑工具中,用户期望的一组功能是对齐顶部。底部。左侧。权利。中间和中心。 在这个示例中我们首先要做的是添加知道如何操作对象的函数。 是时候来点数学了。

对于对齐函数我们需要知道的第一件事是哪个对象最顶端或者最左边。 根据水平或者垂直轴是否对齐,最顶端或者最左边将作为对象,我们将将它的他对象排列。 这两个函数为我们找到了这些项目:

function FindLeftmost()
{
 var lowestX = 100000;
 var grpLeft = null;
 for (var i = 0; i <arSelected.length; i++)
 {
 var grp = layer.get("." + arSelected[i])[0];
 if (parseInt(grp.attrs.x) <lowestX)
 {
 grpLeft = grp;
 lowestX = parseInt(grp.attrs.x);
 }
 }
 return grpLeft;
}function FindTopmost()
{
 var lowestY = 10000;
 var grpTop = null;
 for (var i = 0; i <arSelected.length; i++)
 {
 var grp = layer.get("." + arSelected[i])[0];
 if (parseInt(grp.attrs.y) <lowestY)
 {
 grpTop = grp;
 lowestY = parseInt(grp.attrs.y);
 }
 }
 return grpTop;
}

接下来,我们有了完成对齐的实际函数。 它们都以相同的常规方式工作: 获取引用对象( 最顶端或者最左边的)的绝对位置,然后按照用户请求的方式将它的他对象与它的对齐。

///////////////////////////////////////////////////Alignment functions ///////////////////////////////////////////////function AlignLefts()
{
 var grpTop = FindTopmost();
 if (grpTop == null)
 {
 return;
 }
 var topPos = grpTop.getAbsolutePosition();
 for (i = 0; i <arSelected.length; i++)
 {
 var grp = layer.get("." + arSelected[i])[0];
 var newX = topPos.x;
 var newY = parseInt(grp.attrs.y);
 grp.setAbsolutePosition(newX, newY);
 }
 RemoveHighlights();
 layer.draw();
}function AlignRights()
{
 var grpTop = FindTopmost();
 if (grpTop == null)
 {
 return;
 }
 var topPos = grpTop.getAbsolutePosition();
 var end = topPos.x + parseInt(grpTop.getWidth());
 for (i = 0; i <arSelected.length; i++)
 {
 var grp = layer.get("." + arSelected[i])[0];
 var newX = end - grp.getWidth();
 var newY = grp.getY();
 grp.setAbsolutePosition(newX, newY);
 }
 RemoveHighlights();
 layer.draw();
}function AlignTops()
{
 var grpLeft = FindLeftmost();
 if (grpLeft == null)
 {
 return;
 }
 var leftPos = grpLeft.getAbsolutePosition();
 for (i = 0; i <arSelected.length; i++)
 {
 var grp = layer.get("." + arSelected[i])[0];
 var newX = grp.getX();
 var newY = leftPos.y;
 grp.setAbsolutePosition(newX, newY);
 }
 RemoveHighlights();
 layer.draw();
}function AlignBottoms()
{
 var grpLeft = FindLeftmost();
 if (grpLeft == null)
 {
 return;
 }
 var leftPos = grpLeft.getAbsolutePosition();
 var bottom = leftPos.y + grpLeft.getHeight();
 for (i = 0; i <arSelected.length; i++)
 {
 var grp = layer.get("." + arSelected[i])[0];
 var newX = grp.getX();
 var newY = bottom - grp.getHeight();
 grp.setAbsolutePosition(newX, newY);
 }
 RemoveHighlights();
 layer.draw();
}function AlignCenters()
{
 var grpTop = FindTopmost();
 if (grpTop == null)
 {
 return;
 }
 var topPos = grpTop.getAbsolutePosition();
 var middle = topPos.x + (grpTop.getWidth()/2);
 for (i = 0; i <arSelected.length; i++)
 {
 var grp = layer.get("." + arSelected[i])[0];
 var newX = middle - (grp.getWidth()/2);
 var newY = grp.getY();
 grp.setAbsolutePosition(newX, newY);
 }
 RemoveHighlights();
 layer.draw();
}function AlignMiddles()
{
 var grpLeft = FindLeftmost();
 if (grpLeft == null)
 {
 return;
 }
 var leftPos = grpLeft.getAbsolutePosition();
 var middle = leftPos.x + (grpLeft.getHeight()/2);
 for (i = 0; i <arSelected.length; i++)
 {
 var grp = layer.get("." + arSelected[i])[0];
 var newX = grp.getX();
 var newY = middle - (grp.getHeight()/2);
 grp.setAbsolutePosition(newX, newY);
 }
 RemoveHighlights();
 layer.draw();
}

最后,我们只需要一种调用这些函数的。 为此,我们将使用来自前一篇文章的CreateButton 函数。

x = 10;
y = 290;var grpAlignLeftButton = CreateButton(x, y, "Align Lefts");
grpAlignLeftButton.on("click", function (evt) { AlignLefts(); });
y = 330;var grpAlignRightButton = CreateButton(x, y, "Align Rights");
grpAlignRightButton.on("click", function (evt) { AlignRights(); });
y = 370;var grpAlignTopsButton = CreateButton(x, y, "Align Tops");
grpAlignTopsButton.on("click", function (evt) { AlignTops(); });
x = 160y = 290;var grpAlignBottomsButton = CreateButton(x, y, "Align Bottoms");
grpAlignBottomsButton.on("click", function (evt) { AlignBottoms(); });
y = 330;var grpAlignMiddlesButton = CreateButton(x, y, "Align Middles");
grpAlignMiddlesButton.on("click", function (evt) { AlignMiddles(); });
y = 370;var grpAlignCentersButton = CreateButton(x, y, "Align Centers");
grpAlignCentersButton.on("click", function (evt) { AlignCenters(); });
x = 85;
y = 410;var grpResetButton = CreateButton(x, y, "Reset Blocks");
grpResetButton.on("click", function (evt) { DrawBlocks(); });
stage.add(layer);
layer.draw();

Points of Interest

应该注意的是,调用 setAbsolutePosition的行是绝对必要的。 设置的位置将与鼠标单击时的位置不相同,这将导致你在计算选择框中的项目时遇到很大的痛苦。

你可以在这里看到这个项目的一个工作演示( )。

历史记录

  • 21st 2013年11月: 初始版本