mirror of
https://github.com/osukey/osukey.git
synced 2025-07-02 00:40:09 +09:00
generalize and simplify animation
This commit is contained in:
29
osu.Game.Tests/Visual/UserInterface/TestSceneHueAnimation.cs
Normal file
29
osu.Game.Tests/Visual/UserInterface/TestSceneHueAnimation.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.UserInterface
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestSceneHueAnimation : OsuTestScene
|
||||||
|
{
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(TextureStore textures)
|
||||||
|
{
|
||||||
|
HueAnimation anim;
|
||||||
|
|
||||||
|
Add(anim = new HueAnimation
|
||||||
|
{
|
||||||
|
Texture = textures.Get("Intro/Triangles/logo-triangles.png"),
|
||||||
|
Colour = Colour4.White,
|
||||||
|
});
|
||||||
|
|
||||||
|
AddSliderStep("Progress", 0f, 1f, 0f, newValue => anim.AnimationProgress = newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
75
osu.Game/Graphics/Sprites/HueAnimation.cs
Normal file
75
osu.Game/Graphics/Sprites/HueAnimation.cs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.OpenGL.Vertices;
|
||||||
|
using osu.Framework.Graphics.Shaders;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Graphics.Sprites
|
||||||
|
{
|
||||||
|
public class HueAnimation : Sprite
|
||||||
|
{
|
||||||
|
public HueAnimation()
|
||||||
|
{
|
||||||
|
Size = new Vector2(960);
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(ShaderManager shaders, TextureStore textures)
|
||||||
|
{
|
||||||
|
TextureShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, @"HueAnimation");
|
||||||
|
RoundedTextureShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, @"HueAnimation"); // Masking isn't supported for now
|
||||||
|
}
|
||||||
|
|
||||||
|
private float animationProgress;
|
||||||
|
|
||||||
|
public float AnimationProgress
|
||||||
|
{
|
||||||
|
get => animationProgress;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (animationProgress == value) return;
|
||||||
|
|
||||||
|
animationProgress = value;
|
||||||
|
Invalidate(Invalidation.DrawInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool IsPresent => true;
|
||||||
|
|
||||||
|
protected override DrawNode CreateDrawNode() => new HueAnimationDrawNode(this);
|
||||||
|
|
||||||
|
private class HueAnimationDrawNode : SpriteDrawNode
|
||||||
|
{
|
||||||
|
protected new HueAnimation Source => (HueAnimation)base.Source;
|
||||||
|
|
||||||
|
private float progress;
|
||||||
|
|
||||||
|
public HueAnimationDrawNode(HueAnimation source)
|
||||||
|
: base(source)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ApplyState()
|
||||||
|
{
|
||||||
|
base.ApplyState();
|
||||||
|
|
||||||
|
progress = Source.animationProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Blit(Action<TexturedVertex2D> vertexAction)
|
||||||
|
{
|
||||||
|
Shader.GetUniform<float>("progress").UpdateValue(ref progress);
|
||||||
|
|
||||||
|
base.Blit(vertexAction);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool CanDrawOpaqueInterior => false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -137,7 +138,7 @@ namespace osu.Game.Screens.Menu
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Child = lazerLogo = new LazerLogo()
|
Child = lazerLogo = new LazerLogo
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre
|
Origin = Anchor.Centre
|
||||||
@ -216,7 +217,13 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
// matching flyte curve y = 0.25x^2 + (max(0, x - 0.7) / 0.3) ^ 5
|
// matching flyte curve y = 0.25x^2 + (max(0, x - 0.7) / 0.3) ^ 5
|
||||||
lazerLogo.FadeIn().ScaleTo(scale_start).Then().Delay(logo_scale_duration * 0.7f).ScaleTo(scale_start - scale_adjust, logo_scale_duration * 0.3f, Easing.InQuint);
|
lazerLogo.FadeIn().ScaleTo(scale_start).Then().Delay(logo_scale_duration * 0.7f).ScaleTo(scale_start - scale_adjust, logo_scale_duration * 0.3f, Easing.InQuint);
|
||||||
lazerLogo.Start(logo_1, logo_scale_duration);
|
|
||||||
|
lazerLogo.TransformTo(nameof(LazerLogo.Highlight), 0.6f, logo_scale_duration * 0.4f, Easing.OutCirc).Then()
|
||||||
|
.TransformTo(nameof(LazerLogo.Highlight), 1f, logo_scale_duration * 0.4f);
|
||||||
|
|
||||||
|
lazerLogo.TransformTo(nameof(LazerLogo.Animation), 0.4f, logo_scale_duration * 0.5f, Easing.OutQuart).Then()
|
||||||
|
.TransformTo(nameof(LazerLogo.Animation), 1f, logo_scale_duration * 0.4f);
|
||||||
|
|
||||||
logoContainerSecondary.ScaleTo(scale_start).Then().ScaleTo(scale_start - scale_adjust * 0.25f, logo_scale_duration, Easing.InQuad);
|
logoContainerSecondary.ScaleTo(scale_start).Then().ScaleTo(scale_start - scale_adjust * 0.25f, logo_scale_duration, Easing.InQuad);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,20 +265,42 @@ namespace osu.Game.Screens.Menu
|
|||||||
|
|
||||||
private class LazerLogo : CompositeDrawable
|
private class LazerLogo : CompositeDrawable
|
||||||
{
|
{
|
||||||
private readonly Stream videoStream;
|
private HueAnimation highlight, animation;
|
||||||
|
|
||||||
public LazerLogo(Stream videoStream)
|
public float Highlight
|
||||||
|
{
|
||||||
|
get => highlight.AnimationProgress;
|
||||||
|
set => highlight.AnimationProgress = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float Animation
|
||||||
|
{
|
||||||
|
get => animation.AnimationProgress;
|
||||||
|
set => animation.AnimationProgress = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LazerLogo()
|
||||||
{
|
{
|
||||||
this.videoStream = videoStream;
|
|
||||||
Size = new Vector2(960);
|
Size = new Vector2(960);
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load(TextureStore textures)
|
||||||
{
|
{
|
||||||
InternalChild = new Video(videoStream)
|
const string lazer_logo_texture = @"Intro/Triangles/logo-triangles";
|
||||||
|
|
||||||
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
highlight = new HueAnimation
|
||||||
|
{
|
||||||
|
Texture = textures.Get(lazer_logo_texture),
|
||||||
|
Colour = OsuColour.Gray(0.6f).Opacity(0.8f),
|
||||||
|
},
|
||||||
|
animation = new HueAnimation
|
||||||
|
{
|
||||||
|
Texture = textures.Get(lazer_logo_texture),
|
||||||
|
Colour = Color4.White.Opacity(0.8f),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,109 +0,0 @@
|
|||||||
// 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.
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.OpenGL.Vertices;
|
|
||||||
using osu.Framework.Graphics.Primitives;
|
|
||||||
using osu.Framework.Graphics.Shaders;
|
|
||||||
using osu.Framework.Graphics.Textures;
|
|
||||||
using osu.Framework.MathUtils;
|
|
||||||
using osuTK;
|
|
||||||
|
|
||||||
namespace osu.Game.Screens.Menu
|
|
||||||
{
|
|
||||||
public class LazerLogo : Drawable
|
|
||||||
{
|
|
||||||
private IShader shader;
|
|
||||||
private Texture texture;
|
|
||||||
|
|
||||||
private double startTime = -1000;
|
|
||||||
private double animationTime = -1000;
|
|
||||||
|
|
||||||
private float animation;
|
|
||||||
private float highlight;
|
|
||||||
|
|
||||||
public LazerLogo()
|
|
||||||
{
|
|
||||||
Size = new Vector2(960);
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(ShaderManager shaders, TextureStore textures)
|
|
||||||
{
|
|
||||||
shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, @"LazerLogo");
|
|
||||||
texture = textures.Get("Menu/logo-triangles.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Start(double delay, double duration)
|
|
||||||
{
|
|
||||||
startTime = Clock.CurrentTime + delay;
|
|
||||||
animationTime = duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool IsPresent => true;
|
|
||||||
|
|
||||||
protected override void Update()
|
|
||||||
{
|
|
||||||
base.Update();
|
|
||||||
|
|
||||||
if (animationTime < 0) return;
|
|
||||||
|
|
||||||
highlight = Clock.CurrentTime < startTime + 0.4 * animationTime
|
|
||||||
? Interpolation.ValueAt(Clock.CurrentTime, 0f, 1f, startTime, startTime + animationTime * 1.07, Easing.OutCirc)
|
|
||||||
: Interpolation.ValueAt(Clock.CurrentTime, 0.6f, 1f, startTime, startTime + animationTime * 0.9);
|
|
||||||
|
|
||||||
animation = Clock.CurrentTime < startTime + 0.5 * animationTime
|
|
||||||
? Interpolation.ValueAt(Clock.CurrentTime, 0f, 0.8f, startTime, startTime + animationTime * 1.23, Easing.OutQuart)
|
|
||||||
: Interpolation.ValueAt(Clock.CurrentTime, 0.4f, 1f, startTime, startTime + animationTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override DrawNode CreateDrawNode() => new LazerLogoDrawNode(this);
|
|
||||||
|
|
||||||
private class LazerLogoDrawNode : DrawNode
|
|
||||||
{
|
|
||||||
protected new LazerLogo Source => (LazerLogo)base.Source;
|
|
||||||
|
|
||||||
private IShader shader;
|
|
||||||
private Texture texture;
|
|
||||||
private Quad screenSpaceDrawQuad;
|
|
||||||
private float animation;
|
|
||||||
private float highlight;
|
|
||||||
|
|
||||||
public LazerLogoDrawNode(LazerLogo source)
|
|
||||||
: base(source)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ApplyState()
|
|
||||||
{
|
|
||||||
base.ApplyState();
|
|
||||||
|
|
||||||
shader = Source.shader;
|
|
||||||
texture = Source.texture;
|
|
||||||
screenSpaceDrawQuad = Source.ScreenSpaceDrawQuad;
|
|
||||||
animation = Source.animation;
|
|
||||||
highlight = Source.highlight;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void Blit(Action<TexturedVertex2D> vertexAction)
|
|
||||||
{
|
|
||||||
DrawQuad(texture, screenSpaceDrawQuad, DrawColourInfo.Colour, null, vertexAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Draw(Action<TexturedVertex2D> vertexAction)
|
|
||||||
{
|
|
||||||
base.Draw(vertexAction);
|
|
||||||
|
|
||||||
shader.Bind();
|
|
||||||
shader.GetUniform<float>("highlight").Value = highlight;
|
|
||||||
shader.GetUniform<float>("animation").Value = animation;
|
|
||||||
|
|
||||||
Blit(vertexAction);
|
|
||||||
|
|
||||||
shader.Unbind();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user