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–