16 private bool _isResizing;
17 private float _resizeElapsedSeconds;
18 private float _resizeDurationSeconds;
19 private Size _resizeStart;
20 private Size _resizeTarget;
22 private bool _resizeReturnToStart;
23 private float _resizeReturnDurationSeconds;
24 private Size _resizeOriginalStart;
25 private Size _resizePeak;
27 private bool _isPulseMode;
28 private bool _pulseLoop;
29 private bool _pulseForward;
30 private float _pulseGrowDurationSeconds;
31 private float _pulseShrinkDurationSeconds;
34 private Size _resizeStartSizeForCollision;
36 internal void AdvanceResize(
float deltaSeconds)
41 if (_resizeDurationSeconds <= 0f)
49 _resizeElapsedSeconds += deltaSeconds;
51 float t = _resizeElapsedSeconds / _resizeDurationSeconds;
55 int w = (int)MathF.Round(
56 _resizeStart.Width + ((_resizeTarget.Width - _resizeStart.Width) * t));
57 int h = (int)MathF.Round(
58 _resizeStart.Height + ((_resizeTarget.Height - _resizeStart.Height) * t));
60 var next =
new Size(Math.Max(1, w), Math.Max(1, h));
62 if (next != _renderSize)
65 ApplyScaledCollisionAdjust(next);
72 private void CompleteResizeLeg()
81 _pulseForward =
false;
84 target: _resizeOriginalStart,
85 durationSeconds: _pulseShrinkDurationSeconds,
87 returnDurationSeconds: 0f);
95 start: _resizeOriginalStart,
97 durationSeconds: _pulseGrowDurationSeconds,
99 returnDurationSeconds: 0f);
103 _isPulseMode =
false;
109 if (_resizeReturnToStart)
113 target: _resizeOriginalStart,
114 durationSeconds: _resizeReturnDurationSeconds,
115 returnToStart:
false,
116 returnDurationSeconds: 0f);
125 private void StartResizeLeg(
128 float durationSeconds,
130 float returnDurationSeconds)
132 _resizeStart = start;
133 _resizeTarget = target;
134 _resizeDurationSeconds = Math.Max(0f, durationSeconds);
135 _resizeElapsedSeconds = 0f;
138 _resizeReturnToStart = returnToStart;
139 _resizeReturnDurationSeconds = Math.Max(0f, returnDurationSeconds);
142 _resizeStartSizeForCollision = start;
145 private void ApplyScaledCollisionAdjust(Size currentSize)
147 if (_resizeStartSizeForCollision.Width <= 0 ||
148 _resizeStartSizeForCollision.Height <= 0)
153 float sx = (float)currentSize.Width / _resizeStartSizeForCollision.Width;
154 float sy = (float)currentSize.Height / _resizeStartSizeForCollision.Height;
157 top: (
int)MathF.Round(_resizeStartCollisionAdjust.Top * sy),
158 bottom: (
int)MathF.Round(_resizeStartCollisionAdjust.Bottom * sy),
159 left: (
int)MathF.Round(_resizeStartCollisionAdjust.Left * sx),
160 right: (
int)MathF.Round(_resizeStartCollisionAdjust.Right * sx));
168 public void ResizeTo(Size targetSize,
float durationSeconds)
170 targetSize =
new Size(
171 Math.Max(1, targetSize.Width),
172 Math.Max(1, targetSize.Height));
174 _isPulseMode =
false;
181 durationSeconds: durationSeconds,
182 returnToStart:
false,
183 returnDurationSeconds: 0f);
191 public void ScaleBy(
float factor,
float durationSeconds)
193 factor = MathF.Max(0.01f, factor);
195 int w = (int)MathF.Round(
RenderSize.Width * factor);
196 int h = (int)MathF.Round(
RenderSize.Height * factor);
199 new Size(Math.Max(1, w), Math.Max(1, h)),
212 float growDurationSeconds,
213 float shrinkDurationSeconds,
216 targetSize =
new Size(
217 Math.Max(1, targetSize.Width),
218 Math.Max(1, targetSize.Height));
221 _resizePeak = targetSize;
225 _pulseForward =
true;
226 _pulseGrowDurationSeconds = Math.Max(0f, growDurationSeconds);
227 _pulseShrinkDurationSeconds = Math.Max(0f, shrinkDurationSeconds);
230 start: _resizeOriginalStart,
232 durationSeconds: _pulseGrowDurationSeconds,
233 returnToStart:
false,
234 returnDurationSeconds: 0f);
246 float growDurationSeconds,
247 float shrinkDurationSeconds,
250 factor = MathF.Max(0.01f, factor);
252 int w = (int)MathF.Round(
RenderSize.Width * factor);
253 int h = (int)MathF.Round(
RenderSize.Height * factor);
256 new Size(Math.Max(1, w), Math.Max(1, h)),
258 shrinkDurationSeconds,
267 public void StopPulse(
bool snapBack =
true,
float returnDuration = 0f)
269 Size originalSize = _resizeOriginalStart;
270 var originalCollisionAdjust = _resizeStartCollisionAdjust;
277 if (returnDuration <= 0f)
284 ResizeTo(originalSize, returnDuration);
294 _resizeReturnToStart =
false;
295 _isPulseMode =
false;
297 _pulseForward =
false;
Represents a movable visual element on a scene layer.
void PulseBy(float factor, float growDurationSeconds, float shrinkDurationSeconds, bool loop=false)
Pulses by a factor relative to the current render size.
void ResizeTo(Size targetSize, float durationSeconds)
Smoothly resizes the sprite to an absolute pixel size.
Size RenderSize
Gets or sets the render size.
void ScaleBy(float factor, float durationSeconds)
Scales the sprite by a factor relative to its current render size.
void PulseTo(Size targetSize, float growDurationSeconds, float shrinkDurationSeconds, bool loop=false)
Resizes to an absolute target size and then returns to the original size.
void CancelResize()
Cancels any in-progress resize or pulse.
void StopPulse(bool snapBack=true, float returnDuration=0f)
Stops the current pulse, optionally returning to the original size.
Action? ResizeComplete
Raised when a resize or pulse animation completes its current leg, or when cancelled.
virtual CollisionAdjust AdjustCollisionArea
Gets or sets the collision adjustment used to derive CollisionArea.
Per-edge inset amounts applied to visual bounds to produce a collision rectangle.