TornadoFX编程指南,第9章,形状和动画

译自《Shapes and Animation

形状和动画

JavaFX带有几乎表示任何几何形状的节点,以及一个Path节点,它提供组装和管理几何路径所需的工具(以创建自定义形状)。 JavaFX还具有动画支持,逐渐改变Node属性,创建两个状态之间的视觉转换。 TornadoFX旨在通过构建器构造来简化所有这些功能。

形状基础(Shape Basics)

形状构建器的每个参数都是可选的,在大多数情况下,默认值为0.0 。 这意味着您只需要提供您关心的参数。 构建器具有每个形状的大多数属性的位置参数,其余的可以设置在随后的函数块中。 因此,这些都是创建矩形的有效方式:

rectangle {
    width = 100.0
    height = 100.0
}

rectangle(width = 100.0, height = 100.0)

rectangle(0.0, 0.0, 100.0, 100.0)

您选择的形式是偏好的问题,但显然需要考虑到您编写的代码的易读性。 为了清楚起见,本章中的示例指定了代码块中的大部分属性,除非没有代码块支持或参数是非常自明的。

在父项内定位

大多数形状构建器可以让您选择在父项中指定形状的位置。 这是否有任何影响取决于父节点。 除非您在形状上调用setManaged(false),否则HBox不会关心您指定的xy坐标。 但是,Group控件将会关心这一点。 以下示例中的截图将通过在一个Group周围包装一个StackPane,并最后在该Group内创建形状,如下所示。

class MyView: View() {

    override val root =  stackpane {
       group {
            //shapes will go here
       }
    }
}

长方形(Rectangle)

Rectangle定义了一个矩形,其中可选的大小和位置在父项中。 可以使用arcWidtharcHeight属性指定圆角(图9.1)。

rectangle {
    fill = Color.BLUE
    width = 300.0
    height = 150.0
    arcWidth = 20.0
    arcHeight = 20.0
}
图9.1

弧形(Arc)

Arc表示由中心(center),起始角度(start angle),角度范围(angular extent,以度计的弧度)和圆弧类型(arc type, OPEN, CHORD或ROUND )定义的弧形对象(图9.2)

arc {
    centerX = 200.0
    centerY = 200.0
    radiusX = 50.0
    radiusY = 50.0
    startAngle = 45.0
    length = 250.0
    type = ArcType.ROUND
}
图9.2

圆圈(Circle)

Circle表示具有指定radiuscenter的圆。

circle {
    centerX = 100.0
    centerY = 100.0
    radius = 50.0
}

CubicCurve

CubicCurve表示(x,y)坐标空间中的立方贝塞尔参数曲线段(cubic Bézier parametric curve segment)。 使用指定点(controlX1, controlY1) 和(controlX2, controlY2) 作为Bézier控制点,绘制与指定的坐标(startX, startY)和(endX, enfY)相交的曲线。

cubiccurve {
    startX = 0.0
    startY = 50.0
    controlX1 = 25.0
    controlY1 = 0.0
    controlX2 = 75.0
    controlY2 = 100.0
    endX = 150.0
    endY = 50.0
    fill = Color.GREEN
}

椭圆(Ellipse)

Ellipse表示具有指定大小和位置参数的椭圆。

ellipse {
    centerX = 50.0
    centerY = 50.0
    radiusX = 100.0
    radiusY = 50.0
    fill = Color.CORAL
}

线(Line)

线是相当直接的。 提供开始和结束坐标以绘制两点之间的一条线。

line {
    startX = 50.0
    startY = 50.0
    endX = 150.0
    endY = 100.0
}

折线(Polyline)

Polyline由分段点数组(an array of segment points)定义。 PolylinePolygon类似,但不会自动关闭。

polyline(0.0, 0.0, 80.0, 40.0, 40.0, 80.0)

QuadCurve

Quadcurve表示(x,y)坐标空间中的二次Bézier参数曲线段(quadratic Bézier parametric curve segment)。 使用指定点(controlX, controlY) 作为Bézier控制点,绘制与指定坐标(startX, startY)和 (endX, endY)相交的曲线。

quadcurve {
    startX = 0.0
    startY = 150.0
    endX = 150.0
    endY = 150.0
    controlX = 75.0
    controlY = 0.0
    fill = Color.BURLYWOOD
}

SVGPath

SVGPath表示通过从String解析SVG路径数据(SVG path data)构造的形状。

svgpath("M70,50 L90,50 L120,90 L150,50 L170,50 L210,90 L180,120 L170,110 L170,200 L70,200 L70,110 L60,120 L30,90 L70,50") {
    stroke = Color.DARKGREY
    strokeWidth = 2.0
    effect = DropShadow()
}

路径(Path)

