通过JavaFX标注制作动画效果

在本文中,您将学习如何使用JavaFX的动画API创建标注。 您可以在https://www.youtube.com/watch?v=XTHbB0LRdT4的 YouTube网站上查看这些标注的演示示例。

JavaFX的动画

什么是标注?

我敢肯定,您已经看过广告或科幻电影,它们使用在图像顶部显示的标注来指示场景中的物体。 在本文中,您将学习如何使用JavaFX的Animation API创建动画标注效果。 使用这种效果,您可以将文本放置到场景中,然后通过线条或箭头将文本连接到感兴趣的项目。

图1显示了在本文的上下文中组合在一起构成标注的各个部分。

JavaFX的动画

图1.典型标注的不同部分

以下是图1中所示各个部分的定义:

  • 头部 –指示图像中的项目的点(圆圈)
  • 引导线 –从头部到另一点的线,通常形成对角线
  • 引伸线末端引伸线段的末端 (水平线)
  • 主标题 –主标题文本。 正文开始在引导线的终点滚动
  • 字幕矩形 –来自主标题底部的一个小动画矩形
  • 字幕 - 字幕文字。 字幕文本将在主标题文本下方

并非所有标注都相同。 不过,大多数将包含这些元素中的大多数。

标注通常以静态方式指出书籍或杂志中的内容,但如果可以对标注进行动画处理,则在视频中要好得多。 一个不错的动画效果是从绘制一个点(头)开始,然后画一条线(引导线),然后滚动一个主标题,最后滚动一个字幕。 当动画结束显示时,它可以暂停一会儿(恰好足以允许观看者阅读标题文本),然后将整个过程反向进行,以退出场景。

动画标注

现在您知道了标注的构成,我们可以跳入一些JavaFX代码来为图1中所示的每个片段(1-6)设置动画。

由于标注的每个部分都是按顺序进行动画处理的,因此您将首先创建一个javafx.animation.SequentialTransition实例。 一个SequentialTransition拥有零到许多Animation对象。 创建方法如下:

SequentialTransition calloutAnimation = new SequentialTransition();

顾名思义,动画将按顺序进行。 您需要在calloutAnimation上设置的其他内容是循环计数和自动反转属性。 例如:

// Allow animation to go in reversecalloutAnimation.setCycleCount(2);calloutAnimation.setAutoReverse(true);

通过上述设置,动画可以在阅读者有时间查看和吸收标注之后反转顺序。 若要添加动画,请在顺序过渡动画对象上调用.getChildren()。add()方法。 以下是将头部动画添加到顺序过渡动画对象的代码。 方法buildHeadAnim()返回一个javafx.animation.Animation实例。

// Animation of headCircle head = new Circle(600, 550, 5); // center x, y, radiushead.setFill(Color.WHITE);calloutAnimation.getChildren().add(buildHeadAnim(head));

头部动画

为头部创建动画时,可以使用任何形状,例如矩形或圆形。 在接下来的示例中,头部是JavaFX Circle形状。 动画从零半径开始,然后缩放到更大的半径。 显示的方法创建并返回一个javafx.animation.Timeline对象。

