Fuse手册之之形状绘制与触发及动画(2)

衣咸:受够了有道笔记的各种奇葩BUG和问题,现移步简书,文集属于译文+自己的心得+官方代码的验证与修正,翻译不当之处欢迎在评论中提出,一起来交流、进步。

变形Transforms

All elements can have transforms applied to them in order to move, scale or rotate. It is worth mentioning that the order of these transforms affects the order of when they are applied to the element, and therefore can lead to different results.

<Panel Width="100" Height="50">
    <Translation X="100"/>
    <Rotation Degrees="45"/>
</Panel>
<Panel Width="100" Height="50">
    <Rotation Degrees="45"/>
    <Translation X="100"/>
</Panel>

The two examples have quite different results. In the first case, the panel is first moved 100 points to the right and then rotated 45 degrees. In the other case, the panel is first rotated 45 degrees. The positive X direction is now 45 degrees downward, and so our panel ends up being moved toward the bottom right.

平移Translation

Translation moves the element in the specified X, Y, and Z direction. The following example shows a Rectangle which is moved 100 points in the X-direction and 50 points in the Y-direction.

<Rectangle Width="50" Height="50">
    <Translation X="100" Y="50"/>
</Rectangle>

You can set the translation value for Translation with:

  • X or Y, to separately set the X and Y translations
  • XY, to set the translation of both axes at once
  • Z, to set the translation in the Z axis.

The coordinates default to being relative to the elements original position(TranslationModes.Local), but this can be changed using the property RelativeTo. Further, you can make the transform relative to another element by using RelativeNode.

缩放Scaling

Scaling enlarges or shrinks the element by the factor specified. The following example will make the Rectangle twice as big as the original size:

<Rectangle Width="100" Height="100">
    <Scaling Factor="2"/>
</Rectangle>

Scaling can be utilized using:

  • Factor, to set an universal scale on all axes
  • Vector, to set the scale of all three axes at once
  • X,Y, and Z, for control of individual axes.

旋转Rotation

Rotation rotates the element by the degrees specified. Here is an example of a rectangle which is rotated by 90 degrees.
<Rectangle Width="100" Height="50">
<Rotation Degrees="90"/>
</Rectangle>

你可以使用以下命令来转动一个元素:

  • Degrees, controlling rotation around the Z axis
  • DegreesX, DegreesY, DegreesZ, giving you individual control of all 3 axes.
  • EulerAngle and EulerAngleDegrees, letting you set the Euler angles of the element in radians or degrees, respectively.

剪裁Shear

Shear动画能被用来在一个元素中执行裁剪贴图,能使用DegreesXDegreesY 来设定在一根轴上裁剪, 也可以用 DegreesVector 来设定基于X和Y面板来裁剪,使用的是角度或弧度。

动作Actions

�触发器也能够包含动作在里边,这些事件是一次性的发生在触发器的时间轴的特定的点上。注意,那些违反了动画的动作是不可逆转的。意思是说,如果触发撤消,必定没有可能返回静止状态。
animators it is not necessarily possible to return to the rest stateif the trigger is reversed.
像动画一样,动作Actions能拥有延迟属性Delay,这个触发器的数字秒数的设定在动作执行后被激活。不过,不像是动画Animators,他们也有一个被称为AtProgress的属性,能被设置在0-1的数值。它有一个类似Delay功能的函数,但是用来替换涉及触发Trigger的整个持续时长Duration 。设定AtProgress到0的意思是触发器一激活就执行动作,设定为0.5的意思是到一半的时候执行,以此类推。

AtProgress

动作Actions 也有一个属性叫做AtProgress,能设定基于0-1之间的值,他有一个近似的功能函数——延迟标签Delay
但是用来代替涉及到触发Trigger的整个持续时长Duration 。设定AtProgress为0的意思是触发器一激活就执行动作,设定为0.5的意思是到一半的时候执行,以此类推。

DebugAction

当被激活的时候,DebugAction让你打印输出一个消息到监视器工具视图Monitor/terminal,他相当于在Uno or JavaScript中调用debug_log函数。

<Button>
    <Clicked>
        <DebugAction Message="Clicked!" />
    </Clicked>
</Button>

Set

Set永久地改变一个属性的值�,如果你仅仅是想要临时地改变的话就用Change。在一个属性中使用Set的时候,当触发失效的时候这个值不会回到之前的设定。
在下面的这个例子中,我们使用这个标签设定SolidColor的值,改变了正方形的颜色,但如果同时多个点击触发时不会有任何叠加的效果。Multiple activations of the Clicked trigger won't have any additional effect.

<Rectangle ux:Name="rect" Color="#00f" />
<Clicked>
    <Set rect.Color="#f00"/>
