fuse(Outdated)
2016年03月12日 08:16GMT+8
Getting Started: https://www.fusetools.com/learn/fuse#getting-started
- 相比 haxe 的一些跨平台UI库,多了一个本地实时预览功能
- android SDK/NDK设置 https://www.fusetools.com/learn/guides/preview-and-export-android
Note: 这篇文档仅作为个人笔记, 一些地方可能存在误解, 因此不保证内容的正确性, 缺点:
- 目前似乎不支持使用 system font, 这样导致需要嵌入中文字体会有点大
- 目前不能播放声音,仔细想想好像手机App(除了游戏)并不需要声音, 而通知有没有声音有系统决定
项目结构
在使用 fure 仪表板或命令行创建一个新项目后, 将在目录中可找到二个文件
- PROJECTNAME.unoproj 项目文件
- MainView.ux 应用的主入口文件, 因为它包括 App 元素。
注: Javascript 文件不需要从 .unoproj 内引用, 可直接在 .ux 文件中导入
UX Markup
Fuse主要使用 XML 来开发App, 这些 XML 最后将被转换成相应的Uno Class.(Note: 注意属性名带有 ux:
前缀和普通属性的区别)
ux 标记由以下几种类别:
- App 根节点, 并且一个 app 只能有一个
- Theme=”Basic|Native|NativeWithFallback”:
-
多数 Node 类型, 大多数为 UI Elements
- 修改 Node 的方式:
- Gestures(手势)
- Triggers(触发器)
- Scripts
- Visual effects 视角效果
- Styling(样式)
AutoBind
AutoBind 是一个元素属性,控制元素是否自动”连接”到父节点, 默认情况下将为 true, 但如果你想做些特别的可以设为 false
当设为 false 时, 这个元素将不会变成其XML父标记的子元素, 实际上它将保持独立对象树, 如果你需要在之后再添加到可视列表这还是有意义的
<Panel ux:Name="panel1" >
<Panel ux:AutoBind="false" ux:Name="panel2" />
</Panel>
组件
如果元素不包含子元素则可以使用类似于 <Text Value="Hello World" />
这样的单闭合样式.
Text
<Text>Hello, World</Text>
- TextWrapping=”Wrap|NoWrap(default)” 是否自动换行
-
Font: 需要添加 ttf 字体
<Font File="Roboto-Medium.ttf" ux:Global="Medium" /> <Font File="Roboto-Light.ttf" ux:Global="Light" /> <StackPanel> <Text Font="Light">Roboto Light</Text> <Text Font="Medium">Roboto Medium</Text> <Text Font="Light">Roboto Light again</Text> </StackPanel>
- TextColor = “#999|#999999”
- TextAlignment = “Left(默认)|Conter|Right”
- FontSize=”24” Int
- LineSpacing=”10” Int
Font: 见上边示例, 用于导入字体,字体通常用于整个应用, 因此被标记为全局资源 ux:Global="xxx"
Number: 大多数情况下和 Text 相似, Format 格式参考-中文
<Number Value="3.14159265359" Format="F03" />
将显示为 3.141
Image
支持 PNG 和 JPEG(in RGB color space)
- File: 本地加载与 ux 相同文件夹,只能是常量, 如果你想使用{变量} 需要创建资源然后使用 Source
- Url: 以 Http 的形式从网络加载
-
Source: 加载 Resource 类型的图像
<FileImageSource ux:Key="pic2" File="Images/Image2.jpg" /> <FileImageSource ux:Global="CloseIcon" File="close.png" Density="2" /> <StackPanel> <JavaScript> module.exports = { imageResource: "pic2", url: "http://somewhereontheinternet/Cute-Cat.jpg" } </JavaScript> <Image File="Images/Image1.jpg" /> <Image Source="{DataToResource imageResource}" /> <Image Url="{url}" /> <Image Source="CloseIcon" /> </StackPanel>
- Color=”#f00|#ff0000”: 将影响图片中白色或接近白色的部分
- StretchMode: 当图像添加到容器时将尽可能填满容器, 但如果图像并不是用来作为容器的背景部分,因此
- Fill: 填充容器中可用区域, 而不一定保持高宽比
- PixelPrecise: 使用图像的像素大小为单位来确保图像为crisp, 这意味着不同设备上图像大小不一致,它将忽略容器的大小
- PointPrecise: 使用图像的点(Points)大小为单位作为图像大小, 它确保所有设备上图像的大小一致,它将忽略图像容器的大小
- PointPrefer-PointPrefer: 拉伸模式将优先获得图像大小,TODO:
- Scale9: 九宫格缩放填充,根据 Scale9Margin 定义的值
- Uniform: 保持图片的高宽比, 这可能会使图片没有填充整个容器
- UniformToFill: 填充整个区域并保持高宽比, 这可能使图片的部分超出容器而不可见
- StretchDirection: 设置拉伸是拉大还是缩小
- Both:
- UpOnly: Only upscale contents(仅放大)
- DownOnly: Only downscale contents(仅缩小),有时候子元素大于父元素
- ContentAlignment: 设置图像在其区域内的对齐方式
- Default:
- Left:
- HorizontalCenter:
- Right:
- Top:
- VerticalCenter:
- Bottom:
- TopLeft:
- TopCenter:
- TopRight:
- CenterLeft:
- Center:
- CenterRight:
- BottomLeft:
- BottomCenter:
- BottomRight:
图像资源, 即上边使用 Source 指定图像资源,目前支持以下类型:
- FileImageSource: 单个本地图像文件以及它的屏幕密度(Density)
- HttpImageSource: 单个http图像以及的它的屏幕密度
-
MultiDensityImageSource: 同一个图像以及多个屏幕密度值
<!-- Fuse 将挑选最适合屏,尊循 StretchMode 的图像资源 --> <Image StretchMode="PointPrefer"> <MultiDensityImageSource> <FileImageSource File="Icon.png" Density="1"/> <FileImageSource File="Icon.png@2x.png" Density="2"/> </MultiDensityImageSource> </Image> <!-- 允许指定从HTTP获取并异步显示的图像 --> <!-- 注意 HTTP 可能需要一些时间来加载, 在加载之前Fuse将不能获得图像的大小,因此需要小心处理 --> <Image> <MultiDensityImageSource> <HttpImageSource Url="{image_url_1x}" Density="1"/> <HttpImageSource Url="{image_url_2x}" Density="2"/> </MultiDensityImageSource> </Image> <!-- 或者如果你使用固定的屏幕密度,可以直接简单 --> <Image Url="{image_url}" />
Video
视频显示, 和 Image 一样拥有 Url, StretchMode, StretchDirection, ContentAlignment
- File=”path/to/file.mp4”
- Volume=”0.0~1.0(默认值)”
- Duration:以秒为单位
- Position: 以秒为单位
- IsLooping=”false(默认)|true”
有用的触发器可用于 Video
<Video>
<WhilePlaying /> <!-- Active while the video is playing -->
<WhilePaused /> <!-- Active while the video is paused -->
<WhileCompleted /> <!-- Active while the video is done playing -->
<WhileLoading /> <!-- Active while the video is loading -->
<WhileFailed /> <!-- Active if the video failed to load or an error occured -->
</Video>
有用的操作可用于 Video
<Pause /> <!-- Pauses playback, leaving the current position as-is -->
<Stop /> <!-- Stops playback and returns to the beginning of the video -->
<Resume /> <!-- Resumes playback from the current position -->
<PlayTo Progress="..." /> <!-- Plays until the time specified by the Progress property -->
支持的格式依赖各自的平台. 因此你需要了解统一的格式, 下边是一个示例
<App Theme="Basic">
<DockPanel>
<Video ux:Name="video" Dock="Fill" File="fuse_video.mp4" IsLooping="true" StretchMode="UniformToFill">
<ProgressAnimation>
<Change progressBar.Width="100" />
</ProgressAnimation>
</Video>
<Rectangle ux:Name="progressBar" Dock="Bottom" Fill="#f00" Width="0%" Height="10" />
<Grid Dock="Bottom" ColumnCount="2" RowCount="1">
<Button Text="Play">
<Clicked>
<Resume Target="video" />
</Clicked>
</Button>
<Button>
<Clicked>
<Pause Target="video" />
</Clicked>
</Button>
</Grid>
</DockPanel>
</App>
Shapes
包含有 Rectangle 与 Circle,可以有多种填充及描边,这些将会相互层叠,
- Fill:”#f00|#ff0000” 填充的颜色值
- Width/Height:
- Color: “#f00|#ff0000|Yellow|Red|Green|Blue|…..” 感觉和 Fill 一样, 但
注意: 默认情况下将使用”点(Points)”作为单位, 而非像素值, 参考 Element Layer
Rectangle 例: <Rectangle Fill="#f00" Width="50" Height="50" CornerRadius="5" />
- CornerRadius: Int, 圆角
Circle,
- StartAngle/EndAngle 以弧度为单位
- StartAngleDegrees/EndAngleDegrees 以度为单位
- LengthAngle/LengthAngleDegrees 相对 StartAngle/StartAngleDegrees 的偏移, 用于代替 EndAngle/EndAngleDegrees
<!-- 为什么指定的是 Width/Height 而不是半径值?? -->
<Circle Fill="#f00" Width="50" Height="50">
<Stroke Width="5" Brush="#ff0" />
</Circle>
RegularPolygon 等边多边形: <RegularPolygon Sides="6" Fill="#000" Width="50" Height="50" />
- Sides: Int, 几条边
Ellipse 椭圆: <Ellipse Width="100" Height="50" Fill="#f00" />
除了常用的 Fill=”#f00” 属性还可以有
- LinearGradient
- ImageFill
<StackPanel>
<Circle Width="150" Height="150">
<ImageFill File="Pictures/Picture1.jpg" />
</Circle>
<Rectangle Height="150">
<LinearGradient StartPoint="0,0" EndPoint="1,0.75">
<GradientStop Offset="0" Color="#FC3C47" />
<GradientStop Offset="1" Color="#B73070" />
</LinearGradient>
</Rectangle>
</StackPanel>
Stroke: 边框
- Width:
- Brush: “#f00|#ff0000” 指定描边的颜色值
- Offset: 正值将边框外移(width/height指定的大小往外移)负数将往内部偏移,
SolidColor: 颜色填充
<!-- SolidColor 感觉就等于 Fill -->
<Rectangle>
<SolidColor Color="#f00" />
<Stroke Width="5">
<SolidColor Color="#0f0" />
</Stroke>
</Rectangle>
Button
Button 外观由 Theme 决定, 将填满分配给它的整个面积, 如果没有指定 Width/Height 时, 大多数元素也是如此
- Text=”Some Text”
- Clicked=”{buttonClick}” 调用 JS 方法(event-trigger)
<Button Text="Click me!" ux:Name="button1">
<Clicked>
<Set button1.Text="Clicked!" />
</Clicked>
</Button>
在 Fuse 中很多元素都可以点击(clickable)和Tab(tappable),因此你可以创建Button的组件类似于:
<Rectangle Fill="#309">
<Clicked>
<DebugAction Message="Rectangle got clicked" />
</Clicked>
</Rectangle>
Switch
类似于CSS中的单项选择
- Value=”true|false(默认)”
- ValueChanged=”{switchChanged}” 调用 JS 方法
<StackPanel>
<Switch>
<WhileTrue>
<Change rectangle.Width="160" Duration="0.5" Easing="CircularInOut" />
</WhileTrue>
</Switch>
<Rectangle ux:Name="rectangle" Width="70" Height="70" Fill="#909" />
</StackPanel>
Slider
可以配合 ProgressAnimation 动画
- ValueChanged=”{sliderValueChanged}” 调用JS
- Minimum/Maximum
<StackPanel>
<Slider>
<ProgressAnimation>
<Rotate Target="rectangle" Degrees="90" />
</ProgressAnimation>
</Slider>
<Rectangle ux:Name="rectangle" Width="100" Height="100" Fill="#808" />
</StackPanel>
请注意这个示例: 当 Slider 的progress值为 1 时,方块将旋转 90度, 而中间的插值 Fuse 将会自动帮你填充在拖动滑块时
TextInput and TextEdit
- TextInput: 由 Theme 决定其样式的文本输入
- TextEdit: 没有样式定义, 其它则完全和 TextInput 一样
示例可以将 TextInput/TextEdit 互换
<JavaScript>
var valueChanged = function (args) {
console.log(args.value);
}
module.exports = {
valueChanged: valueChanged
};
</JavaScript>
<TextInput ValueChanged="{valueChanged}" />
ScrollView
用于一些放置一些大小超过可视的内容, 可以配合 ScrollingAnimation 动画
- AllowedScrollDirections=”Horizontal|Vertical(默认)|Both” 用于限制滚动方向
<ScrollView>
<Panel Width="2000" Height="2000" />
</ScrollView>
NativeViewHost
一些 views 仅当为源生组件时才有效, 下边是一个 WebView 的示例:
<NativeViewHost>
<WebView Url="http://interwebs.com" />
</NativeViewHost>
注意: 源生组件永远位于其它组件上边(在显示图层上), 因它你调用 BringToFront/SendToBack 将不会有效.
GraphicsView, 当使用 Native 的 Theme 时, 这个是用来添加 Opengl 之类的组件的:
<App Theme="Native">
<StackPanel>
<Button Text="I'm a Native button!" />
<GraphicsView>
<Button Text="I'm a Fuse button!" />
</GraphicsView>
</StackPanel>
</App>
- WebView
- MapView
- MapMarker 子元素,用于添加地图标注
UI Elements
一些公共的元素属性 https://www.fusetools.com/learn/fuse#element
- HitTestMode: 点击元素时是否可以交互,以及交互规则
- None: 不交互
- LocalBounds: 基于自身大小
- LocalVisual: 基于自身外观(appearance)
- LocalBoundsAndChildren: 包含自身及其 子元素
- LocalVisualAndChildren: 包含自身及其子元素的外观(appearance)
-
ClipToBounds: 当指定为 “true” 时, 其子元素将不会 overflow(如果子元素指定例如 Margin=”-100”时)
-
Opacity: 0~1.0, 即使指定为 0, 但元素仍然处于 hit test状态
- Layer: 指定元素置于父元素的背影层还是 overflow 层如果不指定 Layer 属性, 那么这个元素将介于 Background 与 Overlay 之间
- Background: 展现于显示列表底层
- Overlay: 展现于显示列表顶层
<!-- 当没有 Layer="Background", 你将看不到 Hello --> <Button Text="Hello!"> <Rectangle Fill="#931" Layer="Background" /> </Button>
- ZOffset: 显示列表顺序,通常元素将按顺序展现。0 为默认的最底层
Effects
一些可视效果能添加到大多数组件, 需要 Basic Theme, 而 Native 将有限制
- DropShadow 阴影效果
- 例:
<DropShadow Angle="90" Distance="12" Size="20" Spread="0.1" Color="#ff06" />
颜色值为 RGBA???
- 例:
- Blur 模糊
- 例:
<Text Value="Hello there!"> <Blur Radius="0.9" /> </Text>
- 例:
- Desaturate 去色
- 例:
<Image File="Pic.jpg"> <Desaturate Amount="0.4" /> </Image>
- 例:
- Halftone 像是一个奇怪的的滤镜效果
- 例:
<Image File="Pic.jpg"> <Halftone Spacing="0.5" Smoothness="2" Intensity="1" DotTint="0.5" PaperTint="0.2" /> </Image>
- 例:
- Mask: 示例: 仅显示 Rectangle, 图像的非 alpha 通道的区域, 感觉就像是加载了一张图片, 如果 Rectangle 的颜色为 #FFF 的话.
- Mode = “RGBA(default)|Alpha|Greyscale”
- 例:
<Rectangle Width="50" Height="50"> <Mask File="Masks/Flower.png" /> </Rectangle>
Layout
Fuse 提供强有力的布局系统在所有平台及设备, 不论是 native 元素还是基于graphics 的元素.
Panels
可以包含子UI元素并让它们按照布局规则, 这里有一些不同类型 panels有着各自不同的布局规则
- Panel 最基本布局的类型, 子元素默认将占据整个空间, 如果包含多个子玩素, 则同时显示多个子素(因此可能会有重叠和遮盖)
结合使用 Alignment,Margin,Padding 在一些情况下将非常有用.
- 子元素的显示排列顺序为: “排在前边的元素将显示在顶层”
对于App的直接子元素,排在后边的将会显示在顶层,并且即使没有重叠, 前边的元素也不会显示)
- StackPanel 子元素表现为堆栈(多个元素将按顺序堆叠), 默认为竖排堆叠. 可以通过 Orientation 属性修改
- Orientation=”vertical (默认)|Horizontal”
- ItemSpacing=”10” 二个堆叠元素的间距, 这个区别于子元素的 Margin设置
- Grid: 栅格, 每一行或每一列可以为各自确定的值,或者根据 RowCount 和 ColumnCount 的值来统一调整
- RowCount/ColumnCount: 仅指定”行数/列数”
- Rows/Columns: 值可以为 Points(“10,10,50”),percent(“1,1,3*” 相当于: “1/5, 1/5, 3/5”)
- CellSpacing: 单元格之间的间距
- 默认情况下, 栅格子元素要么从上往下,要么从左往右。可通过在子元素上添加 Row/Column 来指定子元素的位置
<!-- Row/Column 的第一行/列都将从 0 开始 --> <Grid RowCount="1" ColumnCount="2"> <Rectangle Row="0" Column="1" Color="Red"/> <Rectangle Row="0" Column="0" Color="Blue"/> </Grid>
- WrapPanel: 使其子元素一个接着另一个环绕排列下去。wrap 即换行的意思.
- FlowDirection=”LeftToRight/RightToLeft” 排列方向
- ItemWidth/ItemHeight: 限制子元素的最大宽度/高度
- 没有可以指定子元素间隔的属性, 因此只能用子元素的 Margin 来设置.
- DockPanel: 使其子元素dock(钉)在各自指定的位置, 一个在另一个的后边(如果位置相同)
- Dock=”Left|Top|Right|Bottom|Fill(默认)” Fill 表示将填充所有剩余的空间(如果仅指定了 MinWidth/MinHeight)
- 注意: 对于属性值为Fill的多个子元素, 它们将堆叠在一起而不是像其它值一样一个接一个的层叠。
- Viewbox: 拉伸子元素以适合区域(仅显示最一个子元素, 而前边的子元素将隐藏)
- StretchDirection=”Both|UpOnly|DownOnly”
- StretchMode=”Uniform(默认)” 参见 Image 章节
- 例:
<Viewbox> <Rectangle Color="#808" Width="200" Height="100" /> </Viewbox>
- 如上示例 rectangle 的宽高比为 2/1, 因此这个比例将会填满整个 ViewboxBox,仍旧保持 2/1的宽和高
Layout rules
对于上边的布局其实在底层它们是由普通的 Panel 和 布局相关联(但并不是所有都是这样)
- DockLayout: 放置于 Panel 将使其和 DockPanel 一样
- ColumnLayout: 将同层的其它元素(即其父元素Panel的所有可视子元素)分隔为列. 可由 ColumnCount 调整宽度。它将尝试保持 ColumnCount 所定义的数量
- CircleLayout: 将同层的其它元素(即其父元素Panel的所有可视子元素)以圆排列.
- StartAngleDegrees/EndAngleDegrees: 起始及结束的角度值(感觉排列的位置不太对??)
- Radius: 0~1.0~out 相对于父元素
- ItemSpacingDegrees: 间隔
Element Layout
当 Panel 开始布局其子元素, 它将访问所有子元素与布局相关的属性.
- Alignment: 表明子元素相对于其父元素的对齐方式,当一个元素放置于 Panel 中, 可能并不需要将所有空间都给它
- 包括的值有: “Left|HorizontalCenter|Right|Top|VerticalCenter|Bottom|TopLeft|TopCenter|TopRight”
- 接上边: “CenterLeft|Center|CenterRight|BottomLeft|BottomCenter|BottomRight”
- Visibility:Hide 虽然不可见但仍然占据其空间,而Collapse不可见并且不占用空间
- 包括的值为: “Show|Hide|Collapse”,
-
Width/Height:结合 Alignment 使用. 元素的 Width/Height仅包括了Stroke(边框)和Padding不包括Margin;
- Margin/Padding: 与其父元素或兄弟元素之间的距离/填充, 如果指定了 Width/Height 则在对齐后再应用 Margin
<Rectangle Margin="20,30,50,10"/>
: 分别为 左, 上, 右, 下(注意区别CSS属性的顺序)<Rectangle Margin="50"/>
: 全部一致<Rectangle Margin="50,20"/>
: 左,右 vs 上,下 (同样需要和CSS相区别)
单位: points(点,默认),percent(百分比)和 pixels(像素)
- 可用于:
MinWidth/MaxWidth/MinHeight/MaxHeight/Offset/Anchor/
- 注意: Grid 的 column 和 row 使用其自身的规则
Rectangle Width="50"/> <!-- points -->
<Rectangle Width="30%"/> <!-- percent -->
<Rectangle Width="200px"/> <!-- pixels -->
- Anchor: 布局锚点. 默认情况下 panel 将使用元素的中心点作为元素的锚点(注意: 这里是一个容易混淆的地方)
- 例:
<Rectangle Anchor="0,0"/>
将使元素的锚点更改为左上角
- 例:
-
X/Y: 绝对定位, 使用绝对定位就应该尽量避免使用其它布局规则(Alignment,Margin)
- TransformOrigin: 指定元素移动,大小,旋转,缩放时的基点
- Center(默认)
- TopLeft:
- Anchor: 根据其 Anchor 属性的值
- HorizontalBoxCenter:Simulates the effect of the element being the front-facing side of a cube in 3D space, using the width of the element for determining the depth of the cube. Without the element being in a Viewport this will have no illusion of depth, effectively rendering it useless.
- VerticalBoxCenter:与 HorizontalBoxCenter 一样, 只是它使用元素的高度值确定深度
-
LayoutMaster: 指定布局相对的元素(如果没有这个属性, 那就相对于父元素布局), 例如当指定对齐时
查看 当 LayoutMaster 元素发生改变时, LayoutAnimations 动画将被激活 的示例…
Viewport
允许执行一些 perspective projection 的3D动画, 有一些的限制, 不可以处理局部的 perspectives
<App Theme="Basic">
<Viewport Perspective="400">
<Panel>
<Rectangle Width="200" Height="200" Background="#2ecc71">
<Clicked>
<Rotate DegreesX="360" Duration="1.5" Easing="QuadraticInOut" DurationBack="0" />
</Clicked>
</Rectangle>
</Panel>
</Viewport>
</App>
Status bars
IOS 和 Andriod 通常会有一个状态栏显示如电池,信号之类的, 在 APP 中状态可以显示或者是不显示
- StatusBarBackground: 填充状态栏边距,在所有设备及平台它将与状态栏有着同样的大小
- BottomBarBackground:将和键盘有一样大小(比如在用户输入时,如果不重新调整布局那么输入框很可能会被弹出来的键盘挡住)
- ClientPanel: 位于 StatusBarBackground 与 BottomBarBackground 之间的
<!-- 因此正常的App应该看起来像这样 -->
<App Theme="Basic">
<DockPanel>
<StatusBarBackground Dock="Top"/>
<ClientPanel>
......
</ClientPanel>
<BottomBarBackground Dock="Bottom"/>
</DockPanel>
</App>
Triggers and Animators
Trigger 表现为事件触发, 如用户输入,程序事件. Triggers可以包含Animators和Actions元素用于展现动画和操作元素。
动画元素需要放置于 Triggers 元素的下边,如果没有交互或程序触发, 可放置于 WhileEnabled 下
简单示例: 点击住 Panel 时, 旋转 90度:
<Panel>
<WhilePressed>
<Rotate Degrees="90" Duration="0.5" Easing="BounceInOut"/>
</WhilePressed>
</Panel>
-
默认的UX标记元素将为休息(rest)状态, Triggers 将使元素偏离休息状态,每个 Trigger 知道如何反向应用动画回到 rest 状态, 即使中断动画.
-
分离的向前(forward)及回复(backward)动画, 即 rest到动画完成,然后恢复到rest状态可以分离
为了做到这一点, 需要把 backward 把动画放置于 TriggerAnimation 内, 并且添加
ux:Binding="BackwardAnimation"
<Panel Background="#f00"> <WhilePressed> <Rotate Degrees="90" Duration="0.5" /> <TriggerAnimation ux:Binding="BackwardAnimation" > <Rotate Degrees="90" Duration="10" Easing="BounceOut" /> </TriggerAnimation> </WhilePressed> </Panel> <!-- BackwardAnimation 是自动右对齐 -->
Animators
Animators 用来指定和如何使用元素执行动画. 这有三个重要的动画控制属性:
- Duration/DurationBack 动画持继时间, 向前及恢复
- Delay/DelayBack
- Easing/EasingBack: Note: 记得添加 In,Out,InOut在每个值上
Linear\|Quadratic\|Cubic\|Quartic\|Sinusoidal\|Exponential\|Circular\|Elastic\|Back\|Bounce
- 每个 easing 都将有 In,Out,InOut 三种状态。例: CubicIn,CubicOut,CubicInOut
动画需要由 trigger 触发, 因此不能直接就放在元素下边, 注意区别 Transforms
属性动画: 通过 Target 来指定元素的属性
-
Change 当 trigger 激活时, 暂时将更改的值, 若要永久更改其值,需要使用 Set 动画.
<Panel ux:Name="somePanel" Color="Red" /> <Change somePanel.Opacity="0"/> <Change somePanel.Color="Blue" Duration="0.3"/> <Change somePanel.Visibility="Collapsed"/> <!-- 另一种方式 --> <Change Target="somePanel.Opacity" Value="0"/>
同样可以更改元素的 Width/Height或Margin, 只是这些属性会破坏整体布局,并导致一些性能问题.
通常有更有效的方法来做布局方面的动画: LayoutAnimation 和 MultiLayoutPanel
-
Cycle 周期性在二个值之间的动画,例如不断闪烁的激光, 你还可以指定 Duration 来控制动画时长
- Frequency: 例 0.5即每秒半个周期
- 似乎不支持Duration , 以及 Easing 仅支持 Linear???
<Panel> <Translation ux:Name="someTranslation" /> <WhilePressed> <Cycle Target="someTranslation.X" Low="-20" High="20" Frequency="2" /> </WhilePressed> </Panel>
变形动画(Transform animators):
-
Move 移动元素, Move 并不影响布局, 因此元素仅会偏移位置
<Move X="50" /> <!-- 触发时元素将在 X 方向移动 50点(points) --> <!-- 或者相对于自身或其它元素的大小, 往 X 方向移动自身的一半 --> <Move X="0.5" RelativeTo="Size" />
RelativeTo 可以设置为:
- Local(默认): 在 X 或 Y 方向移动点的量值
- Size: 移动的量相当于自身或关联元素的大小. X=”1” 将移动 X 方向的整个宽度大小
- ParentSize: 和 Size 一样, 但使用父元素作参照
- PositionChange: 用于响应 LayoutAnimation 的移动量
- WorldPositionChange: 用于响应 LayoutAnimation 的移动量
- Keyboard: 相对于键盘大小
RelativeNode 属性可以让移动相对于另一个元素, 这时 RelativeTo 可接受的值为:
- Size: 同上, 但为关联元素的大小
- ParentSize: 同上, 但为关联元素的父元素
- PositionOffset: 向关联的元素的方向移动, 二个元素位置的差值
- TransformOriginOffset: 像 PositionOffset, 但 TODO:
Move 等效于在元素上添加 Translation 并使用 Change 的动画:
<Panel> <WhilePressed> <Move X="100" Duration="0.2"/> </WhilePressed> </Panel> <!-- 等效于 --> <Panel> <Translation ux:Name="someTranslation"/>Transition <WhilePressed> <Change someTranslation.X="100" Duration="0.2"/> </WhilePressed> </Panel>
-
缩放, 缩放并不更改元素的实际大小, 因此使 UI 布局不会受影响
<Scale Factor="2" Duration="0.4"/> <!-- Factor 将对所有轴同时缩放, 或单独地使用 X,Y,Z轴 -->
其 RelativeTo 属生可指定为:
- SizeChange: 相对于指定元素(RelativeNode)大小
- SizeFactor: 相对于另一个元素(RelativeNode), 如果设为 1, 这个元素将与另一个元素变得一样大小
-
旋转, 前边已经有示例, 可指定:
DegreesX, DegreesY, DegreesZ(等同于Degrees)
,<Rotate Degrees="90" Duration="0.5"/>
-
Resize, 与 LayoutAnimation 一起使用, Resize 将允许动画调整元素大小
<Resize RelativeTo="SizeChange" Duration="0.5" Easing="CircularInOut" />
RelativeTo 有二个选项:
- SizeChange: 在 LayoutAnimation 期间
- Size: 指定元素的大小通过(RelativeNode)
-
Spin, 周期性自旋, Frequency 给出每秒将要旋转的圈数, 这个非常适合来做 Loading 动画
<WhileTrue Value="{isLoading}"> <Image ux:Name="img" File="busy.png" /> <Spin Target="img" Frequency="1" /> </WhileTrue>
-
Skew, 倾斜,
DegreesX, DegreesY, DegreesXY
<Skew DegreesX="30" Duration="0.4" />
-
Attractor 用于给动画添加更自然的运动.(但是这样层层绑定有些太绕了)
<Panel ux:Name="somePanel"> <Translation ux:Name="someTranslation"/> <Attractor ux:Name="someAttractor" Target="someTranslation.X"/> <WhilePressed> <Change someAttractor.Value="100"/> </WhilePressed> </Panel>
-
Keyframes 更精确的控制动画, 更多详情…
<Move RelativeTo="ParentSize"> <Keyframe X="10" Time="0.5"/> <Keyframe X="15" Time="1"/> <Keyframe X="5" Time="2"/> </Move> <!-- 或者使用 TimeDelta 代替 Time, TimeDelta 是一个相对于上一帧的时间 -->
-
Nothing 所有动画都在 Trigger 后共享同一个时间轴直到动画完成并结束, 在某些罕见的情况下你可以有想要人为地延长时间轴, 从逻辑上来说, 它是一个空白的动画, 迫使动画至少须持继时间轴长度
<Nothing Duration="1" />
Transforms
所有元素都可以移动, 缩放,旋转, Transforms的先后顺序,将会导致不同的结果,
这个和 Animators 不一样的是, 不可以放在 trigger 下, 也没有 Duration 和 Easing, 并且不会处理恢复及动画插值
- Translation: 移动元素在指定的X,Y,Z方向
- Scaling:
<Scaling Factor="2"/>
- Rotation:
<Rotation Degrees="90"/>
- Shear: 错切(特殊性性变换)
- 指定 DegreesX和DegreesY 将设置错切在某一轴上
- 或指定 Degrees和Vector值设置错切同时用于 X 和 Y 平面, 使用度数或弧度
Actions
Actions不具有自动恢复性,及 Duration 属性, 但将具有 AtProgress(形为有些类似于Delay) 介于 0~1 之间的值, 和 Delay 属性
- DebugAction: 将消息输出到调试终端(如果激活), 等效于Uno或JS中的 debug_log
<DebugAction Message="Clicked!" />
-
Set: 永久性的更改属性的值, 如果你只是想暂时改变可以使用 Change
<Rectangle ux:Name="rect" Color="#00f" /> <Clicked> <Set rect.Color="#f00" /> <!-- <Set Target="rect.Color" Value="#f00" /> --> </Clicked>
-
Callback 用于 JS(见数据绑定章节)
<JavaScript> var someJSFunction = function () { console.log("some function called"); } module.exports = { someJSFunction: someJSFunction }; </JavaScript> <Rectangle Width="100" Height="50" Alignment="Center" Fill="Red"> <WhilePressed> <Callback Handler="{someJSFunction}"/> </WhilePressed> </Rectangle>
- GoForward 使 navigation context 或 WebView 的历史记录”前进”
<GoForward TargetNode="myNavigation" />
- GoBack: 使 navigation context 或 WebView 的历史记录”后退”
<GoBack TargetNode="myWebView" />
-
Toggle: 切换 true 或 false. 如果在 Switch 内将切换其值. 也可用于激活/取消 WhileTrue
<WhileTrue ux:Name="trueTrigger"> ... </WhileTrue> <Panel> <Clicked> <Toggle Target="trueTrigger"/> </Clicked> </Panel>
-
Pulse: 用来即时触发 Timeline ~~WhileTrue, WhileFalse 或 ~~
-
BringIntoView: 与 ScrollView 一起使用,通过设置其 TargetNode 属性,可以使 ScrollView 滚动到指定位置
-
BringToFront: 置于将指定的元素置于其父元素的显示列表顶层。
-
TransitionLayout: 创建临时的布局动画,而非真实的布局更改。必需要结合 LayoutAnimation 同时使用。
- NavigateToggle: 目前仅支持在 EdgeNavigation 中,通过设置 EdgeNavigation.Edge 切换其 Target 指向的目标
Gestures
属于 trigger
-
Clicked 点击.(press 与 release 都在同一个元素上)
<Panel Width="50" Height="50"> <Clicked> <Scale Factor="2" Duration="0.2"/> </Clicked> </Panel>
-
Tapped 轻触. 有些类似于Clicked,(但 press 与 release 几乎在相同的时间)
-
DoubleClicked
-
DoubleTapped
-
WhilePressed 当按住时
-
WhileHovering 仅在设备支持时才可用.(手机上会有hover???)
-
SwipeGesture 滑动。 需要和其相关元素同时使用才有效果
- Direction=”Right|Left|Up|Down” 滑动的方向
- Edge 用于替代 Direction
- HitSize 当有 Edge 属性时可用. 滑动后的区域
- Length=”100” 滑动的距离与 Direction 一起用
- LengthNode 可用于代替 Length. 它将引用到另一个元素之间的距离
- Type=”Active|Simple(默认)” 在inactive/active这间切换状态 or 仅为简单的触发(相关的元素将根据这个值作一些行为)
SwipeGesture相关元素
-
SwipingAnimation 当Type=”Active”时, 能保持住Animators后的效果,并且能自动处理以反手势切换回原状态
<Panel ux:Name="parentContainer" Margin="40" Background="#ff4800"> <Panel Width="60" Height="60" Background="#000" Alignment="Left"> <SwipeGesture ux:Name="swipe" Direction="Right" Type="Active" LengthNode="parentContainer" /> <SwipingAnimation Source="swipe"> <Move X="1" RelativeTo="Size" RelativeNode="parentContainer" /> </SwipingAnimation> </Panel> </Panel>
-
Swiped 不能保持 Animators 后效果, 类似于简单触发, 如果 Type=”Active” 当切换到 inactive 状态时,将需要以反手势切换回 active
<Panel Width="100" Height="100"> <SwipeGesture ux:Name="swipe" Direction="Up" Length="50" Type="Simple" /> <Swiped Source="swipe"> <Scale Factor="1.5" Duration="0.4" DurationBack="0.2" /> </Swiped> </Panel>
-
WhileSwipeActive:
TODO: 不知道在形为上和 SwipingAnimation 有什么区别? 因为它也能保持 Animators 后效果, 如果指定 Duration, 动画效果似乎比 SwipingAnimation 更平滑???
<Panel Width="100" Height="100"> <SwipeGesture ux:Name="swipe" Direction="Up" Length="50" Type="Active" /> <WhileSwipeActive Source="swipe"> <Scale Factor="1.5" Duration="0.4" DurationBack="0.2" /> </WhileSwipeActive> </Panel>
-
SetSwipeActive/ToggleSwipeActive 控制 SwipeGesture Type=”Active” 时的状态。用于通过其它事件控制手势动画等等
<!-- 将下边示例代码添加到上边相位置观察 --> <StackPanel> <Button Text="Close"> <Clicked> <SetSwipeActive Target="swipe" Value="false" /> </Clicked> </Button> <Button Text="Toggle"> <Clicked> <ToggleSwipeActive Target="swipe" /> </Clicked> </Button> </StackPanel>
Data triggers
当数据的值发生改变时触发
- WhileTrue
- WhileFalse
Native triggers
-
Platform
<Panel> <Android> <Panel Background="#f00" Alignment="Center" Width="150" Height="150"/> </Android> <iOS> <Panel Background="#00f" Alignment="Center" Width="150" Height="150"/> </iOS> </Panel>
-
WhileKeyboardVisible 当键盘显示时触发
-
TextInputActionTriggered 当按下”回车键”时触发,而不是任意按键
<!-- 这个示例展示了如何隐藏键盘,当输入完成后 --> <TextInput> <TextInputActionTriggered> <ReleaseFocus /> </TextInputActionTriggered> </TextInput>
-
OnBackButton 当用户按了手机或模拟器的 “返回” 键时
-
OnKeyPress 当按定的键按下时, 所有可用按键…
<Panel> <Rectangle ux:Name="rect" Layer="Background" Color="#F00" /> <OnKeyPress Key="MenuButton"> <Change rect.Color="#00F" Duration="0.2" /> </OnKeyPress> </Panel>
Native actions
Fuse 提供一些当调用系统的动作, 例如: 拨打电话或振动设备
Fuse.Launcher
注意: 确保在 .unoproj 文件中的添加 Fuse.Launcher 到 packages 下.
- LaunchUri 请求系统打开指定的Uri
- 例:
<LaunchUri Uri="https://www.fusetools.com" />
- 例:
- LaunchEmail 启动默认邮件应用
- To: 例:
<LaunchEmail To="contact@fusetools.com" />
- CarbonCopy: 抄送
- BlindCarbonCopy: 密送
- Subject
- Message
- To: 例:
- LaunchMaps 启动默认的地图应用
- 例:
<LaunchMaps Latitude="35.673813" Longitude="-36.780810" />
- 例:
- Call 打电话给指定号码
- 例:
<Call Number="123 45 678" />
- 例:
- Vibrate 振动设备(注: IOS 将忽略指定的 Duration 属性)
- 例:
<Vibrate Duration="0.8" />
- 例:
State groups
State groups 允许定义完全的自定义状态用于自定义事件
- State: StageGroup 中的一个某一种状态
- StateGroup 这个自已看示例
User events
User events 用于在组件之间传递消息. 可发送以及接收在 UX,Uno 和 JavaScript 中.
你需要同样看这些文档 FuseJS UserEvents from JavaScript
- UserEvent 将附加到节点所在父元素, 只有所有这个父元素下的节点可以 raise 以及 handle 这个事件.
- Note: 确保在 .unoproj 文件中添加了 “Fuse.UserEvents”
- RaiseUserEvent 触发事件,通过 UX
- 传递参数通过 UserEventArg
-
OnUserEvent 监听事件,默认情况下仅监听其祖先节点的事件, 如果需要监听任意处事件, 可设置 Filter 属性为 Global.
<App> <UserEvent Name="MyEvent"/> <!-- ... --> <Button> <Clicked> <RaiseUserEvent Name="MyEvent"> <UserEventArg Name="message" StringValue="Hello from UX!" /> </RaiseUserEvent> </Clicked> </Button> <!-- 监听事件 --> <OnUserEvent Name="MyEvent"> </OnUserEvent> <OnUserEvent Name="MyEvent" Handler="{myHandler}" />
Viewport triggers
当屏幕发生改变时(横屏,竖屏)
-
WhileWindowLandscape: 当横屏时(当app视角的width大于height时)
<App ux:Name="app" Theme="Basic" Background="#FFF"> <WhileWindowLandscape> <Change app.ClearColor="0,0,1,1" Duration="1" /> </WhileWindowLandscape> </App>
- WhileWindowPortrait: 当竖屏时(宽度小于或等于高度)
- WhileWindowSize: 当app视角大小符合下边三种时:
- GreaterThan=”width,height”
- LessThan=”width,height”
- EqualTo=”width,height”
<Panel> <SolidColor ux:Name="coloredPanel" Color="#F00" /> <WhileWindowSize GreaterThan="400,400"> <Change coloredPanel.Color="#0F0" Duration=".5"/> </WhileWindowSize> </Panel>
Control triggers
- WhileEnabled 当包含它的元素的 IsEnabled(表示是否交互和事件或动画) 值为 true 时,(默认都为true)
- WhileDisabled
Focus triggers and actions
- WhileFocused 当包含它的元素获得焦点时
- WhileNotFocused
- WhileFocusWithin 当包含它的元素的子节点获得焦点时
actions
- GiveFocus: 将焦点给包含它的元素
- ReleaseFocus 移除当前焦点元素
WebView-specific triggers & actions
- PageBeginLoading: 触发一次, 当 WebView 开始加载 content
-
WhilePageLoading: 当 WebView 的 Url 更改,并用保持这个状态直到 content 加载完成
<NativeViewHost> <WebView Url="http://fusetools.com"> <PageBeginLoading> <DebugAction Message="Page began to load!"/> </PageBeginLoading> </WebView> </NativeViewHost>
- PageLoaded: 触发一次, 当 WebView完全加载完 URL 的内容
actions
- Reload: 让 WebView 重新加载
<Reload TargetNode="myWebView" />
- LoadUrl: 指定加载 Url
<LoadUrl TargetNode="myWebView" Url="http://mypage.com" />
-
LoadHtml: 使用 WebView 加载直接 Html元素
<LoadHtml TargetNode="myWebView" BaseUrl="http://my.domain"> <HTML> <![CDATA[ <h1>Boom!</h1> ]]> </HTML> </LoadHtml>
-
EvaluateJS: 执行有一些限制的任意JS于当前加载环境。
<EvaluateJS Handler="{onPageLoaded}"> var result = { url : document.location.href }; return result; </EvaluateJS>
由于仅能从JS中返回字符串值, 因此在接收返回值时你可能需要用到 JSON 相关的方法
如果你没有返回任何值, 返回值将默认为 “null”
Special Animations
Animations 将会自动帮你处理插值, 以及一些恢复
- LayoutAnimation: 布局变化时触发,
- AddingAnimation: 当元素添加到可视列表时, 注意: 设置动画的初使值,因为元素的默认值为动画的最终值
- RemovingAnimation: 当元素从可视列表中移除时
- ActivatingAnimation: 当Page(见navigation)激活时
- DeactivatingAnimation:
- ScrollingAnimation: ScrollView 滚动时动画
- From:
- To:
- PullToReload: 非常容易地创建 “pull to relaod” 交互
- WhileScrollable: 当 ScrollView 的指定方向可以滚动时,根据 ScrollDirections 的参数
- ScrollDirections=”All|Both|Down|Horizontal|Left|Right|Up|Vertical”
- ProgressAnimation: 当 slider 元素滑块移动时, 值将总是从 0~1
- Timeline: 将多个动画组合在一起的不错方法
- TargetProgress=”0~1”
Data Binding
通过 Observable 绑定到 UX, 不可以绑定Object的子值(如果需要这样做需要将所有子值都变成Observable),
Resources
-
ux:Global
创建全局资源,比如字体, 颜色, 声音(目前还不能播放声音)<Font File="HelveticaNeue-MediumCondensed.ttf" ux:Global="Helvetica" /> ...... <Text Font="Helvetica">Hello, yes, this is text.</Text>
ux:Key
创建动态资源- string
- bool - true or false
- float - 1, 0.2 , .2
- float2 - “1,1”
- float3 - “1,0.2,1”
- float4 - “1,1,1,3.2”
<string ux:Key="WelcomeMessage" ux:Value="Hello World!"> ...... <Text Value="{Resource WelcomeMessage}" />
- 使用 StateGroup 的方式来实现本地化
Creating custom UI components
https://www.fusetools.com/learn/fuse#creating-custom-ui-components
-
ux:Class
用于样式化元素: 这其实相当于public class Header: Text{...}
<Text ux:Class="Header" FontSize="22" /> ...... <Header>Welcome</Header>
ux:Property
:当自定义样式时如果需要, 可用来自定义属性- 注意如何在元素中调用自定义的属性,
this
将指向根节点的ux:Class
。 -
如果你需要传递 Observable 或 Array 类型的属性, 使用
object
类型 -
ux:InnerClass
: 参考官网示例, 可以在 InnerClass 定义的内部访问其所在域的 ux:Name 的元素 ux:Include
: 在当前行插入 UX 文件
Navigation
用于在多个页面(Panel)之间切换, 一些概念:
<Panel>
<Panel Background="Red"/>
<Panel Background="Blue"/>
<Panel Background="Green"/>
</Panel>
上边的示例只会显示 Red,仅显示第一个, 后边的将被隐藏。 需要注意的是 App 下的元素将显只示最后一个而前边的被删除(重写了)
为了通过手势来实现在 Panel 之间切换, 需要做三件事:
- 一个 Navigation 行为
- 一个 SwipeNavigate 行为
- EnteringAnimation 以及 ExitingAnimation
- 如果你使用 Change 来触发动画, 那么只有 EnteringAnimation 也可以, 因为 Change 能自动恢复
- 但你使用 Set 触发, 则提供需要二个(比如你弹出一个菜单, 并不想它自已马上回去)
<Panel>
<Panel ux:Class="NavPanel">
<EnteringAnimation> <!-- 当开始动画时,即从右往左拖时 -->
<Move X="-1" RelativeTo="ParentSize"/>
</EnteringAnimation>
<ExitingAnimation>
<Move X="1" RelativeTo="ParentSize" Duration="0.5"/>
</ExitingAnimation>
</Panel>
<LinearNavigation /> <!-- 一个 Navigation 行为 -->
<SwipeNavigate SwipeDirection="Left"/> <!-- 一个 SwipeNavigate 行为 -->
<NavPanel Background="Red"/>
<NavPanel Background="Blue"/>
<NavPanel Background="Green"/>
</Panel>
当 Panel 包含了 Navigation 行为, 那么它的所有直接子元素将为导航页面(Page)。
Page
基本和 Panel 一样, 除了带一个属性 Title(这个属性其实就像个名字而已),
个人注: Page + PageControl + PageIndicator 是 Fuse 提供的一个使用了 LinearNavigation 的页面, 而其它 navigation type 需要自已定义它们的形为
PageControl 页面导航控制
- InactiveState 控制子元素的 Visibility 及 IsEnabled 状态当其在屏幕不可见时
- Collapsed(默认): 设置 Visibility=”Collapsed”, 因此不活动的Page将不可见以及不计算其布局
- Disabled: 设置 IsEnabled=”false” 不活动的page将可见, 但不可交互
- Unchanged: 不活动的page保持原样(as-is)。
- Transition=”Standard(默认)|None”: 控制转换。 标准的 sliding 动画 or 无动画(使用这项实现自已的动画)
- Interaction=”Swipe(默认)|None”: 触发动作。 手势 or 不直接交互(使用这项实现自已的导航控制/手势)
-
Active=”NAME” 指定NAME为活动page, 这样就能自定义上边的 None 了.
<!-- 相比上边的示例, 这一个是不是简单多了? --> <PageControl> <Panel Background="Red"/> <Panel Background="Blue"/> </PageControl>
PageIndicator 小圆点组件(通常手势切换页面时都会有这个小圆点组件,显示当前第几页, 以及总共的页数)
<DockPanel>
<PageControl ux:Name="pageControl">
<Page Background="Red"/>
<Page Background="Blue"/>
<Page Background="Green"/>
<Page Background="Yellow"/>
</PageControl>
<PageIndicator Navigation="pageControl" Dock="Bottom" Alignment="Center">
<Circle ux:Generate="Factory" ux:Binding="DotFactory"
Fill="Teal" Margin="5" Width="20" Height="20">
<ActivatingAnimation>
<Scale Factor="1.3"/>
</ActivatingAnimation>
</Circle>
</PageIndicator>
</DockPanel>
注意这个示例中使用的 ux:Generate="Factory" ux:Binding="DotFactory"
{Page} Binding 语法 {Page res_name}
将允许关联资源到当前活动的页面, 它仅从当前活动页面(Page)元素中查找资源而不是节点,见下边示例,
<DockPanel>
<Panel Navigation="myNav" Dock="Top" Height="100" Background="Teal">
<Text Value="{Page title}" FontSize="22" Alignment="Center"/>
</Panel>
<PageControl ux:Name="myNav">
<Page Background="Red">
<string ux:Key="title" ux:Value="First page"/> <!-- 被引用的资源 -->
</Page>
<Page Background="Green">
<string ux:Key="title" ux:Value="Second page"/>
</Page>
</PageControl>
</DockPanel>
- 属性: Navigation: 见下边示例的 Panel,将其指定为 PageControl 的名字即可在切换 Page 时随之更改内容, 像是一个随着 Page 变换而更改资源的 {Resource res_name} 一样
- 资源通过有各 Page 元素下使用
ux:Key="TILE NAME"
来定义 - 这个特性可以创建有趣的 PageIndicator, 我们可以使用图片代替前边的圆形
Fuse 提供的 Page 元素相前的定义就上边这些, 下边是自定义的内容
Navigation types
通过指定 Navigation 的 Active="panel_name"
属性来激活
-
LinearNavigation
-
DirectNavigation: 页面切换之间没有动画
-
HierarchicalNavigation: 直接从主页面切换到各相关子页,而不像 LinearNavigation 需要一个一个按顺序来, 可以使用 NavigateTo, GoBack, GoForward, 和 WhileCanGoForward 进行一些控制
- EdgeNavigator: 用于从侧栏切换出菜单(示例有些复杂, 例如从左侧切出半个屏幕宽度的页面作为菜单)
- 它的第一个Panel子元素为菜单, 可以设置 panel 的 Edge=”Left|Right|Top|Bottom”, 并注意相应的高宽值。
- 它的第二个Panel子元素为正常页面, 通这个页面的交互, 调出第一个Panel作为菜单,或者设置 HitTestMode 属性
- 看上去 EdgeNavigator 类似于 Page 一样是一个已经定义好的东西, 因此不需要指定 EnteringAnimation 监听ActivatingAnimation 事件就行了
- EdgeNavigation:虽然大多数时候 EdgeNavigator(推荐使用)就能工作得很好, 但如果想要自定义一些导航动画,或更多的自定义
- EdgeNavigator/EdgeNavigation 元素里边没有 ExitingAnimation, 因此 WhileInExitState 也没有
<App Theme="Basic"> <Panel> <EdgeNavigation ux:Name="Nav" /> <Panel ux:Name="menu" Width="150" Background="#0F0" Edge="Left" Alignment="Left"> <EnteringAnimation> <Move X="-1" RelativeTo="Size" /> </EnteringAnimation> <ActivatingAnimation> <Change main.X="150" /> </ActivatingAnimation> </Panel> <Panel Background="#F00"> <Translation ux:Name="main" /> <Text Value="Hello World" Alignment="Center" TextColor="#fff" /> <Clicked> <NavigateToggle Target="menu" /> </Clicked> </Panel> </Panel> </App>
Controlling navigation
控制导航,通过设置 NavigationContext 属性来指定指定
- GoBack
- GoForward
- WhileCanGoForward 当可以 GoForward 时
- NavigateTo 导航到指定页面
- EnteringAnimation: 定义如何切换页面, 元素内应该包含 enter 触发后动画应该到达的值(依赖于 Navigation Type)
- ExitingAnimation: 定义如何切换页面, 元素内应该包含 exit 触发后动画应该到达的值
- ActivatingAnimation 当激活页面时的动画,即在 enter或exit 动画执行前就触发
- WhileActive/WhileInactive 当页面为活动状态时(即动画完成后)/当页面处于非活动状态时(即使初使化也会根据页面的状态而触发)
- Threshold=”0~1.0” 这个值是当与动画的进度匹配时即激活(因此默认为 1, 当设为 0.5时动画运行到一半时即触发)
- WhileInEnterState: 与 WhileActive 类似, 当 EnteringAnimation 完成后
-
WhileInExitState: 与 WhileInactive 类似,当 ExitingAnimation 完成后
容易混乱的地方: 对于 LinearNavigation 来说, 第一个页面不会有 ExitingAnimation 和 WhileInExitState, 而最后一个页面则不会有 EnteringAnimation 和 WhileInEnterState, 通常把页面拖到左边为 enter, 而从右边退出为 exit
enter/exit-Animation 与页面的”活动与非活动”是没有关系的. 它的依赖于不同的 Navigation Type.
-
WhileNavigating: 和页面是同层元素,当二个页面切换时立即触发, 而不是等到动画结束。
- SwipeNavigate: 用于将手势与导航相关联,EdgeNavigator在内部即使用了这个.
- SwipeDirection=”Down|Right|Left|Up” 指定方向
- SwipeEnds=”Closed(默认)|Open|Short” 即用户往一个方向拉完所有页面后, 还可以拖动的空白, 如果想要这种效果选 Short 就好(如果有个事件就好了, 这样可以知道已经拉到页面底部或顶部了,然后执行 Ajax 操作)
- VelocityThreshold 设定手势的速率最小值即可切换
Physics
- Draggable 包含它的元素将可以移动
- WhileDragging 与 Draggable 为同层元素, 当拖动时
- PointAttractor 力场器, 像是磁铁一样的东西, 比如你要拖动元素丢到某一处时,或实现拖动删除时
- Radius 范围
- Strength 强度, 更的的值将把范围内的吸过来(如果多个PointAttractor)
- Offset=”X,Y,?” float3, 位置相对于其容器(父元素)
- Exclusive=”true|false” 除排
Force field triggers
定义一个元素是否受到力场的作用, 这个需要下载并参考示例, 将下边这些元素添加到需要被力场作用的Panel元素下
- 公共属性
- ForceField=”PointAttractor_NAME”: 激活力场
- EnteredForceField 进入力场范围
- Threshold=”0.0~1.0”: 在哪个点触发 handler
- Handler=”{js_handler}”:
- ExitedForceField
- InForceFieldAnimation
LayoutAnimation and MultiLayoutPanel
当一个元素的布局属性如 Width,Hight或Margin(参阅layout properties)发生变化或元素位置在显示列表的位置发生变化时,LayoutAnimation 将会被触发。
当使用 Change 来更改布局属性时, 计算大的 UX 文件布局是非常耗时的, 这很容易导致明显的帧数下降.
因此 Fuse 提供了 LayoutAnimation 来代替使用 Change 的动画. 可以使用 Set 来代替 Change
<Panel>
<Panel ux:Name="panel" Width="50" Height="50" Background="Teal">
<LayoutAnimation>
<Resize X="1" Y="1" RelativeTo="LayoutChange" Duration="0.5"/>
<Move X="1" Y="1" RelativeTo="LayoutChange" Duration="0.5"/>
</LayoutAnimation>
<Clicked>
<Set panel.Width="200"/>
<Set panel.Height="300"/>
</Clicked>
</Panel>
</Panel>
<!-- 另一个示例 -->
<Panel>
<Panel ux:Name="panel" Width="50" Height="50" Background="Teal" Alignment="Center">
<LayoutAnimation>
<Move X="1" Y="1" RelativeTo="LayoutChange" Duration="0.5"/>
</LayoutAnimation>
<Clicked>
<Set panel.Alignment="BottomRight"/>
</Clicked>
</Panel>
</Panel>
MultiLayoutPanel 允许在不同的布局之间移动元素. 这将允许在不同的显示列表之间移动元素,
- Placeholder: 用于在可视树(显示列表)中引用其它元素,它本身就是一个元素并且有它自已的布局属性
。。。。。。
misc
–empty–