mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
Add animations demo to the gallery app, make vertical alignment center and visibility collapsed backward compatible
This commit is contained in:
BIN
apps/app/gallery-app/animations/bkg.png
Normal file
BIN
apps/app/gallery-app/animations/bkg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 311 B |
175
apps/app/gallery-app/animations/configurable.ts
Normal file
175
apps/app/gallery-app/animations/configurable.ts
Normal file
@@ -0,0 +1,175 @@
|
||||
import * as observable from "data/observable";
|
||||
import * as pages from "ui/page";
|
||||
import * as buttonModule from "ui/button";
|
||||
import * as abs from "ui/layouts/absolute-layout";
|
||||
import * as animationModule from "ui/animation";
|
||||
import * as colorModule from "color";
|
||||
import * as model from "./model";
|
||||
import * as enums from "ui/enums";
|
||||
import * as frame from "ui/frame";
|
||||
import * as trace from "trace";
|
||||
|
||||
var vm = new model.ViewModel();
|
||||
|
||||
var page: pages.Page;
|
||||
var panel: abs.AbsoluteLayout;
|
||||
var button1: buttonModule.Button;
|
||||
var button2: buttonModule.Button;
|
||||
var button3: buttonModule.Button;
|
||||
var buttonAnimation: animationModule.Animation;
|
||||
var panelAnimation: animationModule.Animation;
|
||||
|
||||
export function pageLoaded(args: observable.EventData) {
|
||||
page = <pages.Page>args.object;
|
||||
page.bindingContext = vm;
|
||||
panel = page.getViewById<abs.AbsoluteLayout>("panel1");
|
||||
button1 = page.getViewById<buttonModule.Button>("button1");
|
||||
button2 = page.getViewById<buttonModule.Button>("button2");
|
||||
button3 = page.getViewById<buttonModule.Button>("button3");
|
||||
|
||||
|
||||
trace.enable();
|
||||
trace.addCategories(trace.categories.concat(trace.categories.Animation));
|
||||
}
|
||||
|
||||
export function onSlideOut(args: observable.EventData) {
|
||||
console.log("onSlideOut");
|
||||
var curve = enums.AnimationCurve.easeOut;
|
||||
|
||||
var buttonAnimations = [
|
||||
{ target: button1, translate: { x: -240, y: 0 }, scale: { x: 0.5, y: 0.5 }, opacity: 0, duration: vm.duration, delay: 0, iterations: vm.iterations, curve: curve },
|
||||
{ target: button2, translate: { x: -240, y: 0 }, scale: { x: 0.5, y: 0.5 }, opacity: 0, duration: vm.duration, delay: vm.duration, iterations: vm.iterations, curve: curve },
|
||||
{ target: button3, translate: { x: -240, y: 0 }, scale: { x: 0.5, y: 0.5 }, opacity: 0, duration: vm.duration, delay: vm.duration * 2, iterations: vm.iterations, curve: curve },
|
||||
]
|
||||
buttonAnimation = new animationModule.Animation(buttonAnimations, vm.playSequentially);
|
||||
|
||||
panelAnimation = panel.createAnimation({ opacity: 0, scale: { x: 0.5, y: 0.5 }, rotate: -360, backgroundColor: new colorModule.Color("red"), duration: vm.duration, iterations: vm.iterations, curve: enums.AnimationCurve.easeInOut });
|
||||
|
||||
buttonAnimation.play()
|
||||
.then(() => panelAnimation.play())
|
||||
.catch((e) => console.log(e.message));
|
||||
}
|
||||
|
||||
export function onSlideIn(args: observable.EventData) {
|
||||
console.log("onSlideIn");
|
||||
var curve = enums.AnimationCurve.easeIn;
|
||||
|
||||
panelAnimation = panel.createAnimation({ opacity: 1, scale: { x: 1, y: 1 }, rotate: 0, backgroundColor: new colorModule.Color("yellow"), duration: vm.duration, iterations: vm.iterations, curve: enums.AnimationCurve.easeInOut });
|
||||
|
||||
var buttonAnimations = [
|
||||
{ target: button3, translate: { x: 0, y: 0 }, scale: { x: 1, y: 1 }, opacity: 1, duration: vm.duration, delay: 0, iterations: vm.iterations, curve: curve },
|
||||
{ target: button2, translate: { x: 0, y: 0 }, scale: { x: 1, y: 1 }, opacity: 1, duration: vm.duration, delay: vm.duration, iterations: vm.iterations, curve: curve },
|
||||
{ target: button1, translate: { x: 0, y: 0 }, scale: { x: 1, y: 1 }, opacity: 1, duration: vm.duration, delay: vm.duration * 2, iterations: vm.iterations, curve: curve },
|
||||
]
|
||||
buttonAnimation = new animationModule.Animation(buttonAnimations, vm.playSequentially);
|
||||
|
||||
panelAnimation.play()
|
||||
.then(() => buttonAnimation.play())
|
||||
.catch((e) => console.log(e.message));
|
||||
}
|
||||
|
||||
export function onCancel(args: observable.EventData) {
|
||||
console.log("onCancel");
|
||||
if (panelAnimation && panelAnimation.isPlaying) {
|
||||
panelAnimation.cancel();
|
||||
}
|
||||
if (buttonAnimation && buttonAnimation.isPlaying) {
|
||||
buttonAnimation.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
export function onTap(args: observable.EventData) {
|
||||
console.log((<any>args.object).text);
|
||||
}
|
||||
|
||||
export function onSingle(args: observable.EventData) {
|
||||
console.log("onSingle");
|
||||
button1.animate({
|
||||
opacity: 0.75,
|
||||
backgroundColor: new colorModule.Color("Red"),
|
||||
translate: { x: 100, y: 100 },
|
||||
scale: { x: 2, y: 2 },
|
||||
rotate: 180,
|
||||
duration: vm.duration,
|
||||
delay: 0,
|
||||
iterations: vm.iterations,
|
||||
curve: enums.AnimationCurve.linear,
|
||||
})
|
||||
.then(() => console.log("Animation finished"))
|
||||
.catch((e) => console.log(e.message));
|
||||
}
|
||||
|
||||
export function onSequence(args: observable.EventData) {
|
||||
console.log("onSequence");
|
||||
|
||||
button3.animate({
|
||||
translate: { x: 80, y: -40 },
|
||||
scale: { x: 0.9, y: 0.3 },
|
||||
rotate: 25,
|
||||
duration: 1000
|
||||
})
|
||||
.then(() => button3.animate({
|
||||
translate: { x: 0, y: -80 },
|
||||
scale: { x: 0.5, y: 0.5 },
|
||||
rotate: -25,
|
||||
duration: 1000
|
||||
}))
|
||||
.then(() => button3.animate({
|
||||
translate: { x: -80, y: -40 },
|
||||
scale: { x: 0.5, y: 0.9 },
|
||||
rotate: 45,
|
||||
duration: 1000
|
||||
}))
|
||||
.then(() => button3.animate({
|
||||
translate: { x: 0, y: 0 },
|
||||
scale: { x: 1, y: 1 },
|
||||
rotate: 0,
|
||||
duration: 1000
|
||||
}))
|
||||
.then(() => console.log("Animation finished"))
|
||||
.catch((e) => console.log(e.message));
|
||||
}
|
||||
|
||||
export function onInterrupted(args: observable.EventData) {
|
||||
console.log("onInterrupt");
|
||||
|
||||
setTimeout(() => {
|
||||
button3.animate({
|
||||
translate: { x: 80, y: -40 },
|
||||
scale: { x: 0.9, y: 0.3 },
|
||||
rotate: 25,
|
||||
duration: 1000
|
||||
});
|
||||
}, 700 * 0);
|
||||
|
||||
setTimeout(function() {
|
||||
button3.animate({
|
||||
translate: { x: 0, y: -80 },
|
||||
scale: { x: 0.5, y: 0.5 },
|
||||
rotate: -25,
|
||||
duration: 1000
|
||||
})
|
||||
}, 700 * 1);
|
||||
|
||||
setTimeout(function() {
|
||||
button3.animate({
|
||||
translate: { x: -80, y: -40 },
|
||||
scale: { x: 0.5, y: 0.9 },
|
||||
rotate: 45,
|
||||
duration: 1000
|
||||
})
|
||||
}, 700 * 2);
|
||||
|
||||
setTimeout(function() {
|
||||
button3.animate({
|
||||
translate: { x: 0, y: 0 },
|
||||
scale: { x: 1, y: 1 },
|
||||
rotate: 0,
|
||||
duration: 1000
|
||||
})
|
||||
}, 700 * 3);
|
||||
}
|
||||
|
||||
export function onOpacity(args: observable.EventData) {
|
||||
frame.topmost().navigate("./opacity");
|
||||
}
|
||||
36
apps/app/gallery-app/animations/configurable.xml
Normal file
36
apps/app/gallery-app/animations/configurable.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="pageLoaded" id="mainPage">
|
||||
<StackLayout orientation="vertical">
|
||||
<StackLayout orientation="vertical" backgroundColor="LightGray" paddingTop="5" paddingBottom="5">
|
||||
|
||||
<Label text="{{ duration, 'Duration: ' + duration + ' ms' }}" width="180" />
|
||||
<Slider minValue="0" maxValue="10000" value="{{ duration }}" margin="0 15" />
|
||||
|
||||
<Label text="{{ iterations, 'Iterations: ' + iterations + ' times' }}" width="180" />
|
||||
<Slider minValue="0" maxValue="10" value="{{ iterations }}" margin="0 15" />
|
||||
|
||||
<StackLayout orientation="horizontal" horizontalAlignment="center">
|
||||
<Label text="Play Sequentially?"/>
|
||||
<Switch marginLeft="10" checked="{{ playSequentially }}"/>
|
||||
</StackLayout>
|
||||
|
||||
<StackLayout orientation="horizontal" marginTop="5" marginBottom="5" horizontalAlignment="center" paddingLeft="5" paddingRight="5">
|
||||
<Button text="Out" tap="onSlideOut" width="40" marginLeft="5" marginRight="5" />
|
||||
<Button text="In" tap="onSlideIn" width="40" marginLeft="5" marginRight="5" />
|
||||
<Button text="Single" tap="onSingle" width="70" marginLeft="5" marginRight="5" />
|
||||
<Button text="Cancel" tap="onCancel" width="70" marginLeft="5" marginRight="5" />
|
||||
<Button text="Opacity" tap="onOpacity" width="70" marginLeft="5" marginRight="5" />
|
||||
</StackLayout>
|
||||
|
||||
<StackLayout orientation="horizontal" marginTop="5" marginBottom="5" horizontalAlignment="center" paddingLeft="5" paddingRight="5">>
|
||||
<Button text="Sequence" width="80" marginLeft="5" marginRight="5" tap="onSequence" />
|
||||
<Button text="Interrupted" width="80" marginLeft="5" marginRight="5" tap="onInterrupted" />
|
||||
</StackLayout>
|
||||
|
||||
</StackLayout>
|
||||
<AbsoluteLayout id="panel1" backgroundColor="Yellow" width="300" height="190" clipToBounds="true" marginTop="10">
|
||||
<Button id="button1" text="Button 1" backgroundColor="White" width="180" height="50" left="60" top="10" tap="onTap" borderWidth="1" borderColor="red" />
|
||||
<Button id="button2" text="Button 2" backgroundColor="White" width="180" height="50" left="60" top="70" tap="onTap" borderWidth="1" borderColor="red" />
|
||||
<Button id="button3" text="Button 3" backgroundColor="White" width="180" height="50" left="60" top="130" tap="onTap" borderWidth="1" borderColor="red" />
|
||||
</AbsoluteLayout>
|
||||
</StackLayout>
|
||||
</Page>
|
||||
37
apps/app/gallery-app/animations/model.ts
Normal file
37
apps/app/gallery-app/animations/model.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import observable = require("data/observable");
|
||||
|
||||
export class ViewModel extends observable.Observable {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this._duration = 3000;
|
||||
this._iterations = 1;
|
||||
}
|
||||
|
||||
private _playSequentially: boolean;
|
||||
get playSequentially(): boolean {
|
||||
return this._playSequentially;
|
||||
}
|
||||
set playSequentially(value: boolean) {
|
||||
this._playSequentially = value;
|
||||
this.notify({ object: this, eventName: observable.Observable.propertyChangeEvent, propertyName: "playSequentially", value: value });
|
||||
}
|
||||
|
||||
private _duration: number;
|
||||
get duration(): number {
|
||||
return this._duration;
|
||||
}
|
||||
set duration(value: number) {
|
||||
this._duration = value;
|
||||
this.notify({ object: this, eventName: observable.Observable.propertyChangeEvent, propertyName: "duration", value: value });
|
||||
}
|
||||
|
||||
private _iterations: number;
|
||||
get iterations(): number {
|
||||
return this._iterations;
|
||||
}
|
||||
set iterations(value: number) {
|
||||
this._iterations = value;
|
||||
this.notify({ object: this, eventName: observable.Observable.propertyChangeEvent, propertyName: "iterations", value: value });
|
||||
}
|
||||
}
|
||||
27
apps/app/gallery-app/animations/opacity.css
Normal file
27
apps/app/gallery-app/animations/opacity.css
Normal file
@@ -0,0 +1,27 @@
|
||||
.complex {
|
||||
width: 45;
|
||||
height: 45;
|
||||
margin: 1;
|
||||
background-image: url('~/gallery-app/animations/bkg.png');
|
||||
background-repeat:repeat-x;
|
||||
background-position: 20% 80%;
|
||||
background-color: lightyellow;
|
||||
background-size: 25% 50%;
|
||||
border-radius: 20;
|
||||
border-width: 4;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.simple {
|
||||
width: 45;
|
||||
height: 45;
|
||||
margin: 1;
|
||||
border-radius: 20;
|
||||
background-color: lightgreen;
|
||||
}
|
||||
|
||||
.none {
|
||||
width: 45;
|
||||
height: 45;
|
||||
margin: 1;
|
||||
}
|
||||
47
apps/app/gallery-app/animations/opacity.ts
Normal file
47
apps/app/gallery-app/animations/opacity.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import observable = require("data/observable");
|
||||
import pages = require("ui/page");
|
||||
import view = require("ui/core/view");
|
||||
import animationModule = require("ui/animation");
|
||||
import slider = require("ui/slider");
|
||||
import wrapLayout = require("ui/layouts/wrap-layout");
|
||||
|
||||
var page: pages.Page;
|
||||
var opacitySlider: slider.Slider;
|
||||
var container: wrapLayout.WrapLayout;
|
||||
|
||||
export function pageLoaded(args: observable.EventData) {
|
||||
page = <pages.Page>args.object;
|
||||
opacitySlider = page.getViewById<slider.Slider>("opacitySlider");
|
||||
container = page.getViewById<wrapLayout.WrapLayout>("container");
|
||||
}
|
||||
|
||||
export function onSetOpacity(args: observable.EventData) {
|
||||
var newOpacity = opacitySlider.value / 100;
|
||||
container.eachChildView((view: view.View) => {
|
||||
view.opacity = newOpacity;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
var animationSet: animationModule.Animation;
|
||||
export function onAnimateOpacity(args: observable.EventData) {
|
||||
var newOpacity = opacitySlider.value / 100;
|
||||
var animationDefinitions = new Array<animationModule.AnimationDefinition>();
|
||||
container.eachChildView((view: view.View) => {
|
||||
animationDefinitions.push({
|
||||
target: view,
|
||||
opacity: newOpacity,
|
||||
duration: 5000
|
||||
});
|
||||
return true;
|
||||
});
|
||||
|
||||
animationSet = new animationModule.Animation(animationDefinitions);
|
||||
animationSet.play();
|
||||
}
|
||||
|
||||
export function onReset(args: observable.EventData) {
|
||||
if (animationSet.isPlaying) {
|
||||
animationSet.cancel();
|
||||
}
|
||||
}
|
||||
35
apps/app/gallery-app/animations/opacity.xml
Normal file
35
apps/app/gallery-app/animations/opacity.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<Page xmlns="http://schemas.nativescript.org/tns.xsd" loaded="pageLoaded" id="opacityPage">
|
||||
<StackLayout orientation="vertical">
|
||||
<StackLayout orientation="vertical">
|
||||
<Label text="opacity" width="180" />
|
||||
<Slider id="opacitySlider" minValue="0" maxValue="100" width="180" />
|
||||
<Button text="Set" tap="onSetOpacity"/>
|
||||
<Button text="Animate" tap="onAnimateOpacity"/>
|
||||
<Button text="Reset" tap="onReset"/>
|
||||
</StackLayout>
|
||||
<WrapLayout orientation="horizontal" id="container">
|
||||
|
||||
<StackLayout class="complex"/>
|
||||
<Button text="Button" class="complex"/>
|
||||
<Label text="Label" class="complex"/>
|
||||
<Image src="~/test-icon.png" class="complex"/>
|
||||
<TextField text="TextField" class="complex"/>
|
||||
<TextView text="TextView" class="complex"/>
|
||||
|
||||
<StackLayout class="simple"/>
|
||||
<Button text="Button" class="simple"/>
|
||||
<Label text="Label" class="simple"/>
|
||||
<Image src="~/test-icon.png" class="simple"/>
|
||||
<TextField text="TextField" class="simple"/>
|
||||
<TextView text="TextView" class="simple"/>
|
||||
|
||||
<StackLayout class="none"/>
|
||||
<Button text="Button" class="none"/>
|
||||
<Label text="Label" class="none"/>
|
||||
<Image src="~/test-icon.png" class="none"/>
|
||||
<TextField text="TextField" class="none"/>
|
||||
<TextView text="TextView" class="none"/>
|
||||
|
||||
</WrapLayout>
|
||||
</StackLayout>
|
||||
</Page>
|
||||
2
apps/app/gallery-app/animations/package.json
Normal file
2
apps/app/gallery-app/animations/package.json
Normal file
@@ -0,0 +1,2 @@
|
||||
{ "name" : "animations",
|
||||
"main" : "app.js" }
|
||||
BIN
apps/app/gallery-app/animations/test-icon.png
Normal file
BIN
apps/app/gallery-app/animations/test-icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
@@ -40,6 +40,12 @@
|
||||
<Button tag="views/list-picker" text="ListPicker" tap="itemTap" />
|
||||
<Button tag="views/segmented-bar" text="SegmentedBar" tap="itemTap" />
|
||||
</StackLayout>
|
||||
|
||||
<Label class="title" text="Animations" />
|
||||
<StackLayout>
|
||||
<Button tag="animations/configurable" text="configurable" tap="itemTap" />
|
||||
<Button tag="animations/opacity" text="opacity" tap="itemTap" />
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</ScrollView>
|
||||
</Page>
|
||||
@@ -65,6 +65,13 @@ declare module "data/observable" {
|
||||
* Observable is used when you want to be notified when a change occurs. Use on/off methods to add/remove listener.
|
||||
*/
|
||||
class Observable {
|
||||
|
||||
/**
|
||||
* Please note that should you be using the `new Observable({})` constructor, it is **obsolete** since v3.0,
|
||||
* and you have to migrate to the "data/observable" `fromObject({})` or the `fromObjectRecursive({})` functions.
|
||||
*/
|
||||
constructor();
|
||||
|
||||
/**
|
||||
* String value used when hooking to propertyChange event.
|
||||
*/
|
||||
|
||||
@@ -1250,16 +1250,8 @@ export namespace VerticalAlignment {
|
||||
export const BOTTOM: "bottom" = "bottom";
|
||||
export const STRETCH: "stretch" = "stretch";
|
||||
export const isValid = makeValidator<VerticalAlignment>(TOP, MIDDLE, BOTTOM, STRETCH);
|
||||
export const parse = value => {
|
||||
const lower = value && value.toLowerCase();
|
||||
if (lower === "canter") {
|
||||
return MIDDLE;
|
||||
} else if (isValid(lower)) {
|
||||
return lower;
|
||||
} else {
|
||||
throw new Error("Invalid value: " + value);
|
||||
}
|
||||
}
|
||||
export const parse = (value: string) => value.toLowerCase() === "center" ? MIDDLE : parseStrict(value);
|
||||
const parseStrict = makeParser<VerticalAlignment>(isValid);
|
||||
}
|
||||
|
||||
export const verticalAlignmentProperty = new CssProperty<Style, VerticalAlignment>({ name: "verticalAlignment", cssName: "vertical-align", defaultValue: VerticalAlignment.STRETCH, affectsLayout: isIOS, valueConverter: VerticalAlignment.parse });
|
||||
@@ -2025,7 +2017,8 @@ export namespace Visibility {
|
||||
export const HIDDEN: "hidden" = "hidden";
|
||||
export const COLLAPSE: "collapse" = "collapse";
|
||||
export const isValid = makeValidator<Visibility>(VISIBLE, HIDDEN, COLLAPSE);
|
||||
export const parse = makeParser<Visibility>(isValid);
|
||||
export const parse = (value: string) => value.toLowerCase() === "collapsed" ? COLLAPSE : parseStrict(value);
|
||||
const parseStrict = makeParser<Visibility>(isValid);
|
||||
}
|
||||
|
||||
export const visibilityProperty = new CssProperty<Style, Visibility>({
|
||||
|
||||
Reference in New Issue
Block a user