</Clicked>

Set也可以使用TargetValue属性调用,下例的两行实现的是同样的效果:

<Set Target="rect.Color" Value="#f00" />
<Set rect.Color="#f00" />

回调函数Callback

当一个触发器被触发或激活时,Callback动作用来调用一个JavaScript函数(�具体参看数据梆定Data Binding章节) 。

<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

Tells a navigation context or a WebView to step forward in its navigation history.

<GoForward TargetNode="myNavigation" />
<GoForward TargetNode="myWebView" />

For more information about GoForward
in the context of navigation, see Controlling navigation.

后退GoBack

Tells a navigation context or a WebView to step backward in its navigation history.

<GoBack TargetNode="myNavigation" />
<GoBack TargetNode="myWebView" />

For more information about GoBack
in the context of navigation, see Controlling navigation.

�触发开关Toggle

Toggle 用来触发一个true或false的布尔值,如果内含一个Switch 标签,他将改变Switch的值来开关。触发开关Toggle同样能被用于激活或失效activate/deactiveWhileTrueWhileFalse触发器,如下例:

<WhileTrue ux:Name="trueTrigger">
    ...
</WhileTrue>
<Panel>
    <Clicked>
        <Toggle Target="trueTrigger"/>
    </Clicked>
</Panel>

脉动Pulse

Pulse 用来�随时地触发一个WhileTrue, WhileFalseTimeline

<Button Text="Pulse">
    <WhileTrue ux:Name="pulseMe" Value="false">
        <Scale Factor="1.5" Duration="0.2" />
    </WhileTrue>

    <Clicked>
        <Pulse Target="pulseMe" />
    </Clicked>
</Button>

带入视图BringIntoView

BringIntoView动作常和ScrollView控制标签一起使用,通过设定他的TargetNode属性,我们可以构建ScrollView到一个指定位置,以便对应的节点Node变得可见。
这个示例展示了怎样使用BringIntoView来构建一个ScrollView,通过一个按钮的点击,自动地在顶部和底部之间滚动。

<App Theme="Basic">
    <DockPanel>
        <StatusBarBackground DockPanel.Dock="Top" />
        <ScrollView ClipToBounds="true">
            <StackPanel>
                <Panel ux:Name="panel1" Height="80" Background="#F44336" />
                <Panel Height="200" Background="#ddd"/>
                <Panel Height="200" Background="Yellow"/>
                <Panel Height="200" Background="#999"/>
                <Panel Height="200" Background="Green"/>
                <Panel Height="200" Background="#444"/>
                <Panel ux:Name="panel2" Height="80" Background="#3949AB" />
            </StackPanel>
        </ScrollView>
        
        <StackPanel Dock="Bottom" Height="60" Orientation="Horizontal" Alignment="Center">
            <Button Text="To the top" >
                <Clicked>
                    <BringIntoView TargetNode="panel1" />
                </Clicked>
            </Button>
            <Button Text="To the bottom" >
                <Clicked>
                    <BringIntoView TargetNode="panel2" />
                </Clicked>
            </Button>
        </StackPanel>
    </DockPanel>
</App>

衣咸注:上例经过测试,App标签中如果不加入Theme="Basic"属性的话按钮就显示不出来。

带入到最前BringToFront

UX通常是这样组织的,在文档中,元素被定义为最高级别被绘制在视图的最顶端。这种机制是模仿一些流行的制图软件,类似Photoshop的图层表现形式。使用BringToFront可以,可以通过Target属性,把元素从他的同级图层中带到最前面,
注意:BringToFront 仅仅使得元素能在他的父级节点中处于最前面,但在不是进入时的UX树中.

<DockPanel>
    <Panel Background="#F00" />
    <Panel ux:Name="bluePanel" Background="#00F" />
    <Button Text="Blue to front!" Dock="Bottom">
        <Clicked>
            <BringToFront Target="bluePanel" />
        </Clicked>
    </Button>
</DockPanel>

转变布局TransitionLayout

TransitionLayout动作让你建立一个临时的图层变更,这能被用于在无需�真实布局改变的情况下做视图布局变更。
对他自身来说,没有很明显的影响,然后需要和图层动画LayoutAnimation来结合使用。图层动画LayoutAnimation将轮流被这个动作触发。

<DockPanel>
    <Panel Dock="Top" Height="20" ux:Name="originElement" />

    <Button Height="100" Dock="Bottom" Text="Transition!">
        <LayoutAnimation>
            <Move X="1" Y="1" RelativeTo="WorldPositionChange" Duration="1" />
            <Resize X="1" Y="1" RelativeTo="SizeChange" Duration="1" />
        </LayoutAnimation>
        <Clicked>
            <TransitionLayout From="originElement" />
        </Clicked>
    </Button>
