JavaFx 2D、3D、SVG 形状

JavaFx 2D, 3D, SVG Shapes

我有一个关于下图的一般性问题。我对如何使用 JavaFX 创建这样的组件感到有点困惑。下面的船舶图形的每个部分都作为一个按钮自身也动态变化为:“尺寸颜色等”。

我不确定这是否可以使用 SVG 路径或 2D 对象动态创建,或者最好使用 2D-3D 文件类型,如(“.obj,.stl ... 等”)。 如果有人遇到过这种情况,欢迎留下答案和意见讨论。

答案澄清器

当我第一次读到你的问题时,我以为它是关于在你的问题中挑选或选择图像的一部分,但也许它不是并且只是关于如何表示和绘制对象而不是与图像的一部分进行交互它。如果不需要交互,你可以忽略答案的选择部分,只看形状表示部分。

采摘

您可以通过多种方式实现所描述的结果。您要实现的目标的技术术语是“采摘”,但是除了采摘之外还有很多事情可能会影响您表示对象的方式以及您使用的是 2D 还是 3D 系统,甚至 JavaFX 是否最合适您的应用程序的框架。您可能需要 3D 系统,或者 2D 系统可能就足够了(我不知道)。

相关信息:

PickResult

链接的拣选文章中的示例处理程序:

EventHandler<MouseEvent> moveHandler = new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
            PickResult res = event.getPickResult();
            // do something with the pick result.
            event.consume();
        }
}

那篇采摘文章使用了PickResult。 PickResult 可以解释 2D 和 3D 信息。在二维信息的情况下,通常只有选取的节点是相关的。在 3D 拾取的情况下,它提供附加信息,例如纹理 co-ordinates 和拾取的 3D 面。

setOnMouseClicked

等方便方法

通常在 2D 中,除了已选择的节点之外,您不需要很多其他信息。在这种情况下,您不需要查询和查看 PickResult 中的所有信息。你可以利用"convenience methods" for user interaction handling such as setOnMouseClicked。在所有节点上设置点击处理程序,您将能够在点击每个节点时通过其相关的点击处理程序操作每个节点(类似于按钮的功能)。

对于不规则形状,您可能需要确保有 setPickOnBounds(false)。另请注意,如果边界拾取为假,并且您希望在不规则形状内单击以进行注册,则形状内部必须填充颜色(与您的图片不同)。如果需要,颜色可以是半透明的,但不是完全透明的。这是因为如果您没有任何可点击的内容,则点击不会注册。

悬停时绑定

查看此问题的 smurf 答案,了解当节点的悬停 属性 更改状态时采取操作的示例。

  • How to change color of image in JavaFX

实现你自己的hit-testing

当场景图中有节点时,您可以使用 hit-testing 的 JavaFX in-built 系统进行选择关联。

另一种方法是在 Canvas 中渲染您的图像而不使用场景图,然后实现您自己的 hit-testing 算法并使用它。这就是 trashgod 对以下问题的回答中说明的解决方案:

如果您使用 painter's algorithm 在 canvas 中渲染复杂的重叠形状,这可能会变得复杂。因此,我建议使用具有 2D 或 3D 形状的场景图,而不是使用 canvas 来完成此任务。

形状表示

您可以执行此操作的示例方法:

选择哪种表示取决于应用程序,因为有些更适合不同的目的。对于您在问题中显示的图像,您似乎有各种 orthographic projections of the same object, using a ParallelCamera 将 3D 表示渲染到 2D 平面上可能是最好的。对于许多其他应用程序,位图 2D 图像是最好的。

要表示不规则的二维形状,如果您有适当的路径信息,您可以使用 SVGPath。如果您没有适当的路径信息,那么使用 2D 系统来表示一组复杂的图像将是一个挑战,就像您在问题中遇到的那样(即使有路径信息,这对您来说也可能是一个挑战)。

形状表示的另一个选项是 Image 从位图文件(例如 PNG)中读取,这些文件具有透明背景以允许不规则形状。

一边

这个问题可能会因为不够集中而被关闭,因为这就是发生在像这样的问题上的情况。这个答案在范围上同样更笼统,而不是具体,特别是,没有提供完整的代码(或者根本没有任何代码)来为您在问题中概述的问题实施解决方案。