Skip to content

Commit 53a9f10

Browse files
authored
Merge pull request #427 from f3dm76/fix/morphingAnimation
Morphing animation scale/translate/rotation
2 parents 34e381f + 70ff74e commit 53a9f10

File tree

7 files changed

+47
-28
lines changed

7 files changed

+47
-28
lines changed

Source/animation/AnimationUtils.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import Foundation
22

33
class AnimationUtils {
4-
class func absolutePosition(_ node: Node) -> Transform {
5-
return AnimationUtils.absoluteTransform(node, pos: node.place)
4+
class func absolutePosition(_ node: Node, view: MacawView? = nil) -> Transform {
5+
return AnimationUtils.absoluteTransform(node, pos: node.place, view: view)
66
}
77

8-
class func absoluteTransform(_ node: Node, pos: Transform) -> Transform {
8+
class func absoluteTransform(_ node: Node, pos: Transform, view: MacawView? = nil) -> Transform {
99
var transform = pos
1010
var parent = nodesMap.parents(node).first
1111
while parent != .none {

Source/animation/types/ShapeAnimation.swift

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,7 @@ class ShapeAnimation: AnimationImpl<Shape> {
1111

1212
let interpolationFunc = { (t: Double) -> Shape in
1313
if t == 0 {
14-
return Shape(form: animatedNode.form,
15-
fill: animatedNode.fill,
16-
stroke: animatedNode.stroke,
17-
place: animatedNode.place,
18-
opaque: animatedNode.opaque,
19-
opacity: animatedNode.opacity,
20-
clip: animatedNode.clip,
21-
effect: animatedNode.effect,
22-
visible: animatedNode.visible,
23-
tag: animatedNode.tag)
14+
return animatedNode
2415
}
2516

2617
return finalValue

Source/animation/types/animation_generators/ShapeAnimationGenerator.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func addShapeAnimation(_ animation: BasicAnimation, sceneLayer: CALayer, animati
3737

3838
// Creating proper animation
3939
let generatedAnim = generateShapeAnimation(
40-
from: fromShape,
40+
from: mutatingShape,
4141
to: toShape,
4242
duration: duration,
4343
renderTransform: layer.renderTransform!)
@@ -78,6 +78,12 @@ func addShapeAnimation(_ animation: BasicAnimation, sceneLayer: CALayer, animati
7878

7979
if !animation.autoreverses {
8080
let currentShape = shapeAnimation.getVFunc()(t)
81+
mutatingShape.place = currentShape.place
82+
mutatingShape.opaque = currentShape.opaque
83+
mutatingShape.opacity = currentShape.opacity
84+
mutatingShape.clip = currentShape.clip
85+
mutatingShape.mask = currentShape.mask
86+
mutatingShape.effect = currentShape.effect
8187
mutatingShape.form = currentShape.form
8288
mutatingShape.stroke = currentShape.stroke
8389
mutatingShape.fill = currentShape.fill
@@ -137,6 +143,15 @@ fileprivate func generateShapeAnimation(from: Shape, to: Shape, duration: Double
137143

138144
group.animations = [pathAnimation]
139145

146+
// Transform
147+
let scaleAnimation = CABasicAnimation(keyPath: "transform")
148+
scaleAnimation.duration = duration
149+
let view = nodesMap.getView(from)
150+
scaleAnimation.fromValue = CATransform3DMakeAffineTransform(AnimationUtils.absolutePosition(from, view: view).toCG())
151+
scaleAnimation.toValue = CATransform3DMakeAffineTransform(AnimationUtils.absolutePosition(to, view: view).toCG())
152+
153+
group.animations?.append(scaleAnimation)
154+
140155
// Fill
141156
let fromFillColor = from.fill as? Color ?? Color.clear
142157
let toFillColor = to.fill as? Color ?? Color.clear

Source/animation/types/animation_generators/TransformGenerator.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ func transformAnimationByFunc(_ node: Node, valueFunc: (Double) -> Transform, du
102102
}
103103

104104
timeValues.append(dt)
105-
let value = AnimationUtils.absoluteTransform(node, pos: valueFunc(offset + dt))
105+
106+
let view = nodesMap.getView(node)
107+
let value = AnimationUtils.absoluteTransform(node, pos: valueFunc(offset + dt), view: view)
106108
let cgValue = CATransform3DMakeAffineTransform(value.toCG())
107109
transformValues.append(cgValue)
108110
}

Source/model/scene/Group.swift

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ open class Group: Node {
3131
tag: tag
3232
)
3333

34+
self.contents = contents
3435
self.contentsVar.node = self
3536
}
3637

@@ -64,17 +65,7 @@ open class Group: Node {
6465
}
6566

6667
override open var bounds: Rect? {
67-
var union: Rect?
68-
69-
contents.forEach { node in
70-
guard let nodeBounds = node.bounds?.applying(node.place) else {
71-
return
72-
}
73-
74-
union = union?.union(rect: nodeBounds) ?? nodeBounds
75-
}
76-
77-
return union
68+
return BoundsUtils.getNodesBounds(contents)
7869
}
7970

8071
override func shouldCheckForPressed() -> Bool {

Source/utils/BoundsUtils.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,15 @@ final internal class BoundsUtils {
4141
return CGRect(x: destX, y: destY, width: newSize.w, height: newSize.h)
4242
}
4343
}
44+
45+
class func getNodesBounds(_ nodes: [Node]) -> Rect? {
46+
var union: Rect?
47+
nodes.forEach { node in
48+
guard let nodeBounds = node.bounds?.applying(node.place) else {
49+
return
50+
}
51+
union = union?.union(rect: nodeBounds) ?? nodeBounds
52+
}
53+
return union
54+
}
4455
}

Source/views/MacawView.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -592,12 +592,21 @@ private class LayoutHelper {
592592

593593
public func getTransform(_ node: Node, _ layout: ContentLayout, _ size: Size) -> CGAffineTransform {
594594
setSize(size: size)
595-
if let rect = getNodeBounds(node: node) {
595+
var rect = node.bounds
596+
if let canvas = node as? SVGCanvas {
597+
if let view = nodesMap.getView(canvas) {
598+
rect = canvas.layout(size: view.bounds.size.toMacaw()).rect()
599+
} else {
600+
rect = BoundsUtils.getNodesBounds(canvas.contents)
601+
}
602+
}
603+
604+
if let rect = rect {
596605
setRect(rect: rect)
597606
if let transform = prevTransform {
598607
return transform
599608
}
600-
return setTransform(transform: layout.layout(rect: prevRect!, into: size).toCG())
609+
return setTransform(transform: layout.layout(rect: prevRect!, into: size).move(dx: rect.x, dy: rect.y).toCG())
601610
}
602611
return CGAffineTransform.identity
603612
}

0 commit comments

Comments
 (0)