</DockPanel>

When clicked, the Button in this example will perform a transition over 1 second from the position and size of originElement
(top edge of the DockPanel) to its actual position and size (bottom edge of theDockPanel).

导航触发NavigateToggle

触发一个导航Navigation,当前仅仅支持在 EdgeNavigation导航中使用,如果被用在其它类别的导航上的话将不会有任何动作发生。
当用到一个侧边导航上时EdgeNavigation,它将从一个Panel引导到Panel, 使用EdgeNavigation.Edge设置,并通过目标Target属性来指定。

手势Gestures

下面是触发器,用来响应手势的动作。

单击Clicked

Clicked 被激活用来响应一个单击手势, 这构成了一个单击事件event, 但是常常意味着点击器被压下和释放在容器元素之内(或者理解为在元素上)。

<Panel Width="50" Height="50">
    <Clicked>
        <Scale Factor="2" Duration="0.2"/>
    </Clicked>
</Panel>

长按Tapped

Tapped�触发其实很类似于前面的单击Clicked�,只不过�单击是点一下就放开,�而一个触摸意味着点击后需要在一个特定的时间里释放。

双击DoubleClicked

当元素在一个特定的时间段被单击Clicked了两次时DoubleClicked被激活。

双长按DoubleTapped

跟双击DoubleClicked一样,DoubleTapped is activated when the element has been Tapped twice within a certain timeframe.

按压WhilePressed

WhilePressed所包含元素被压住而且光标或触点位于这个范围之内时WhilePressed处于活跃状态。

<Panel Width="50" Height="50">
    <WhilePressed>
        <Scale Factor="2" Duration="0.2"/>
    </WhilePressed>
</Panel>

悬停WhileHovering

当触点或者光标当前位于他包含的元素的范围之内的时候WhileHovering是活跃的。
注意:WhileHovering 仅仅当设备支持悬停光标的时候有值,像是桌面环境的鼠标光标等,对大多数流行的移动设备来说这个触发器不会有多少重要性的。

滑动手势Swipe gestures

当我们想要一个元素处理滑动手势的时候,我们可以使用滑动手势SwipeGesture来表现。

<Panel>
    <SwipeGesture Direction="Right" Length="100" Type="Active" />
</Panel>

上边这个例子的解释如下:

  • Direction="Right" 指定此滑动手势响应向右滑动swipe-to-the-right;
  • Length="100" 意思是这个滑动有一个长度, 100 points 在设定指定方向的时候 Direction
  • Type="Active" 表明这应该是一个双向滑动手势,触发基于inactive/active的状态。

滑动手势SwipeGesture能够接收的属性如下:

  • A:Direction“方向指示”指定滑动的方向,可能的值为Left, Up, Right and Down;
  • B:Edge 能够被用来代替Direction,指定一个能被滑动到的元素的边缘,可能的值为Left, Top, Right and Bottom;
  • C:HitSize 仅仅当Edge被使用的时候才可用,然后指定有多远的距离从我们可以开始滑动的边缘起;
  • D:Length 指定, 编辑的起点,在指定的指示Direction之内我们可以滑动多远的距离;
  • E:LengthNode 能被用来代替Length,它引用那些应该被测量过的其它元素,来判断滑动时的长度;
  • F:Type
  1. a:Active 指示滑动时应该在inactive/active这两状态之间被触发,意思是如果有触发器,先触发到另一种状态,再通过触发回到初始状态;
  2. b:Simple 指示滑动应该调用一个单个、瞬间的动作,相对于上面的指令,这里如果被触发会进入一种状态,可以按你的要求生成动画,但会在执行后自动返回。

滑动手势SwipeGesture行为是没有他自身的效果的,我们需要应用我们自己的触发器和动画来响应这个手势。在下边的小节中我们将会过一下我们可以用来响应滑动手势SwipeGestures的各种不同的触发器和动作。

注意:自从可以在同一个元素上面来附加多重滑动手势后,而相关联的触发器(用来触发动画)需要知道哪一个才手势才是他应该响应的。我们此前需要给那些所有滑动涉及到的触发器来设置“源”Source属性,就是说将要响应滑动手势的触发器。

滑动动画SwipingAnimation
SwipingAnimation——这便是我们上文提及的触发器之一,执行动画在响应一个元素被滑动后。多数普通的使用情况是用来随同按点(或者称光标)一起移动元素。

<Panel Width="100" Height="100" Background="#000">
    <SwipeGesture ux:Name="swipe" Direction="Right" Length="200" />
    <SwipingAnimation Source="swipe">
        <Move X="200" />
    </SwipingAnimation>