protected Animation buildHeadAnim(Node head) {Circle headCircle = (Circle) head;return new Timeline(new KeyFrame(Duration.millis(1),new KeyValue(headCircle.visibleProperty(), true),new KeyValue(headCircle.radiusProperty(), 0)), // start valuenew KeyFrame(Duration.millis(300),new KeyValue(headCircle.radiusProperty(), 5.0d)) // end value);
}

时间轴由一个初始关键帧组成,该初始关键帧将头圈的visible属性设置为true,并将radius属性设置为零。 接下来,使用关键值定义结束关键帧,以在300毫秒内将radius属性从零插入到5.0。

领导线动画

在设置引导线动画时,该线将看起来就像是用铅笔进行描画或绘制。 在下面的代码中,将对端点坐标进行插值(线性)。 从头部的中心(600,550)到lineToPoint坐标(400,300)画一条线。 我对值进行了硬编码,以使代码更简洁。 endX / endY的实际键值分别设置为getLeaderLineToPoint()。getX()getLeaderLineToPoint()。getY()

protected Animation buildBeginLeaderLineAnim(Line leaderLine) {return new Timeline(new KeyFrame(Duration.millis(1),new KeyValue(leaderLine.visibleProperty(), true)),// shownew KeyFrame(Duration.millis(300),new KeyValue(leaderLine.endXProperty(), 400),new KeyValue(firstLeaderLine.endYProperty(), 300)));
}

领导线结束动画

由于动画化引线的末端部分的代码将与以前的动画非常相似,因此,我将省略该代码。 要查看完整列表,请访问: https : //github.com/carldea/callouts/tree/master/src/com/carlfx/callouts 。

主标题文字动画

主标题文本动画由一个HBox组成,该HBox包含一个Text节点,该文本节点将根据引线终点的方向向左或向右滚动。 例如,如果引出线终点的方向指向右侧,则主标题文本将显示为向右滚动。

以下是负责对主标题文本进行动画处理的buildMainTitleAnim()方法。 由于该方法是标注动画中最复杂的部分,因此我想分享我在使用过程中遇到的一些技巧。

protected Animation buildMainTitleAnim(HBox mainTitleBackground) {// main title box// Calculate main title width and height upfrontRectangle2D mainTitleBounds = getBoundsUpfront(mainTitleBackground);double mainTitleWidth = mainTitleBounds.getWidth();double mainTitleHeight = mainTitleBounds.getHeight();// Position mainTitleText background beside the end part of the leader line.Point2D endPointLLine = calcEndPointOfLeaderLine();double x = endPointLLine.getX();double y = endPointLLine.getY();// Viewport to make main title appear to scrollRectangle mainTitleViewPort = new Rectangle();mainTitleViewPort.setWidth(0);mainTitleViewPort.setHeight(mainTitleHeight);mainTitleBackground.setClip(mainTitleViewPort);mainTitleBackground.setLayoutX(x);mainTitleBackground.setLayoutY(y - (mainTitleHeight/2));// Animate main title from end point to the left.if (LEFT == getEndLeaderLineDirection()) {// animate layout x and widthreturn new Timeline(new KeyFrame(Duration.millis(1),new KeyValue(mainTitleBackground.visibleProperty(), true),new KeyValue(mainTitleBackground.layoutXProperty(), x)), // shownew KeyFrame(Duration.millis(200),new KeyValue(mainTitleBackground.layoutXProperty(), x - mainTitleWidth),new KeyValue(mainTitleViewPort.widthProperty(), mainTitleWidth)));}// Animate main title from end point to the rightreturn new Timeline(new KeyFrame(Duration.millis(1),new KeyValue(mainTitleBackground.visibleProperty(), true)), // shownew KeyFrame(Duration.millis(200),new KeyValue(mainTitleViewPort.widthProperty(), mainTitleWidth)));
}

放置主标题文本时,您的代码将需要预先知道边界区域的大小。 下面是一种方法,该方法采用包含文本节点的HBox,然后计算HBox的宽度和高度,而不必在主场景图上显示该框。

protected Rectangle2D getBoundsUpfront(Region node) {// Calculate main title width and heightGroup titleRoot = new Group();new Scene(titleRoot);titleRoot.getChildren().add(node);titleRoot.applyCss();titleRoot.layout();return new Rectangle2D(0, 0, node.getWidth(), node.getHeight());
}

您可以在此示例中看到javafx.scene.Node类中的applyCss()layout()方法如何负责在应用CSS样式后确定宽度和高度。 在上方,您会发现一个场景是临时创建的。

字幕动画

为了简洁起见,我省略了字幕动画。 我相信您会看到我在Github上提到的完整代码清单。 在动画的初始开始和内插到结束键值方面,字幕动画均遵循与标题动画相同的模式。

播放标注动画

假设将构成标注的节点添加到JavaFX Pane布局节点,则需要停止顺序动画calloutAnimation 。 然后,您需要初始化所有不显示的节点(visible属性设置为false)。 最后,您需要调用play()方法。

getChildren().addAll(head,firstLeaderLine,secondLeaderLine,mainTitle,subTitleRect,subTitle);calloutAnimation.stop();getChildren().forEach(node -> node.setVisible(false));calloutAnimation.play();

结论

通过使用JavaFX的动画API和简单的形状,创建动画标注非常容易。 在本文中,您学习了如何使用SequentialTransition对象来顺序调用较小的动画(时间轴)。

构建每个时间轴动画的标注的每个步骤,将使用根据形状属性(例如圆的半径)在关键值上插值的关键帧。 之后,在学习如何对引导线进行动画处理之后,您还学到了一个巧妙的技巧,该技巧可以通过applyCss()layout()方法确定主标题文本的大小。 由于样式和字体大小的原因,在将UI组件呈现到主场景图上之前,很难知道它的大小。

现在,您知道如何实现动画标注,我相信您将使应用程序更具吸引力。 编码愉快!

翻译自: https://www.javacodegeeks.com/2018/10/animated-effects-javafx-callouts.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/346057.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php 继承内核中的基类,继承类上的PHP new self()正在创建一个基类对象

参见英文答案 > New self vs. new static 3个我有一个充当基类的类.然后我有几个继承它的类.我想开始使用静态语法加载继承的类,但行为没有多大意义.直到现在我加载了这样的类,它完成了这项工作.$obj new foo();$something $obj->B…

使用trackBy启动流程

仍然沿用Corda Services的趋势,我还有其他一些技巧可帮助您的CorDapp顺利工作。 这次,我们将重点关注使用trackBy从服务内部启动流以及如果您不小心可能会引起的离散问题。 这应该是一个相对简短的职位,因为我可以依靠之前的职位&#xff1a…

过防火墙一句话php2017,dedeCMS友情链接getshell漏洞利用

1.php//print_r($_SERVER);$referer $_SERVER[HTTP_REFERER];$dede_login str_replace("friendlink_main.php","",$referer);//去掉friendlink_main.php,取得dede后台的路径//拼接 exp$muma .;$exp tpl.php?actionsavetagfile&actiond…

java 1.8新增功能_Java 8的新增功能(第二部分-可能会出现什么)

java 1.8新增功能免责声明:我不为Oracle工作,也不以任何方式代表Oracle。 此功能列表不是官方的。 作为“局外人”,这只是我研究的一部分。 这是由三部分组成的系列文章的第二部分。 在第一部分中 ,我谈到了Oracle正式让开发人员…

Spring应用架构

我最近收到我博客的一位读者Ajay的问题,并决定在此处分享我的答案,以帮助其他有类似问题的人。 这是来自阿杰的问题: 大卫您好,我想知道我最近遇到的两种MVC应用程序体系结构之间的区别: 1)在普通的Spri…

PHP能不能让一串代码现实,一段让你认清现实的Java代码.java

/*** 答致命三问* 终回归现实*/public static void main(String[] args) {boolean a false,b false,c false;java.util.Scanner scanner new java.util.Scanner(System.in);System.out.println(decode("5oKo5aSa6auY77yIY23vvInvvJ8"));int height 0;while (hei…

java+springmvc+vo,springmvc+mybatis的实例详解

前面讲到:SpringSpringMVCMyBatis深入学习及搭建(十三)——SpringMVC入门程序(二)1.需求使用springmvc和mybatis完成商品列表查询。2.整合思路springmvcmybatis的系统架构:第一步:整合dao层mybatis和spring整合,通过spring管理map…

java是面向过程的编程语言吗,下列关于Java语言特点的叙述中,错误的是()。 A.Java是面向过程的编程语言B.Java支持分...

查询最近30天的记录应使用( )作为准则某企业年度主营业务收入为以下关于第一层ISP特征的描述中,错误的是测量电压时,应将数字万用表与被测电路并联。()HLAⅡ类分子主要分布于在铁碳合金相图中今年来,公务员逐渐成为广大高校毕业生所青睐的热门职业,但是报考公务员必…

了解为什么这个直观的工具是您团队的通用团队管理工具

每个项目管理工具都试图做同样的工具性工作:保持团队联系,按任务执行和按时完成重大计划。 但是市场变得非常拥挤,并且有充分的理由-没有平台似乎对人们需要看的东西以及应该如何显示这些信息具有正确的感觉,以便它们既可行又相关…

ecshop 模板 php代码,ecshop无法在模板文件.dwt和.lbi中直接添加php代码的解决方法...

ecshop不能在模板文件.dwt和.lbi中直接添加php代码了,为什么呢?因为直接在模板中加入php函数和代码,没有经过过滤,容易造成安全隐患。程序源码安全是比较重要的。不过如果有朋友希望能在模板文件中直接加入.dwt和.lbi文件&#xf…

php mail 在线,在线web e-mail发送

名称:CJ Web2Mail V3.0说明:很多网站的“Contact Us ”打开的是outlook,但很多人没装。本人提供的是web发。可以给管理员发信的人自动发一封确认信,同时管理员也可以收到一封!演示:http://phptext.512j.com(左下角的“…

jstl视图_使用JSTL视图探索Spring Controller

jstl视图让我们通过对Spring MVC的Controller开发的更多探索来改进我们以前的Spring JDBC应用程序 。 我将展示另一种编写新的Controller的练习,该Controller处理HTML表单并在JSP视图页面中使用JSTL标签。 要在Spring MVC应用程序中启用JSTL,您需要将以…

php5.6 连接 oracle,XAMPP中PHP5.6.3连接Oracle

系统环境:Windows 8.1 x64PHP 5.6.3 x86Apache/2.4.10 (Win32)Oracle Database 11g Enterprise Editionxampp-win32-5.6.3-0-VC11-installer.exe 这个版本很坑爹… 在 php.ini 中只有extensionphp_oci8.dll ; Use with Oracle 10gR2 Instant Clientextensionphp_oci…

模型服务:流处理与使用Java,gRPC,Apache Kafka,TensorFlow的RPC / REST

机器学习/深度学习模型可以通过不同的方式进行预测。 我的首选方法是将分析模型直接部署到流处理应用程序(如Kafka Streams或KSQL )中。 您可以例如使用TensorFlow for Java API 。 这样可以实现最佳延迟和外部服务的独立性。 在我的Github项目中可以找到…

electronjs MySQL,javascript – 在Electron应用程序中使用sql.js.

我是Electron的新手.它非常棒,而且入门非常有趣而且非常简单.一段时间以来,我一直试图找到一个在我的应用程序中使用的“数据库”解决方案.当然有Web SQL /本地存储选项,但我试图使用SQLite.我找到了sql.js,它很棒且易于使用.我可以让一切正常运行放我无法保存/更新数据库文件&…

php ajax mysql 出错,MySql + PHP + Ajax的乱码问题的解决方案

现如今,基本的web2.0应用都会涉及到表现层、业务层、数据层等多个层次。在数据的来回传递中,新手一不注意就会产生汉字的乱码问题。汉字乱码主要是由于各层使用的编码、或在层间进行数据传输时使用的编码不一致造成的,釜底抽薪的解决办法就是…

读取csv文件 java_Java:逐步读取/流式传输CSV文件

读取csv文件 java我一直在做一些涉及读取CSV文件的工作,而我一直在使用OpenCSV ,而我的最初方法是逐行读取文件,解析内容并将其保存到地图列表中。 当文件的内容适合内存时,此方法有效,但对于较大的文件来说是个问题&…

php+数组转换函数是,php数组与字符串的转换函数大全

4.在字符串种中查找另外一个字符使用strpos()或strstr()函数strpos() 函数返回字符串在另一个字符串中第一次出现的位置。如果没有找到该字符串,则返回 false。语法://string为必须,表示被搜索的字符串//find为必须,表示被查找的字…

拥抱模块化Java平台:Java 10上的Apache CXF

Java 9版本终于将Project Jigsaw交付给大众已经过去了一年多的时间。 这是一段漫长的旅程,但是在那里,所以发生了什么变化? 这是一个很好的问题,答案并不明显和直接。 总的来说, 拼图项目是一种颠覆性的变化&#xff…

matlab sym转str,sym struct 转换

描述:用 sym() 生成了 矩阵; 再用 solve() 结果返回 结构体,还带sym 型。。。尝试:用 struct 转换 ; eval() 什么的 都无解,, (结构体还带sym。。。。昏了)求:怎…