使用 OpenLaszlo 创建 Web 富客户端(2)
- UID
- 1066743
|
使用 OpenLaszlo 创建 Web 富客户端(2)
约束:强大的交互对于富用户界面,一个重要的方面就是布局管理。Laszlo 支持(通过布局组件)很多标准的方法。例如,可以使用 <simplelayout> 元素,该元素有两个主要属性。axis 属性可用于指定布局方向,它的值可以是 x-axis 或 y-axis,而 spacing 属性可用于控制组件之间的间距。对于一个容器,可以声明多个布局,以便组合水平和垂直方向的间距。同样,这也是 Laszlo 中的一个简单而有效的概念。Laszlo 还包含网格布局和那些用于一个区域的布局,但这并不是使我对 Laszlo 刮目相看的原因。真正令人兴奋的特性是 Laszlo 约束模型(constraint model),通过它可以非常优雅地获得 UI 控件和动画效果。
大多数事件的替代物每当 Laszlo 组件中的属性发生改变时,就触发了一个事件。正如 “” 小节中所述,这些事件可以被侦听到。这是一个很好的特性 —— 不必为每个属性添加侦听器之类的东西 —— 但是这仍然会导致大量冗余代码。如果元素可以通过一种更方便的方式,就像电子表格中应用的依赖关系一样来使用这些属性,岂不是更好?通过约束,您就可以做到这一点。对于 Laszlo 中的任何属性,都可以为之赋予一个约束表达式(constraint expression),而不是赋予一个标准的值。约束表达式以一个美元符号开头,格式如下:
1
| $when{ConstrainedExpression}
|
其中,when 的值是 always、once 和 immediately 中的一个。如果忽略了 when,那么这个值就默认为 always,也就是说,每当 ContrainedExpression 的一个依赖关系发生改变,该约束都将重新计算。如果一个约束在初始化之后一直是静态的,那么可以将这个值设为 once,这样可以使约束只计算一次,可以提高效率。另一个值是 immediately,如果定义了结束元素,并且约束不依赖于其他对象,那么可以使用这个值来计算约束。
我们首先来看一个简单的例子。如果您想要一个大小可变的项,并且还有一个位于它中间的项,应该怎么办呢? 展示了如何实现这一点。它使用标准的 Laszlo 组件 slider 来控制矩形的大小。
清单 3. 用于控制一个矩形大小,同时影响矩形内部的另一个矩形的大小的 slider 组件1
2
3
4
5
6
7
8
9
10
11
12
13
| <canvas>
<slider id="sliderItem" y="20" x="10" minvalue="50" maxvalue="300"
value="50"/>
<view y="$once{sliderItem.y + sliderItem.height + 5}"
x="$once{sliderItem.x}" bgcolor="0xff0000"
width="${sliderItem.value}" height="${width}">
<view bgcolor="0x0000ff"
width="${parent.width / 5}" height="${width}"
x="${(parent.width / 2) - (width / 2)}"
y="${(parent.height / 2) - (height / 2)}"/>
</view>
</canvas>
|
您可以看到,由于 x 是 <view> 的一个属性,您可以使用一个约束来设置这个值。Laszlo 使用分层的方法来标识项,parent 对象是指包含控件。通过这种语法,可以访问该结构中的所有地方,但是也可以指定 name 和 id 属性。两者之间的不同之处是,id 标识的是一个特定的项(因此在文档中只能使用一次),所以它可以全局使用(例如在 中,我为 slider 控件使用一个 id 属性,然后在约束中使用那个 id:${sliderItem.value})。
在这个例子中,注意用于指定有色矩形的 x 和 y 位置的约束的 once 选项的使用。 给出了 中代码的输出。
图 2. 清单 3 的输出高级约束 约束对于替代简单事件和建立布局约束来说很棒,但是它们所提供的特性远远不止这些。由于可以为约束表达式设置任何 任意的属性值(包括您自己定义的值),或者在约束中使用它,因此存在很多可能。在下一节中,您将结合使用约束和 Laszlo 的动画制作系统来产生强大的结果。
动画和绘画 在现代界面设计中更关键的表示细节是动画。动画可以为界面的用户提供灵感和视觉感受。动画是 Macromedia Flash 的长项,也是 OpenLaszlo 的长项。动画也是目前不使用特殊的扩展就不能实现跨浏览器的少数几种技术之一。
动画标记 Laszlo 附带了两个元素用于帮助加快动画的开发:<animator> 元素是所有动画的基本构件,而 <animatorgroup> 则是 <animator> 项的容器。在 Laszlo 中,动画意味着在指定的一段时间内以复杂的组合改变不同属性的值。通过使用这些简单的概念和构件,几乎任何事情都有可能实现。
<animator> 元素有一个必需的名为 attribute 的属性。该属性指定动画将在哪个属性上进行操作。它还有一个必需的名为 to 的属性,该属性的值为一个数值,表示被操作的属性的终值。最后一个必需的属性是 duration,该属性指定动画所经历的时间,以毫秒计。为了方便,<animator> 元素还有一个可选的 from 属性,该属性为属性值设置起始点。通过使用这些属性,可以构造一个简单的程序,该程序以动画效果改变一个视图的宽度,如 所示。
清单 4. 一个简单的动画例子:改变视图的宽度1
2
3
4
5
| <canvas>
<view bgcolor="#ff0000" width="50" height="${width}">
<animator attribute="width" to="200" duration="1000"/>
</view>
</canvas>
|
在这个例子中将出现一个红色的正方形,并且该正方形在一秒内扩展到 200 乘 200 像素的宽度。如果试着运行这个例子,您会注意到这种运动并不是线性的。这是因为属性 motion 的默认值是 easeboth。通过使用 easein、easeout 或 easeboth,可以分别产生在动画开始或结束较慢或者在动画的开始和结束都较慢的效果。最后,motion 属性还可以带的一个值是 linear,该属性让动画以恒速变化。还要注意,动画是立即开始的,可以通过 start 属性来修改这一点,该属性的默认值是 true。最后,还有其他一些属性,包括用于控制步骤重复次数的属性(repeat)以及各种事件,例如 onstart、onfinish 等 —— 以支持在动画完成之后添加定制逻辑。
使用 <animatorgroup> 获得复杂动画 如前所述,<animatorgroup> 就是 <animator> 元素和其他 <animatorgroup> 元素的容器。然而,增加这种容器类型肯定可以增加很多可能性。<animatorgroup> 可以和 <animator> 一样定义所有相同的属性,还可以定义一个新属性:process。如果应用到 <animatorgroup>,则之前提到的所有属性将串连起来。新的属性 process 用于控制组中各个项的执行顺序。如果它的值是 sequential,则这些项将一个接一个地执行,直到整个组执行完毕。另一个选项是 simultaneous。
通过这两个选项,可以产生非常有趣的效果。例如可以有一个在屏幕上移动同时改变大小的项。由于组还可以包含其他的组,因此可以为动画定义一个好的结构和顺序。 |
|
|
|
|
|