</Panel>

替代给滑动使用一个固定的长度,我们也要从另一个元素的尺寸来判断他。这就完成了使用SwipeGesture的LengthNode属性,此外,还有在这种情况下MoveRelativeNode属性也同样如是。

<Panel ux:Name="parentContainer" Margin="40">
    <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
Swiped标签是一个脉冲触发器,当一个滑动swipe发生以后被呼叫调用的。

<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>

默认状态,Swiped已滑动标签将仅仅只有当滑动触发最主要的滑动指示时(当他进入活跃状态时)被触发。
例如,如果滑动手势SwipeGesture 有设置Direction="Left"的话,他仅仅被触发在一个向左滑动手势时,还会忽略相匹配的关闭滑动closing swipe。 我们能控制这种表现通过设置属性为ToActive (default),ToInactive or ToEither

当滑动激活WhileSwipeActive
WhileSwipeActive 是活跃的状态,每当一个滑动手势SwipeGesture是活跃状态时(当用户已经滑动他到“打开”Open的状时)。

<Panel Width="100" Height="100" Color="#000">
    <SwipeGesture ux:Name="swipe" Direction="Up" Length="50" Type="Simple" />
    <WhileSwipeActive Source="swipe">
        <Scale Factor="1.5" Duration="0.4" DurationBack="0.2" />
    </WhileSwipeActive>
</Panel>

上面的例子执行的是当手势在元素Panel上向手滑动的时候,此Panel自动放大。

**触发滑动激活ToggleSwipeActive和设置滑动激活SetSwipeActive **
SwipeGestures有type这个属性,我们可以用来控制活跃类型Active type。使用ToggleSwipeActive 动作可以触发滑动活跃状态,通过点击的方式来直接操作滑动手势所产生的动作,而无须滑动;
但是SetSwipeActive则是通点击等触发直接来设置目标滑动手势的值。如果其Value="false",则�单击会无效,而如果Value="true",则会开始单向一个单向动作,不会返回原来的静止状态 。

<Page>
<!--定义图层的手势区开始-->
<Panel Width="100" Height="100" Background="#f00">
    <!--SwipeGesture自身只有手势没有动画,是否是双状态的双向动画在此通过Type来控制-->
<SwipeGesture ux:Name="swipe2" Direction="Up" Length="100" Type="Active" />
    <!--这里下面才是真正动画产生的地方-->
    <SwipingAnimation Source="swipe2">
        <!--在相对点沿Y轴移动200--><Move Y="200" />
    </SwipingAnimation>
    <!--真正动画产生的地方结束-->
</Panel>
<!--定义图层的手势区结束-->

<StackPanel>
 <!--而貌似下方的只是控制器模块-->
    <Button Text="Close">
        <!--这里看不到任何效果-->
        <Clicked>
            <!--下方如果属性为True的话会变为可进行单向控制-->
            <SetSwipeActive Target="swipe2" Value="false" />
        </Clicked>
    </Button>
<!--下面可以看到触发效果-->
    <Button Text="Toggle">
        <Clicked>
            <ToggleSwipeActive Target="swipe2" />
        </Clicked>
    </Button>
</StackPanel>

</Page>

如果我们想要跳过动画,SetSwipeActive 也可以做到这些,只要我们设定Bypass="true"

数据触发器Data triggers

这些触发器响应数据的改变,或者是来自梆定的数据data binding 或者是来自于控制时的上下文环境。

当为真时WhileTrue

WhileTrue的值Value属性property为真True时,WhileTrue就处于活跃状态,当为False时进入不活跃状态。

当为假时WhileFalse

WhileFalse 的值Value属性property为否False时,WhileFalse 处于活跃状态,当为真True时进入不活跃状态。

本地触发器Native triggers

待续……
.

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

推荐阅读更多精彩内容

  • 衣咸:受够了有道笔记的各种奇葩BUG和问题,现移步简书,文集属于译文+自己的心得+官方代码的验证与修正,翻译不当之...
    衣咸阅读 489评论 0 0
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,945评论 4 60
  • 4月3日下午我找到了一家画室,开始了我的第一次正式的绘画学习。 我告诉老师我想先学速写,老师让我临摹一张风景画,上...
    尹莉莎阅读 1,217评论 4 3
  • 梦见弯月和圆月同时在夜空里,而后圆月变为太阳,我抬头看,日光太耀眼,晃得眼睛睁不开。再看时已经不见了。 又梦见家里...
    甘银钦阅读 283评论 0 4
  • 在迎来了非常快乐的暑假时,我的心简直像挂在悬崖的一颗美丽的心,高兴夹心紧张,绝配。 ...
    自由_0804阅读 362评论 5 2