Path代表一个形状,并提供基本的构造和管理几何路径所需的设施。 换句话说,它可以帮助您创建自定义形状。 以下帮助函数可用于构建路径:

  • moveTo(x, y)
  • hlineTo(x)
  • vlineTo(y)
  • quadqurveTo(controlX, controlY, x, y)
  • lineTo(x, y)
  • arcTo(radiusX, radiusY, xAxisRotation, x, y, largeArcFlag, sweepFlag)
  • closepath()
path {
    moveTo(0.0, 0.0)
    hlineTo(70.0)
    quadqurveTo {
        x = 120.0
        y = 60.0
        controlX = 100.0
        controlY = 0.0
    }
    lineTo(175.0, 55.0)
    arcTo {
        x = 50.0
        y = 50.0
        radiusX = 50.0
        radiusY = 50.0
    }
}

动画

JavaFX具有通过逐渐更改其一个或多个属性来动画化任何Node的工具。 在JavaFX中创建动画有三个组件。

Timeline - 以指定顺序执行的一系列KeyFrame

KeyFrame - 指定在一个或多个节点上的一个或多个可写属性(通过KeyValue)的值改变的(specifying value changes)“快照”

KeyValue - 将Node属性与将被“转换(transitioned)”到的值配对

KeyValue是JavaFX动画的基本构建块。 它指定一个属性和“新值”,它将逐渐转换到该新值。 所以如果你有一个Rectangle, 其rotateProperty()0.0,并且你指定一个KeyValue,将其改为90.0度,它会递增地从0.0改变到90.0度。 将KeyValue放在KeyFrame,这可以指定这两个值之间的动画持续时间。 在这种情况下,我们让它为5秒。 最后把这个KeyFrame放在一个Timeline 。 如果您运行下面的代码,您将看到一个rectange在5秒钟内从0.0逐渐旋转到90.0度(图9.1)。

val rectangle = rectangle(width = 60.0,height = 40.0) {
    padding = Insets(20.0)
}
timeline {
    keyframe(Duration.seconds(5.0)) {
        keyvalue(rectangle.rotateProperty(),90.0)
    }
}
图9.1

在给定的KeyFrame,您可以同时处理该5秒窗口中的其他属性。 例如,我们可以在Rectangle旋转时转换arcWidthProperty()arcHeightProperty() (图9.2)。

timeline {
        keyframe(Duration.seconds(5.0)) {
            keyvalue(rectangle.rotateProperty(),90.0)
            keyvalue(rectangle.arcWidthProperty(),60.0)
            keyvalue(rectangle.arcHeightProperty(),60.0)
        }
}
图9.2

插值(Interpolators)

您还可以指定一个可以为动画添加微妙效果的Interpolator。 例如,您可以指定Interpolator.EASE_BOTH来优化动画开始和结束时的值更改。

val rectangle = rectangle(width = 60.0, height = 40.0) {
    padding = Insets(20.0)
}

timeline {
    keyframe(5.seconds) {
        keyvalue(rectangle.rotateProperty(), 180.0, interpolator = Interpolator.EASE_BOTH)
    }
}

循环和自动反转(Cycles and AutoReverse)

您可以修改timeline()其他属性,如cycleCountautoReversecycleCount将重复动画指定次数,且将isAutoReverse设置为true将导致每个循环返回。

timeline {
    keyframe(5.seconds) {
        keyvalue(rectangle.rotateProperty(), 180.0, interpolator = Interpolator.EASE_BOTH)
    }
    isAutoReverse = true
    cycleCount = 3
}

要无限期重复动画,请将cycleCount设置为Timeline.INDEFINITE

速记动画(Shorthand Animation)

如果要为单个属性设置动画,您可以快速地将其动画化,而无需声明timeline()keyframe()keyset()。 调用该interoplatoranimate()扩展函数,并提供endValueduration,以及可选的interoplator。 如果您只是一个属性动画,这会更短,更干净。

rectangle.rotateProperty().animate(endValue = 180.0, duration = 5.seconds)

总结

在本章中,我们介绍了形状和动画的构造器。 我们没有覆盖JavaFX的Canvas因为这超出了TornadoFX框架的范围。 它可以容易地占用多个章节。 但是,形状和动画应该能允许您为大多数任务执行基本的自定义图形。

现在,我们对TornadoFX构建器的覆盖范围到此结束。 接下来,我们将为那些需要使用它的人介绍FXML。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • Animation Animation类是所有动画(scale、alpha、translate、rotate)的基...
    四月一号阅读 1,868评论 0 10
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,099评论 18 139
  • 先看看CAAnimation动画的继承结构 CAAnimation{ CAPropertyAnimation { ...
    时间不会倒着走阅读 1,560评论 0 1
  • 选择qi:是表达式 标签选择器 类选择器 属性选择器 继承属性: color,font,text-align,li...
    wzhiq896阅读 1,689评论 0 2
  • 最近项目中有需求对存有 ARGB8888 数据的 Bitmap 进行基于原值的透明度(alpha 值)调整,要对每...
    硬耳geeklok阅读 447评论 0 0