<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Xojo-Graphics &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/xojo-graphics/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Mon, 04 Nov 2024 15:42:22 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Beyond Static UI: Create Dynamic Loading Animations with Xojo Graphics</title>
		<link>https://blog.xojo.com/2024/11/05/beyond-static-ui-create-dynamic-loading-animations-with-xojo-graphics/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Tue, 05 Nov 2024 15:10:24 +0000</pubDate>
				<category><![CDATA[Desktop]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Animation]]></category>
		<category><![CDATA[Custom Controls]]></category>
		<category><![CDATA[DesktopCanvas]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Phase-Animation]]></category>
		<category><![CDATA[UI-Design]]></category>
		<category><![CDATA[Visual Feedback]]></category>
		<category><![CDATA[Xojo-Graphics]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13975</guid>

					<description><![CDATA[Ever wondered how to create those sleek, professional-looking loading animations you see in modern apps? In this blog post, we&#8217;re going to unlock the power&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Ever wondered how to create those sleek, professional-looking loading animations you see in modern apps?</p>



<p>In this blog post, we&#8217;re going to unlock the power of Xojo&#8217;s DesktopCanvas and its Graphics capabilities to recreate one of the popular <a href="https://tobiasahlin.com/spinkit/">SpinKit loading animations originally created by Tobias Ahlin</a>. We&#8217;ll be implementing the &#8220;Three Bounce&#8221; animation, transforming this beloved CSS animation into native Xojo code!</p>



<p>Not only will you learn how to create this specific animation, but you&#8217;ll also gain valuable insights into animation principles in Xojo that you can use to create your own custom animations. By the end of this tutorial, you&#8217;ll understand how to:</p>



<ul class="wp-block-list">
<li>Harness the power of DesktopCanvas for custom graphics</li>



<li>Create smooth animations using Timers</li>



<li>Implement phase-based animations</li>



<li>Use Graphics methods to draw dynamic shapes</li>



<li>Manage animation lifecycles properly</li>
</ul>



<h3 class="wp-block-heading">Why This Matters</h3>



<p>Loading animations are more than just eye candy – they&#8217;re essential UI elements that keep users engaged while your app processes data. Instead of using static images or third-party libraries, creating your own animations gives you complete control over the look and feel of your application while keeping your dependencies minimal.</p>



<h3 class="wp-block-heading">What We&#8217;re Building</h3>



<p>We&#8217;ll create a smooth, professional-looking three-dot loading animation where dots gracefully scale up and down in sequence. The result is a lightweight, customizable loading indicator that you can drop into any Xojo project. Here&#8217;s what makes this implementation special:</p>



<ul class="wp-block-list">
<li>Pure Xojo code &#8211; no external dependencies</li>



<li>Smooth, fluid animation</li>



<li>Easily customizable colors and timing</li>



<li>Efficient resource usage</li>



<li>Clean, object-oriented design</li>
</ul>



<figure class="wp-block-video"><video height="184" style="aspect-ratio: 360 / 184;" width="360" controls loop preload="auto" src="https://blog.xojo.com/wp-content/uploads/2024/10/spinkit_animation.mp4" playsinline></video></figure>



<p>Ok, let&#8217;s start building our awesome animation class.</p>



<h2 class="wp-block-heading">Step 1: Setting Up the Base Class</h2>



<p>First, create a new class (Insert &gt; Class) that inherits from DesktopCanvas:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://storage.googleapis.com/co-writer/images/HRIwK4xjWLXvNRyAbzXbq5t8wJF3/-1730379923862.webp" alt="IMAGE"/></figure>
</div>


<pre class="wp-block-code"><code>Protected Class SpinKitClass Inherits DesktopCanvas</code></pre>



<h2 class="wp-block-heading">Step 2: Defining Core Properties</h2>



<p>Add these essential properties to control the animation:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://storage.googleapis.com/co-writer/images/HRIwK4xjWLXvNRyAbzXbq5t8wJF3/-1730380034310.webp" alt="IMAGE"/></figure>
</div>


<pre class="wp-block-code"><code>Private animationPhases() As Double      // Stores phase offsets for each dot
Private animationSpeed As Integer = 60   // Animation refresh rate in milliseconds
Private animationTimer As Timer         // Timer to drive the animation
Private currentPhase As Double = 0.0    // Current animation phase
Private dotSize As Integer = 20         // Size of each dot
Private dotSpacing As Integer = 20      // Space between dots</code></pre>



<h2 class="wp-block-heading">Step 3: Setting Up Constants</h2>



<p>Define the constants that control the animation behavior:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://storage.googleapis.com/co-writer/images/HRIwK4xjWLXvNRyAbzXbq5t8wJF3/-1730380079168.webp" alt="IMAGE"/></figure>
</div>


<pre class="wp-block-code"><code>Private Const kDefaultColor As Color = &amp;c333333    // Dot color
Private Const kPhaseIncrement As Double = 0.05    // Animation speed</code></pre>



<h2 class="wp-block-heading">Step 4: Implementing Animation Control Methods</h2>



<p>Add methods to start and stop the animation:</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<pre class="wp-block-code"><code>Public Sub StartAnimation()
  /// Initializes and starts the animation
  /// Sets up initial phase offsets for the dots
  /// Creates and configures the animation timer
  
  If animationTimer = Nil Then
    animationPhases = Array(0.0, 0.16, 0.32)
    
    animationTimer = New Timer
    AddHandler animationTimer.Action, AddressOf UpdateAnimation
    animationTimer.Period = animationSpeed
    animationTimer.RunMode = Timer.RunModes.Multiple
  End If
End Sub</code></pre>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<pre class="wp-block-code"><code>Public Sub StopAnimation()
  /// Stops the running animation
  /// Removes the timer handler and cleans up
  /// Refreshes the canvas to clear the animation
  
  If animationTimer &lt;&gt; Nil Then
    RemoveHandler animationTimer.Action, AddressOf UpdateAnimation
    animationTimer = Nil
    Refresh
  End If
End Sub</code></pre>
</div>
</div>



<h2 class="wp-block-heading">Step 5: Creating the Animation Update Logic</h2>



<p>Implement the timer callback that drives the animation:</p>



<pre class="wp-block-code"><code>Private Sub updateAnimation(sender As Timer)
  /// Timer callback that updates the animation state
  /// Increments the phase and triggers a redraw
  /// @param sender The Timer that triggered this callback
  
  #Pragma Unused sender
  
  // Increment the current phase (spin08)
  currentPhase = currentPhase + kPhaseIncrement
  // Reset currentPhase if it exceeds 1.0
  If currentPhase &gt; 1.0 Then currentPhase = 0
  
  // Invalidate the canvas to trigger a repaint
  Refresh()
End Sub</code></pre>



<h2 class="wp-block-heading">Step 6: Implementing the Drawing Logic</h2>



<p>Add the core animation rendering code:</p>



<pre class="wp-block-code"><code>Private Sub animation08(g As Graphics)
  /// Renders a single frame of the three-dot loading animation
  /// Draws 3 dots that scale up and down in sequence
  /// @param g The graphics context to draw into
  
  Var centerX As Integer = Me.Width / 2
  Var centerY As Integer = Me.Height / 2
  
  For i As Integer = 0 To 2
    Var phase As Double = currentPhase + animationPhases(i)
    
    // Ensure phase is within 0 to 1
    If phase &gt; 1.0 Then phase = phase - 1.0
    
    Var scale As Double
    If phase &lt; 0.4 Then
      scale = phase / 0.4
    Else
      scale = (1.0 - phase) / 0.6
    End If
    
    Var size As Integer = dotSize * scale
    Var x As Integer = centerX + (i - 1) * dotSpacing - size / 2
    Var y As Integer = centerY - size / 2
    
    g.DrawingColor = kDefaultColor
    g.FillOval(x, y, size, size)
  Next
End Sub</code></pre>



<h2 class="wp-block-heading">Step 7: Handling the Paint Event</h2>



<p>Implement the Paint event to trigger the animation rendering:</p>



<pre class="wp-block-code"><code>Sub Paint(g As Graphics, areas() As Rect) Handles Paint
  /// Paint event handler that renders the animation
  /// Called automatically when the canvas needs to be redrawn
  /// If animation is running, calls animation08, otherwise clears the canvas
  
  If animationTimer &lt;&gt; Nil Then
    animation08(g)
  Else
    g.ClearRectangle(0, 0, Width, Height)
  End If
End Sub
</code></pre>



<h2 class="wp-block-heading">How It Works</h2>



<ol class="wp-block-list">
<li>The animation uses a phase-based system where each dot is offset in its animation cycle.</li>



<li>The dots scale up and down based on their current phase.</li>



<li>A timer drives the animation by incrementing the phase and triggering redraws.</li>



<li>The dots are positioned horizontally with equal spacing around the center.</li>



<li>Each dot&#8217;s size is calculated based on its current phase in the animation.</li>
</ol>



<h2 class="wp-block-heading">Using the Animation</h2>



<p>To use this animation in your project, all you have to do is simply drag and drop the class on a DesktopWindow and then start or stop the animation when needed.</p>



<pre class="wp-block-code"><code>// Start the animation
SpinKit1.StartAnimation()

// Stop the animation when done
SpinKit1.StopAnimation()</code></pre>



<h2 class="wp-block-heading">Customization</h2>



<p>You can customize the animation by adjusting:</p>



<ul class="wp-block-list">
<li><code>dotSize</code> for larger or smaller dots</li>



<li><code>dotSpacing</code> to change the spread of the dots</li>



<li><code>animationSpeed</code> to make it faster or slower</li>



<li><code>kDefaultColor</code> to change the dot color</li>



<li><code>kPhaseIncrement</code> to adjust the animation speed</li>
</ul>



<h2 class="wp-block-heading">Taking It Further</h2>



<p>The &#8220;Three Bounce&#8221; animation we&#8217;ve created is just one of many amazing animations in the <a href="https://tobiasahlin.com/spinkit/">SpinKit collection</a>. Now that you understand the fundamentals, why not try recreating other SpinKit animations? Here are some exciting challenges to tackle:</p>



<ul class="wp-block-list">
<li>Modify the current animation to use different shapes (squares, rectangles).</li>



<li>Experiment with different timing functions for varied animation effects.</li>



<li>Try implementing the &#8220;Rotating Plane&#8221; or &#8220;Chasing Dots&#8221; animations from SpinKit.</li>



<li>Create your own unique variations by combining what you&#8217;ve learned.</li>



<li>Optimize the class further.</li>
</ul>



<h2 class="wp-block-heading">Share Your Creations!</h2>



<p>Have you created an awesome variation or implemented another SpinKit animation in Xojo? Share it with the community! The <a target="_blank" rel="noreferrer noopener" href="https://forum.xojo.com/">Xojo Forums</a> and social media are great places to showcase your work and inspire others.</p>



<h2 class="wp-block-heading">Resources for Further Exploration</h2>



<ul class="wp-block-list">
<li>Original SpinKit animations by Tobias Ahlin: <a href="https://tobiasahlin.com/spinkit/" target="_blank" rel="noreferrer noopener">https://tobiasahlin.com/spinkit/</a></li>



<li>Xojo Graphics documentation: <a href="https://documentation.xojo.com/api/graphics/graphics.html" target="_blank" rel="noreferrer noopener">https://documentation.xojo.com/api/graphics/graphics.html</a></li>



<li>Xojo DesktopCanvas documentation: <a href="https://documentation.xojo.com/api/user_interface/desktop/desktopcanvas.html" target="_blank" rel="noreferrer noopener">https://documentation.xojo.com/api/user_interface/desktop/desktopcanvas.html</a></li>
</ul>



<p><strong>Remember</strong>: Every great application deserves great animations and now you have the tools to create them! Keep experimenting, keep creating, and most importantly, keep animating!</p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2024/10/spinkit_animation.mp4" length="308355" type="video/mp4" />

			</item>
	</channel>
</rss>
