Create simple animation

This works with BETA3 and higher

We will provide an entire chapter on animation, but for now, please find a quick example on how to animate graphics.

Simple Watch animation

📘

Source Code

Please see the UgSwissWatchDemo project for the source code created in this chapter. See Installing examples for information on how to download the examples.

The idea is to use SVG to create a simple animated circular watch comprising three hands.

<g>
   <ellipse fill="#FFFFFF" rx="125" cx="135" ry="125" id="svg_1" cy="135" stroke="#000000" stroke-width="14.0"/>
      <line stroke-linecap="null" fill="none" x1="135" x2="135" y1="135" stroke-linejoin="null" y2="50" id="svg_4" stroke="#000000" stroke-width="14.0"/>
      <line stroke-linecap="null" fill="none" x1="135" x2="200" y1="135" stroke-linejoin="null" y2="135" id="svg_6" stroke="#666666" stroke-width="14.0"/>
      <line stroke-linecap="null" fill="none" x1="135" x2="135" y1="135" stroke-linejoin="null" y2="35" id="sechand" opacity="0.5" stroke="#FF0000" stroke-width="5.0"/>
</g>

Drag and drop a CustomWidget to a page. Use its Layout property to size and position it to be in the page's centre:

Copy and paste the above SVG code snippet into a CustomWidget:

To polish it, we set the page background to grey.

Code for animating the second hand

The source code provides two alternative ways of animating the second hand of the watch:

  1. moveSecHand
  2. moveSecHand2

We use an SCD SVG animation to animate the SVG element named sechand

self.secondHandSvg = self.page!.drawing!.findById("sechand") as? SCDSvgLine

moveSecHand2

The second method, moveSecHand2, is a little more elegant. The API is a little older and not very Swift-like, but we fixed this:

  • We use a SCD SVG animation to animate the SVG element named sechand
  • It depends on SCDSvgRotateAnimation and uses its attributes such as .angle to rotate 360 degrees within .duration 60 seconds via the .anchor concept, and continues if not signaled otherwise.
  • The anchor concept might not be known to everyone, in a nutshell : (1,1) is lower right corner, (0,0) upper left, and (1,0) upper right corner. (0,5,1) puts it the rotation anchor in the midway on the x-axis and uses bottom of the y-axis.
  • You can also choose how many times you want the animated hand to rotate using the .repeatCount or use the .onComplete to have an endless animated rotation.

Entire code with two the different options of implementation

Animations with a very few lines of code.

import ScadeKit

class MainPageAdapter: SCDLatticePageAdapter {
	
	var secondHandPos : Float = 0.0
	var secondHandSvg : SCDSvgLine?
	var statusStopped : Bool = false

	override func show(_ view: SCDLatticeView, data: Any!) {		
		super.show(view, data: data)
		
		self.secondHandSvg = self.page!.drawing!.find(byId: "sechand") as? SCDSvgLine
		self.moveSecHand2()
	}
	
	func moveSecHand()  {
		// This is another option how to do it,
		// but our best practice approach is moveSecHand2. Less CPU intensive
		
		SCDRuntime.call(withDelay: 1) {
        	self.secondHandPos = self.secondHandPos >= 360 ? 0.0 : self.secondHandPos + 6.0
			if let tranformableSvg = self.secondHandSvg! as? SCDSvgTransformable {
        		tranformableSvg.matrix = SCDSvgMatrix()
				tranformableSvg.rotateAround(self.secondHandPos,x:self.secondHandSvg!.x1.value,y:self.secondHandSvg!.y1.value)
        	}
			self.moveSecHand()
		}
	}
	
	func moveSecHand2() {
		// this is the more economic option
		// Create SVG animation
		let animation = SCDSvgRotateAnimation()
		
		// animation runs for 60 seconds
		animation.duration = 60
		
		// rotates hand 360 degrees
		animation.angle = 360	
		
		// rotate around the botton middle part
		animation.anchorX = 0.5
		animation.anchorY = 1.0
		
		// and repeats once
		animation.repeatCount = 1
		
		// once we finished the animation, we start over
		animation.onComplete = SCDSvgOnCompleteHandler{ _ in if(!self.statusStopped) { self.moveSecHand2() } }
		
		// add animation to SVG
		self.secondHandSvg!.animations.append(animation)
	}
}