mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
feat: glass effects containers
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Observable, EventData, Page, CoreTypes, GlassEffectConfig } from '@nativescript/core';
|
||||
import { Observable, EventData, Page, CoreTypes, GlassEffectConfig, View, GlassEffectType, TouchAnimationOptions, Label, Image } from '@nativescript/core';
|
||||
|
||||
let page: Page;
|
||||
|
||||
@@ -7,10 +7,154 @@ export function navigatingTo(args: EventData) {
|
||||
page.bindingContext = new GlassEffectModel();
|
||||
}
|
||||
|
||||
const originalTransform = Symbol('originalTransform');
|
||||
|
||||
export class GlassEffectModel extends Observable {
|
||||
iosGlassEffectInteractive: GlassEffectConfig = {
|
||||
interactive: true,
|
||||
tint: '#faabab',
|
||||
variant: 'clear',
|
||||
};
|
||||
currentEffect: GlassEffectConfig = {
|
||||
variant: 'none',
|
||||
interactive: false,
|
||||
// tint: '#ccc',
|
||||
};
|
||||
|
||||
toggleGlassEffect(args) {
|
||||
const btn = args.object as View;
|
||||
this.currentEffect =
|
||||
this.currentEffect.variant === 'none'
|
||||
? {
|
||||
variant: 'clear',
|
||||
interactive: true,
|
||||
// tint: '#faabab',
|
||||
}
|
||||
: {
|
||||
variant: 'none',
|
||||
interactive: false,
|
||||
// tint: '#ccc',
|
||||
};
|
||||
btn.iosGlassEffect = this.currentEffect;
|
||||
}
|
||||
|
||||
images = ['res://bg1.jpg', 'res://bg2.jpg', 'res://bg3.jpg'];
|
||||
currentImage = this.images[0];
|
||||
cycleImage() {
|
||||
if (!this.image) {
|
||||
return;
|
||||
}
|
||||
let currentIndex = this.images.indexOf(this.currentImage);
|
||||
currentIndex++;
|
||||
if (currentIndex === this.images.length) {
|
||||
currentIndex = 0;
|
||||
}
|
||||
this.currentImage = this.images[currentIndex];
|
||||
// this.notifyPropertyChange('currentImage', this.currentImage);
|
||||
this.image.animate({ opacity: 0, duration: 300, curve: CoreTypes.AnimationCurve.easeInOut }).then(() => {
|
||||
this.image.src = this.currentImage;
|
||||
setTimeout(() => {
|
||||
this.image.animate({ opacity: 1, duration: 800, curve: CoreTypes.AnimationCurve.easeInOut });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
image: Image;
|
||||
loadedImage(args) {
|
||||
this.image = args.object as Image;
|
||||
}
|
||||
|
||||
glassMerged = false;
|
||||
glassTargets = {};
|
||||
loadedGlass(args) {
|
||||
const glass = args.object as View;
|
||||
switch (glass.id) {
|
||||
case 'glass1':
|
||||
glass.translateX = -40;
|
||||
break;
|
||||
case 'glass2':
|
||||
glass.translateX = 40;
|
||||
|
||||
break;
|
||||
}
|
||||
this.glassTargets[glass.id] = glass;
|
||||
}
|
||||
|
||||
glassTargetLabels: { [key: string]: Label } = {};
|
||||
loadedGlassLabels(args) {
|
||||
const label = args.object as Label;
|
||||
this.glassTargetLabels[label.id] = label;
|
||||
}
|
||||
|
||||
toggleMergeGlass() {
|
||||
if (!this.glassTargets['glass1'] || !this.glassTargets['glass2']) {
|
||||
return;
|
||||
}
|
||||
this.glassMerged = !this.glassMerged;
|
||||
const glass1 = this.glassTargets['glass1'];
|
||||
const glass2 = this.glassTargets['glass2'];
|
||||
glass1.animate({ translate: { x: this.glassMerged ? -40 : 0, y: 0 }, duration: 300, curve: CoreTypes.AnimationCurve.easeInOut }).catch(() => {});
|
||||
glass2.animate({ translate: { x: this.glassMerged ? 40 : 0, y: 0 }, duration: 300, curve: CoreTypes.AnimationCurve.easeInOut }).catch(() => {});
|
||||
|
||||
this.glassTargetLabels['share'].animate({ opacity: this.glassMerged ? 1 : 0, duration: 300, curve: CoreTypes.AnimationCurve.easeInOut }).catch(() => {});
|
||||
|
||||
this.glassTargetLabels['like'].text = this.glassMerged ? 'Done' : 'Like';
|
||||
}
|
||||
|
||||
touchAnimation: TouchAnimationOptions = {
|
||||
down: (view: View) => {
|
||||
if (__APPLE__) {
|
||||
UIView.animateWithDurationDelayUsingSpringWithDampingInitialSpringVelocityOptionsAnimationsCompletion(
|
||||
0.3,
|
||||
0,
|
||||
0.5,
|
||||
3,
|
||||
UIViewAnimationOptions.CurveEaseInOut | UIViewAnimationOptions.AllowUserInteraction,
|
||||
() => {
|
||||
if (view?.ios) {
|
||||
view[originalTransform] = view[originalTransform] ?? view.ios.transform;
|
||||
|
||||
view.ios.transform = CGAffineTransformConcat(view[originalTransform], CGAffineTransformMakeScale(0.97, 0.97));
|
||||
}
|
||||
},
|
||||
null,
|
||||
);
|
||||
} else {
|
||||
view
|
||||
?.animate({
|
||||
scale: { x: 0.97, y: 0.97 },
|
||||
duration: 120,
|
||||
curve: CoreTypes.AnimationCurve.easeInOut,
|
||||
})
|
||||
.then(() => {})
|
||||
.catch(() => {});
|
||||
}
|
||||
},
|
||||
up: (view: View) => {
|
||||
if (__APPLE__) {
|
||||
UIView.animateWithDurationDelayUsingSpringWithDampingInitialSpringVelocityOptionsAnimationsCompletion(
|
||||
0.3,
|
||||
0,
|
||||
0.5,
|
||||
3,
|
||||
UIViewAnimationOptions.CurveEaseInOut | UIViewAnimationOptions.AllowUserInteraction,
|
||||
() => {
|
||||
if (view?.ios) {
|
||||
view.ios.transform = view[originalTransform] ?? CGAffineTransformMakeScale(1, 1);
|
||||
}
|
||||
},
|
||||
null,
|
||||
);
|
||||
} else {
|
||||
view
|
||||
?.animate({
|
||||
scale: { x: 1, y: 1 },
|
||||
duration: 120,
|
||||
curve: CoreTypes.AnimationCurve.easeInOut,
|
||||
})
|
||||
.then(() => {})
|
||||
.catch(() => {});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,27 +1,55 @@
|
||||
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page">
|
||||
<Page.actionBar>
|
||||
<ActionBar title="Glass Effects" class="action-bar">
|
||||
<ActionBar title="Glass Effects" color="white">
|
||||
</ActionBar>
|
||||
</Page.actionBar>
|
||||
|
||||
<GridLayout>
|
||||
|
||||
<Image src="https://cdn.wallpapersafari.com/89/64/c6MnRY.jpg" stretch="aspectFill" iosOverflowSafeArea="true" />
|
||||
|
||||
<GridLayout rows="*,auto,auto,auto,*">
|
||||
<GridLayout backgroundColor="#000">
|
||||
|
||||
<GridLayout row="1" width="300" height="150" iosGlassEffect="regular" horizontalAlignment="center" verticalAlignment="middle">
|
||||
<!-- <Image src="https://wallpapers.com/images/hd/yosemite-iphone-1440-x-2560-9t7u3ctc1hmq35p4.jpg" stretch="aspectFill" iosOverflowSafeArea="true" /> -->
|
||||
<Image src="res://bg1.jpg" stretch="aspectFill" iosOverflowSafeArea="true" loaded="{{loadedImage}}" />
|
||||
<!-- <ContentView backgroundColor="#000" height="300" verticalAlignment="bottom"/> -->
|
||||
|
||||
<ScrollView >
|
||||
<StackLayout>
|
||||
<GridLayout height="400" tap="{{cycleImage}}"/>
|
||||
<GridLayout rows="*,auto,auto,auto,auto,auto,*">
|
||||
|
||||
<Button row="2" text="Toggle Glass" tap="{{toggleGlassEffect}}" horizontalAlignment="center" verticalAlignment="middle" class="c-white font-weight-bold m-y-20 p-4" fontSize="22" borderRadius="32" width="300" height="100" touchAnimation="{{touchAnimation}}" iosGlassEffect="{{currentEffect}}"/>
|
||||
|
||||
<LiquidGlass row="3" width="300" height="100" borderRadius="32">
|
||||
<Label text="Glass Interactive" fontSize="22" class="p-4 font-weight-bold text-center" />
|
||||
</LiquidGlass>
|
||||
|
||||
<!--
|
||||
<LiquidGlassContainer row="4" tap="{{toggleMergeGlass}}" horizontalAlignment="center" verticalAlignment="middle" class="m-t-20" width="300" height="100">
|
||||
<LiquidGlass id="glass1" loaded="{{loadedGlass}}" borderRadius="50" width="100" height="100">
|
||||
<Label id="share" text="Share" fontSize="22" class="font-weight-bold text-center" width="100" height="100" loaded="{{loadedGlassLabels}}" />
|
||||
</LiquidGlass>
|
||||
<LiquidGlass id="glass2" loaded="{{loadedGlass}}" borderRadius="50" width="100" height="100">
|
||||
<Label id="like" text="Like" fontSize="22" class="font-weight-bold text-center" loaded="{{loadedGlassLabels}}" />
|
||||
</LiquidGlass>
|
||||
</LiquidGlassContainer> -->
|
||||
|
||||
|
||||
<!-- <GridLayout row="1" width="300" height="150" iosGlassEffect="regular" horizontalAlignment="center" verticalAlignment="middle">
|
||||
<Label class="text-center c-white" fontWeight="bold" fontSize="18" text="Glass Effects Regular" />
|
||||
</GridLayout>
|
||||
</GridLayout> -->
|
||||
|
||||
<GridLayout row="2" width="300" height="150" iosGlassEffect="clear" horizontalAlignment="center" verticalAlignment="middle" class="m-t-10">
|
||||
<!-- <GridLayout row="3" width="300" height="150" iosGlassEffect="clear" horizontalAlignment="center" verticalAlignment="middle" class="m-t-10" borderRadius="50">
|
||||
<Label class="text-center c-white" fontWeight="bold" fontSize="18" text="Glass Effects Clear" />
|
||||
</GridLayout>
|
||||
|
||||
<GridLayout row="3" width="300" height="150" iosGlassEffect="{{iosGlassEffectInteractive}}" horizontalAlignment="center" verticalAlignment="middle" class="m-t-10">
|
||||
<GridLayout row="4" width="300" height="150" iosGlassEffect="{{iosGlassEffectInteractive}}" horizontalAlignment="center" verticalAlignment="middle" class="m-t-10" borderRadius="50">
|
||||
<Label class="text-center c-white" fontWeight="bold" fontSize="18" text="Glass Effects Interactive" />
|
||||
</GridLayout>
|
||||
</GridLayout>
|
||||
</GridLayout> -->
|
||||
</GridLayout>
|
||||
|
||||
<GridLayout height="600"/>
|
||||
</StackLayout>
|
||||
|
||||
</ScrollView>
|
||||
</GridLayout>
|
||||
</Page>
|
||||
|
||||
Reference in New Issue
Block a user