2019-01-24 16:43:03 +08:00
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
2018-04-13 17:19:50 +08:00
2022-06-17 15:37:17 +08:00
#nullable disable
2016-10-07 16:07:23 +08:00
using System ;
2016-11-14 16:23:33 +08:00
using osu.Framework.Allocation ;
2017-02-07 20:45:59 +08:00
using osu.Framework.Audio ;
using osu.Framework.Audio.Sample ;
2017-05-24 00:17:09 +08:00
using osu.Framework.Audio.Track ;
2020-03-11 09:18:41 +08:00
using osu.Framework.Extensions.Color4Extensions ;
2016-10-07 16:07:23 +08:00
using osu.Framework.Graphics ;
using osu.Framework.Graphics.Containers ;
2017-06-20 13:54:23 +08:00
using osu.Framework.Graphics.Shapes ;
2016-10-07 16:07:23 +08:00
using osu.Framework.Graphics.Sprites ;
2016-11-14 16:23:33 +08:00
using osu.Framework.Graphics.Textures ;
2018-10-02 11:02:47 +08:00
using osu.Framework.Input.Events ;
2020-01-09 12:43:44 +08:00
using osu.Framework.Utils ;
2017-05-24 00:17:09 +08:00
using osu.Game.Beatmaps.ControlPoints ;
2016-12-01 19:21:14 +08:00
using osu.Game.Graphics.Backgrounds ;
2017-05-23 11:29:43 +08:00
using osu.Game.Graphics.Containers ;
2020-08-04 20:53:00 +08:00
using osu.Game.Overlays ;
2018-11-20 15:51:59 +08:00
using osuTK ;
using osuTK.Graphics ;
using osuTK.Input ;
2018-04-13 17:19:50 +08:00
2016-11-14 16:23:33 +08:00
namespace osu.Game.Screens.Menu
2016-10-07 16:07:23 +08:00
{
/// <summary>
/// osu! logo and its attachments (pulsing, visualiser etc.)
/// </summary>
2022-11-24 13:32:20 +08:00
public partial class OsuLogo : BeatSyncedContainer
2016-10-07 16:07:23 +08:00
{
2020-03-11 09:18:41 +08:00
public readonly Color4 OsuPink = Color4Extensions . FromHex ( @"e967a1" ) ;
2018-04-13 17:19:50 +08:00
2017-11-01 19:54:58 +08:00
private const double transition_length = 300 ;
2018-04-13 17:19:50 +08:00
2017-03-23 12:41:50 +08:00
private readonly Sprite logo ;
private readonly CircularContainer logoContainer ;
private readonly Container logoBounceContainer ;
2017-05-23 11:29:43 +08:00
private readonly Container logoBeatContainer ;
2017-05-24 00:45:01 +08:00
private readonly Container logoAmplitudeContainer ;
2017-03-23 12:41:50 +08:00
private readonly Container logoHoverContainer ;
2020-06-09 05:45:40 +08:00
private readonly MenuLogoVisualisation visualizer ;
2018-04-13 17:19:50 +08:00
2017-11-03 16:54:35 +08:00
private readonly IntroSequence intro ;
2018-04-13 17:19:50 +08:00
2021-01-19 16:11:40 +08:00
private Sample sampleClick ;
private Sample sampleBeat ;
2021-02-12 16:22:15 +08:00
private Sample sampleDownbeat ;
2018-04-13 17:19:50 +08:00
2017-03-23 12:41:50 +08:00
private readonly Container colourAndTriangles ;
2017-05-24 12:29:12 +08:00
private readonly Triangles triangles ;
2018-04-13 17:19:50 +08:00
2017-11-25 22:29:08 +08:00
/// <summary>
/// Return value decides whether the logo should play its own sample for the click action.
/// </summary>
public Func < bool > Action ;
2018-04-13 17:19:50 +08:00
2019-04-05 11:02:47 +08:00
/// <summary>
/// The size of the logo Sprite with respect to the scale of its hover and bounce containers.
/// </summary>
/// <remarks>Does not account for the scale of this <see cref="OsuLogo"/></remarks>
2019-03-28 14:40:58 +08:00
public float SizeForFlow = > logo = = null ? 0 : logo . DrawSize . X * logo . Scale . X * logoBounceContainer . Scale . X * logoHoverContainer . Scale . X ;
2018-04-13 17:19:50 +08:00
2019-04-05 12:56:08 +08:00
public bool IsTracking { get ; set ; }
2019-04-05 11:02:47 +08:00
2017-03-23 12:41:50 +08:00
private readonly Sprite ripple ;
2018-04-13 17:19:50 +08:00
2017-03-23 12:41:50 +08:00
private readonly Container rippleContainer ;
2018-04-13 17:19:50 +08:00
2016-12-01 19:21:14 +08:00
public bool Triangles
{
2019-02-28 12:58:19 +08:00
set = > colourAndTriangles . FadeTo ( value ? 1 : 0 , transition_length , Easing . OutQuint ) ;
2016-12-01 19:21:14 +08:00
}
2018-04-13 17:19:50 +08:00
2018-09-26 13:01:15 +08:00
public override bool ReceivePositionalInputAt ( Vector2 screenSpacePos ) = > logoContainer . ReceivePositionalInputAt ( screenSpacePos ) ;
2018-04-13 17:19:50 +08:00
2016-10-07 16:07:23 +08:00
public bool Ripple
{
2019-02-28 12:58:19 +08:00
get = > rippleContainer . Alpha > 0 ;
set = > rippleContainer . FadeTo ( value ? 1 : 0 , transition_length , Easing . OutQuint ) ;
2016-10-07 16:07:23 +08:00
}
2018-04-13 17:19:50 +08:00
2020-11-23 13:27:02 +08:00
private const float visualizer_default_alpha = 0.5f ;
2017-03-23 12:41:50 +08:00
private readonly Box flashLayer ;
2018-04-13 17:19:50 +08:00
2017-05-15 18:36:03 +08:00
private readonly Container impactContainer ;
2018-04-13 17:19:50 +08:00
2017-06-29 01:19:04 +08:00
private const double early_activation = 60 ;
2018-04-13 17:19:50 +08:00
2022-07-21 11:13:45 +08:00
private const float triangles_paused_velocity = 0.5f ;
2018-09-08 15:31:00 +08:00
public override bool IsPresent = > base . IsPresent | | Scheduler . HasPendingTasks ;
2016-10-07 16:07:23 +08:00
public OsuLogo ( )
{
2017-06-29 01:19:04 +08:00
EarlyActivationMilliseconds = early_activation ;
2018-04-13 17:19:50 +08:00
2016-10-07 16:07:23 +08:00
Origin = Anchor . Centre ;
2018-04-13 17:19:50 +08:00
2016-10-22 16:50:42 +08:00
AutoSizeAxes = Axes . Both ;
2018-04-13 17:19:50 +08:00
2016-10-07 16:07:23 +08:00
Children = new Drawable [ ]
{
2017-11-03 16:54:35 +08:00
intro = new IntroSequence
{
RelativeSizeAxes = Axes . Both ,
} ,
2017-05-23 14:29:23 +08:00
logoHoverContainer = new Container
2016-10-07 16:07:23 +08:00
{
2016-10-22 16:50:42 +08:00
AutoSizeAxes = Axes . Both ,
2016-10-07 16:07:23 +08:00
Children = new Drawable [ ]
{
2022-10-27 09:33:07 +08:00
logoBounceContainer = new Container
2016-10-07 16:07:23 +08:00
{
2016-10-22 17:40:04 +08:00
AutoSizeAxes = Axes . Both ,
2016-12-01 19:21:14 +08:00
Children = new Drawable [ ]
2016-10-17 01:25:08 +08:00
{
2017-05-23 14:29:23 +08:00
rippleContainer = new Container
{
Anchor = Anchor . Centre ,
Origin = Anchor . Centre ,
RelativeSizeAxes = Axes . Both ,
Children = new Drawable [ ]
{
ripple = new Sprite
{
Anchor = Anchor . Centre ,
Origin = Anchor . Centre ,
2019-08-21 12:29:50 +08:00
Blending = BlendingParameters . Additive ,
2017-05-23 14:29:23 +08:00
Alpha = 0
}
}
} ,
2017-05-24 00:45:01 +08:00
logoAmplitudeContainer = new Container
2016-12-01 19:21:14 +08:00
{
2016-12-01 20:29:14 +08:00
AutoSizeAxes = Axes . Both ,
2016-12-01 19:21:14 +08:00
Children = new Drawable [ ]
{
2017-05-24 00:45:01 +08:00
logoBeatContainer = new Container
2016-12-01 19:21:14 +08:00
{
2017-05-23 11:29:43 +08:00
AutoSizeAxes = Axes . Both ,
2016-12-01 19:52:26 +08:00
Children = new Drawable [ ]
{
2020-06-09 05:45:40 +08:00
visualizer = new MenuLogoVisualisation
2017-06-19 08:33:50 +08:00
{
RelativeSizeAxes = Axes . Both ,
Origin = Anchor . Centre ,
Anchor = Anchor . Centre ,
2020-11-23 13:27:02 +08:00
Alpha = visualizer_default_alpha ,
2017-06-19 08:33:50 +08:00
Size = new Vector2 ( 0.96f )
} ,
2018-03-01 15:01:32 +08:00
new Container
2016-12-01 19:52:26 +08:00
{
2017-05-24 00:45:01 +08:00
AutoSizeAxes = Axes . Both ,
2016-12-01 20:29:14 +08:00
Children = new Drawable [ ]
{
2017-05-24 00:45:01 +08:00
logoContainer = new CircularContainer
2016-12-01 20:29:14 +08:00
{
2017-05-23 11:29:43 +08:00
Anchor = Anchor . Centre ,
Origin = Anchor . Centre ,
2017-05-24 00:45:01 +08:00
RelativeSizeAxes = Axes . Both ,
Scale = new Vector2 ( 0.88f ) ,
Masking = true ,
2017-05-23 11:29:43 +08:00
Children = new Drawable [ ]
{
2017-05-24 00:45:01 +08:00
colourAndTriangles = new Container
2017-05-23 11:29:43 +08:00
{
RelativeSizeAxes = Axes . Both ,
2017-05-24 00:45:01 +08:00
Anchor = Anchor . Centre ,
Origin = Anchor . Centre ,
Children = new Drawable [ ]
{
new Box
{
RelativeSizeAxes = Axes . Both ,
Colour = OsuPink ,
} ,
2017-05-24 12:05:11 +08:00
triangles = new Triangles
2017-05-24 00:45:01 +08:00
{
TriangleScale = 4 ,
2020-03-11 09:18:41 +08:00
ColourLight = Color4Extensions . FromHex ( @"ff7db7" ) ,
ColourDark = Color4Extensions . FromHex ( @"de5b95" ) ,
2017-05-24 00:45:01 +08:00
RelativeSizeAxes = Axes . Both ,
} ,
}
2017-05-23 11:29:43 +08:00
} ,
2017-05-24 00:45:01 +08:00
flashLayer = new Box
2017-05-23 11:29:43 +08:00
{
RelativeSizeAxes = Axes . Both ,
2019-08-21 12:29:50 +08:00
Blending = BlendingParameters . Additive ,
2017-05-24 00:45:01 +08:00
Colour = Color4 . White ,
Alpha = 0 ,
2017-05-23 11:29:43 +08:00
} ,
2017-05-24 00:45:01 +08:00
} ,
2016-12-01 20:29:14 +08:00
} ,
2017-05-24 00:45:01 +08:00
logo = new Sprite
2016-12-01 20:29:14 +08:00
{
2017-05-24 00:45:01 +08:00
Anchor = Anchor . Centre ,
Origin = Anchor . Centre ,
2016-12-01 20:29:14 +08:00
} ,
2017-05-24 00:45:01 +08:00
}
2016-12-01 19:52:26 +08:00
} ,
2017-05-24 00:45:01 +08:00
impactContainer = new CircularContainer
2017-01-27 12:50:22 +08:00
{
2017-05-23 11:29:43 +08:00
Anchor = Anchor . Centre ,
Origin = Anchor . Centre ,
2017-05-24 00:45:01 +08:00
Alpha = 0 ,
BorderColour = Color4 . White ,
RelativeSizeAxes = Axes . Both ,
BorderThickness = 10 ,
Masking = true ,
Children = new Drawable [ ]
{
new Box
{
RelativeSizeAxes = Axes . Both ,
AlwaysPresent = true ,
Alpha = 0 ,
}
}
2017-05-23 11:29:43 +08:00
}
}
2017-05-15 18:36:03 +08:00
}
}
2016-10-07 16:07:23 +08:00
}
}
}
}
}
} ;
}
2018-04-13 17:19:50 +08:00
2017-11-13 17:43:05 +08:00
/// <summary>
2019-08-31 01:48:45 +08:00
/// Schedule a new external animation. Handled queueing and finishing previous animations in a sane way.
2017-11-13 17:43:05 +08:00
/// </summary>
/// <param name="action">The animation to be performed</param>
/// <param name="waitForPrevious">If true, the new animation is delayed until all previous transforms finish. If false, existing transformed are cleared.</param>
2017-11-21 10:49:42 +08:00
public void AppendAnimatingAction ( Action action , bool waitForPrevious )
2017-11-13 17:43:05 +08:00
{
2018-01-16 02:42:17 +08:00
void runnableAction ( )
2017-11-13 17:43:05 +08:00
{
if ( waitForPrevious )
this . DelayUntilTransformsFinished ( ) . Schedule ( action ) ;
else
{
ClearTransforms ( ) ;
action ( ) ;
}
2018-01-16 02:42:17 +08:00
}
2018-04-13 17:19:50 +08:00
2017-11-13 17:43:05 +08:00
if ( IsLoaded )
runnableAction ( ) ;
else
2018-01-16 04:27:00 +08:00
Schedule ( runnableAction ) ;
2017-11-13 17:43:05 +08:00
}
2018-04-13 17:19:50 +08:00
2016-11-12 18:44:16 +08:00
[BackgroundDependencyLoader]
2018-08-31 06:04:40 +08:00
private void load ( TextureStore textures , AudioManager audio )
2016-10-07 16:07:23 +08:00
{
2019-05-28 16:06:01 +08:00
sampleClick = audio . Samples . Get ( @"Menu/osu-logo-select" ) ;
sampleBeat = audio . Samples . Get ( @"Menu/osu-logo-heartbeat" ) ;
2021-02-10 17:14:32 +08:00
sampleDownbeat = audio . Samples . Get ( @"Menu/osu-logo-downbeat" ) ;
2018-04-13 17:19:50 +08:00
2018-08-31 06:04:40 +08:00
logo . Texture = textures . Get ( @"Menu/logo" ) ;
ripple . Texture = textures . Get ( @"Menu/logo" ) ;
2016-11-01 22:24:14 +08:00
}
2018-04-13 17:19:50 +08:00
2017-05-24 00:45:01 +08:00
private int lastBeatIndex ;
2018-04-13 17:19:50 +08:00
2020-06-23 12:49:18 +08:00
protected override void OnNewBeat ( int beatIndex , TimingControlPoint timingPoint , EffectControlPoint effectPoint , ChannelAmplitudes amplitudes )
2017-05-23 11:29:43 +08:00
{
2017-05-24 00:17:09 +08:00
base . OnNewBeat ( beatIndex , timingPoint , effectPoint , amplitudes ) ;
2018-04-13 17:19:50 +08:00
2017-05-24 00:45:01 +08:00
lastBeatIndex = beatIndex ;
2018-04-13 17:19:50 +08:00
2021-10-27 12:04:41 +08:00
double beatLength = timingPoint . BeatLength ;
2018-04-13 17:19:50 +08:00
2017-05-24 00:45:01 +08:00
float amplitudeAdjust = Math . Min ( 1 , 0.4f + amplitudes . Maximum ) ;
2018-04-13 17:19:50 +08:00
2017-05-24 00:17:09 +08:00
if ( beatIndex < 0 ) return ;
2018-04-13 17:19:50 +08:00
2017-07-07 13:59:17 +08:00
if ( IsHovered )
2021-02-10 17:14:32 +08:00
{
this . Delay ( early_activation ) . Schedule ( ( ) = >
{
2022-01-23 00:27:27 +08:00
if ( beatIndex % timingPoint . TimeSignature . Numerator = = 0 )
2022-04-15 19:32:41 +08:00
{
sampleDownbeat ? . Play ( ) ;
}
2021-02-10 17:14:32 +08:00
else
2022-04-15 19:32:41 +08:00
{
var channel = sampleBeat . GetChannel ( ) ;
channel . Frequency . Value = 0.95 + RNG . NextDouble ( 0.1 ) ;
channel . Play ( ) ;
}
2021-02-10 17:14:32 +08:00
} ) ;
}
2018-04-13 17:19:50 +08:00
2017-07-16 23:28:20 +08:00
logoBeatContainer
2020-11-23 13:27:02 +08:00
. ScaleTo ( 1 - 0.02f * amplitudeAdjust , early_activation , Easing . Out ) . Then ( )
2017-07-23 02:50:25 +08:00
. ScaleTo ( 1 , beatLength * 2 , Easing . OutQuint ) ;
2018-04-13 17:19:50 +08:00
2017-05-23 14:29:23 +08:00
ripple . ClearTransforms ( ) ;
2017-07-16 23:28:20 +08:00
ripple
. ScaleTo ( logoAmplitudeContainer . Scale )
2017-07-23 02:50:25 +08:00
. ScaleTo ( logoAmplitudeContainer . Scale * ( 1 + 0.04f * amplitudeAdjust ) , beatLength , Easing . OutQuint )
. FadeTo ( 0.15f * amplitudeAdjust ) . FadeOut ( beatLength , Easing . OutQuint ) ;
2018-04-13 17:19:50 +08:00
2017-05-24 00:17:09 +08:00
if ( effectPoint . KiaiMode & & flashLayer . Alpha < 0.4f )
2017-05-23 15:27:01 +08:00
{
flashLayer . ClearTransforms ( ) ;
2017-07-16 23:28:20 +08:00
flashLayer
2020-11-23 13:27:02 +08:00
. FadeTo ( 0.2f * amplitudeAdjust , early_activation , Easing . Out ) . Then ( )
2017-07-16 23:28:20 +08:00
. FadeOut ( beatLength ) ;
2018-04-13 17:19:50 +08:00
2017-07-16 23:28:20 +08:00
visualizer . ClearTransforms ( ) ;
visualizer
2020-11-23 13:27:02 +08:00
. FadeTo ( visualizer_default_alpha * 1.8f * amplitudeAdjust , early_activation , Easing . Out ) . Then ( )
. FadeTo ( visualizer_default_alpha , beatLength ) ;
2017-05-23 15:27:01 +08:00
}
2022-07-21 11:13:45 +08:00
2022-07-21 13:24:56 +08:00
this . Delay ( early_activation ) . Schedule ( ( ) = >
2022-07-21 11:38:33 +08:00
{
2022-07-21 13:24:56 +08:00
triangles . Velocity + = amplitudeAdjust * ( effectPoint . KiaiMode ? 6 : 3 ) ;
} ) ;
2017-05-23 11:29:43 +08:00
}
2018-04-13 17:19:50 +08:00
2017-11-03 16:54:35 +08:00
public void PlayIntro ( )
{
2017-11-08 13:31:11 +08:00
const double length = 3150 ;
const double fade = 200 ;
2018-04-13 17:19:50 +08:00
2017-11-03 16:54:35 +08:00
logoHoverContainer . FadeOut ( ) . Delay ( length ) . FadeIn ( fade ) ;
intro . Show ( ) ;
intro . Start ( length ) ;
intro . Delay ( length + fade ) . FadeOut ( ) ;
}
2018-04-13 17:19:50 +08:00
2020-08-04 20:53:00 +08:00
[Resolved]
private MusicController musicController { get ; set ; }
2017-05-24 00:45:01 +08:00
protected override void Update ( )
{
base . Update ( ) ;
2018-04-13 17:19:50 +08:00
2017-05-24 12:05:28 +08:00
const float scale_adjust_cutoff = 0.4f ;
2018-04-13 17:19:50 +08:00
2020-08-07 19:51:56 +08:00
if ( musicController . CurrentTrack . IsRunning )
2017-09-11 17:31:36 +08:00
{
2021-10-27 12:04:41 +08:00
float maxAmplitude = lastBeatIndex > = 0 ? musicController . CurrentTrack . CurrentAmplitudes . Maximum : 0 ;
2020-07-27 14:10:32 +08:00
logoAmplitudeContainer . Scale = new Vector2 ( ( float ) Interpolation . Damp ( logoAmplitudeContainer . Scale . X , 1 - Math . Max ( 0 , maxAmplitude - scale_adjust_cutoff ) * 0.04f , 0.9f , Time . Elapsed ) ) ;
2018-04-13 17:19:50 +08:00
2022-08-02 17:18:40 +08:00
triangles . Velocity = ( float ) Interpolation . Damp ( triangles . Velocity , triangles_paused_velocity * ( IsKiaiTime ? 4 : 2 ) , 0.995f , Time . Elapsed ) ;
2017-09-11 17:31:36 +08:00
}
2017-05-24 12:05:11 +08:00
else
2017-09-11 17:31:36 +08:00
{
2022-07-21 11:13:45 +08:00
triangles . Velocity = ( float ) Interpolation . Damp ( triangles . Velocity , triangles_paused_velocity , 0.9f , Time . Elapsed ) ;
2017-09-11 17:31:36 +08:00
}
2017-05-24 00:45:01 +08:00
}
2018-04-13 17:19:50 +08:00
2018-09-26 13:01:15 +08:00
public override bool HandlePositionalInput = > base . HandlePositionalInput & & Action ! = null & & Alpha > 0.2f ;
2018-04-13 17:19:50 +08:00
2018-10-02 11:02:47 +08:00
protected override bool OnMouseDown ( MouseDownEvent e )
2016-10-07 16:07:23 +08:00
{
2018-10-02 11:02:47 +08:00
if ( e . Button ! = MouseButton . Left ) return false ;
2018-07-12 11:15:22 +08:00
2017-07-23 02:50:25 +08:00
logoBounceContainer . ScaleTo ( 0.9f , 1000 , Easing . Out ) ;
2016-10-07 16:07:23 +08:00
return true ;
}
2018-04-13 17:19:50 +08:00
2020-01-20 17:17:21 +08:00
protected override void OnMouseUp ( MouseUpEvent e )
2016-10-07 16:07:23 +08:00
{
2020-01-20 17:17:21 +08:00
if ( e . Button ! = MouseButton . Left ) return ;
2018-07-12 11:15:22 +08:00
2017-07-23 02:50:25 +08:00
logoBounceContainer . ScaleTo ( 1f , 500 , Easing . OutElastic ) ;
2016-10-07 16:07:23 +08:00
}
2018-04-13 17:19:50 +08:00
2018-10-02 11:02:47 +08:00
protected override bool OnClick ( ClickEvent e )
2016-10-07 16:07:23 +08:00
{
2017-11-25 22:29:08 +08:00
if ( Action ? . Invoke ( ) ? ? true )
sampleClick . Play ( ) ;
2018-04-13 17:19:50 +08:00
2017-02-25 20:12:39 +08:00
flashLayer . ClearTransforms ( ) ;
2017-01-27 12:50:22 +08:00
flashLayer . Alpha = 0.4f ;
2017-07-23 02:50:25 +08:00
flashLayer . FadeOut ( 1500 , Easing . OutExpo ) ;
2016-10-07 16:07:23 +08:00
return true ;
}
2018-04-13 17:19:50 +08:00
2018-10-02 11:02:47 +08:00
protected override bool OnHover ( HoverEvent e )
2016-10-07 16:07:23 +08:00
{
2017-07-23 02:50:25 +08:00
logoHoverContainer . ScaleTo ( 1.1f , 500 , Easing . OutElastic ) ;
2016-10-07 16:07:23 +08:00
return true ;
}
2018-04-13 17:19:50 +08:00
2018-10-02 11:02:47 +08:00
protected override void OnHoverLost ( HoverLostEvent e )
2016-10-07 16:07:23 +08:00
{
2017-07-23 02:50:25 +08:00
logoHoverContainer . ScaleTo ( 1 , 500 , Easing . OutElastic ) ;
2016-10-07 16:07:23 +08:00
}
2018-04-13 17:19:50 +08:00
2017-05-15 18:36:03 +08:00
public void Impact ( )
{
2017-07-23 02:50:25 +08:00
impactContainer . FadeOutFromOne ( 250 , Easing . In ) ;
2017-05-15 18:36:03 +08:00
impactContainer . ScaleTo ( 0.96f ) ;
impactContainer . ScaleTo ( 1.12f , 250 ) ;
}
2022-04-28 21:58:32 +08:00
2022-10-27 09:33:07 +08:00
public override bool DragBlocksClick = > false ;
2022-04-29 11:09:11 +08:00
2022-10-27 09:33:07 +08:00
protected override bool OnDragStart ( DragStartEvent e ) = > true ;
2022-04-28 21:58:32 +08:00
2022-10-27 09:33:07 +08:00
protected override void OnDrag ( DragEvent e )
{
Vector2 change = e . MousePosition - e . MouseDownPosition ;
2022-04-28 21:58:32 +08:00
2022-10-27 09:33:07 +08:00
// Diminish the drag distance as we go further to simulate "rubber band" feeling.
change * = change . Length < = 0 ? 0 : MathF . Pow ( change . Length , 0.6f ) / change . Length ;
2022-04-28 21:58:32 +08:00
2022-10-27 09:33:07 +08:00
logoBounceContainer . MoveTo ( change ) ;
}
2022-04-28 21:58:32 +08:00
2022-10-27 09:33:07 +08:00
protected override void OnDragEnd ( DragEndEvent e )
{
logoBounceContainer . MoveTo ( Vector2 . Zero , 800 , Easing . OutElastic ) ;
base . OnDragEnd ( e ) ;
2022-04-28 21:58:32 +08:00
}
2016-10-07 16:07:23 +08:00
}
2017-05-24 01:53:21 +08:00
}