row*screen.width/2
(square cells). // grid cell (column, row) let streak = Group( contents: [self.streak(text: "MEDIUM", imageName: "medium")], place: Transform.move( dx: Double(screen.width / 2) * column, dy: Double(screen.width / 2) * row ) ) // streak: content + title func streak(text: String, imageName: String) -> Group { let title = Text( text: text, font: Font(name: fontName, size: 14), fill: Color.white, align: .mid, place: Transform.move( dx: Double(screen.width) / 4, dy: 0.7 * Double(screen.width) / 2 ) ) let streakContent = Group() return [streakContent, title].group() }
let ellipse = Ellipse(cx: radius, cy: radius, rx: radius, ry: radius) let border = Shape( form: Arc(ellipse: ellipse, extent: 2 * M_PI), fill: background, stroke: Stroke(fill: Color(val: 0x744641), width: 8) ) let image = UIImage(named: imageName)! let logoImage = Image( src: imageName, place: Transform.move( // move image in the point (radius, radius) dx: radius - Double(image.size.width) / 2, dy: radius - Double(image.size.height) / 2 ) ) let logo = [border, logoImage].group()
// input parameters let x = width / 6 * Double(column) let y = Double(row) * 15 // skip day let line1 = Line(x1: x - 4, y1: y, x2: x + 4, y2: y + 8) let line2 = Line(x1: x - 4, y1: y + 8, x2: x + 4, y2: y) let stroke = Stroke(fill: Color.black, width: 4) let cross = [ Shape(form: line1, stroke: stroke), Shape(form: line2, stroke: stroke) ].group() // done day let done = Shape( form: Circle(cx: x, cy: y + radius, r: radius), fill: doneColor ) // future day let future = Shape( form: Circle(cx: x, cy: y + radius, r: radius), fill: lightColor )
let bar = Group(contents: [ Text( text: "LAST 30 DAYS", font: Font(name: fontName, size: 12), fill: Color.white, align: .min ), Text( text: "42%", font: Font(name: fontName, size: 12), fill: lightColor, align: .max, place: Transform.move(dx: width, dy: 0) ), Shape( form: Rect(x: 0, y: 18, w: width, h: 10).round(r: 2), fill: lightColor ), Shape( form: Rect(x: 0, y: 18, w: width * 0.42, h: 10).round(r: 2), fill: Color.white ) ]
func animateStreak(newContent: Group, margin: Int) { let animation = streakContent.opacityVar.animation(to: 0.0, during: 0.1) animation.onComplete { streakContent.contents = newContent streakContent.place = Transform.move(dx: margin / 2, dy: 0) streakContent.opacityVar.animation(to: 1.0, during: 0.1).play() } animation.play() }
1.5*PI
to 3.5*PI
when creating a new habit. Here we read more about content-animation. At the end of the animation, open the “Add Task” controller. streak.onTap { tapEvent in let animation = group.contentsVar.animation({ t in let animatedShape = Shape( form: Arc(ellipse: ellipse, shift: 1.5 * M_PI, extent: 2 * M_PI * t), stroke: Stroke(fill: Color.white, width: 8) ) return [animatedShape] }, during: 0.5).easing(Easing.easeInOut) animation.onComplete { // open task controller } animation.play() }
screen.width / columns
and the height of screen.height / rows
. let columns = Array(0..<dimension.0).map { column in let x = cell.w * column return Shape( form: Line(x1: x, y1: 0, x2: x, y2: size.h), stroke: stroke, opacity: 0.2 ) }.group() let rows = Array(0..<dimension.1).map { row in let y = cell.h * row return Shape( form: Line(x1: 0, y1: y, x2: size.w, y2: y), stroke: stroke, opacity: row % 4 == 0 ? 1 : 0.2 ) }.group()
let column = floor(tapLocation.x / cellSize.w) let row = floor(tapLocation.y / cellSize.h) let rect = Rect(w: cellSize.w, h: cellSize.h) let background = Shape(form: rect, fill: Color.rgb(r: 4, g: 112, b: 215)) let foreground = Shape(form: rect, fill: Color.white, opacity: 0.0) let sound = Group( contents: [background, foreground], place: Transform.move( dx: column * cellSize.w, dy: row * cellSize.h ) )
0.05
near PI/2
. "Play" consists of three points: (-1, 2), (2, 0), (-1, -2), "Stop" of four: (-2, 2), (2, 2), (2 , -2), (-2, -2). Any element of the scene is easily scaled to the desired size. Vector graphics - power! let border = Shape( form: Arc( ellipse: Ellipse(rx: radius, ry: radius), shift: -M_PI / 2 + 0.05, extent: 2 * M_PI - 0.1 ), stroke: Stroke(fill: Color.rgba(r: 219, g: 222, b: 227, a: 0.3), width: 2.0) ) let circle = Shape(form: Circle(r: 25.0), fill: olor) let playButton = Shape( form: MoveTo(x: -1, y: 2).lineTo(x: 2, y: 0) .lineTo(x: -1, y: -2).close().build(), fill: Color.rgb(r: 46, g: 48, b: 58), place: Transform.scale(sx: 5.0, sy: 5.0) ) let stopButton = Shape( form: MoveTo(x: -2, y: 2).lineTo(x: 2, y: 2) .lineTo(x: 2, y: -2).lineTo(x: -2, y: -2).close().build(), fill: Color.rgb(r: 46, g: 48, b: 58), place: Transform.scale(sx: 4.0, sy: 4.0) ) let buttons = [[playButton], [stopButton]] let buttonGroup = Group(contents: buttons[0]) let button = Group(contents: [border, circle, buttonGroup])
-PI/2+0.05
arc cyclic animation: the length is animated from -PI/2+0.05
to 3*PI/2–0.1
button.onTap { tapEvent in // change button content let index = buttons.index { $0 == buttonGroup.contents }! buttonGroup.contents = buttons[(index + 1) % buttons.count] if index == 0 { play() } else { // if stop pressed contentAnimation.stop() // hide animation group animationGroup.opacityVar.animation(to: 0.0, during: 0.1).play() } } func play() { contentAnimation = animationGroup.contentsVar.animation({ t in let shape = Shape( form: Arc( ellipse: Ellipse(rx: radius, ry: radius), shift: -M_PI / 2 + 0.05, extent: max(2 * M_PI * t - 0.1, 0) ), stroke: Stroke(fill: Color.white, width: 2) ) return [shape] }, during: time).cycle() contentAnimation.play() }
let line = Shape( form: Line(x1: 0, y1: 0, x2: size.w, y2: 0), stroke: Stroke(fill: Color.rgba(r: 219, g: 222, b: 227, a: 0.5), width: 1.0) ) func run(time: Double) { let lineAnimation = line.placeVar.animation( to: Transform.move(dx: 0, dy: screen.height), during: time ).easing(Easing.linear) let hightlight = sounds.map { sound -> Animation in return sound.hightlight().delay(sound.place.dy / screen.height * time) }.combine() let runAnimation = [soundsAnimation, lineAnimation].combine().cycle() runAnimation?.play() }
let mainCircle = Shape( form: Circle(r: 60), fill: mainColor, stroke: Stroke(fill: Color.white, width: 1.0) ) let score = Text( text: "3", font: Font(name: lightFont, size: 40), fill: Color.white, align: .mid, baseline: .mid ) let icon = Text( text: "", font: Font(name: regularFont, size: 24), fill: Color.white, align: .mid, place: Transform.move(dx: 0.0, dy: 30.0) ) let shadows = [ Point(x: 0, y: 35), Point(x: -25, y: 25), Point(x: 25, y: 25), Point(x: 25, y: -25), Point(x: -25, y: -25), Point(x: -40, y: 0), Point(x: 40, y: 0), Point(x: 0, y: -35) ].map { place in return Shape( form: Circle(r: 40), fill: Color.white.with(a: 0.8), place: Transform.move(dx: place.x, dy: place.y) ) }.group() let acivityCircle = Group(contents: [shadows, mainCircle, score, icon])
(cos(alpha) * d, sin(alpha) * d)
. By default, the icon selection menu is hidden (transparency 0.0). let data = ["", "", ""] // emoji let emojis = data.enumerated().map { (index, item) -> Group in let shape = Shape(form: Circle(r: 20), fill: Color.white) let icon = Text( text: item, font: Font(name: regularFont, size: 14), fill: Color.white, align: .mid, baseline: .mid ) return Group( contents: [shape, icon], place: emojiPlace(index: index, d: 20.0), opacity: 0.0 ) }.group() func emojiPlace(index: Int, d: Double) -> Transform { let alpha = 2 * M_PI / 10.0 * Double(index) return Transform.move( dx: cos(alpha) * d, dy: sin(alpha) * d ) }
let border = Shape( form: Rect(w: 80, h: 30).round(r: 16.0), fill: Color.white ) let text = Text( text: "Low", font: Font(name: regularFont, size: 20), fill: mainColor, align: .mid, baseline: .mid, place: Transform.move(dx: 40, dy: 15) ) let line = Shape( form: Rect(x: 20, y: 30, w: 2, h: 40), fill: LinearGradient( degree: 90, from: Color.white.with(a: 0.8), to: mainColor ) ) let legend = [border, text, line].group()
let text = Text( text: text, font: Font(name: regularFont, size: 12), fill: Color.white, align: .min, baseline: .alphabetic, place: Transform.move(dx: 0, dy: -5) ) let rect = Shape( form: Rect(w: width, h: 8), fill: !last ? color : gradient ) let bar = [text, rect].group()
let jumpAnimation = legend.placeVar.animation( to: Transform.move(dx: 0.0, dy: -8.0), during: 2.0 ).autoreversed().cycle()
reverse()
method. let during = 0.5 let hideAnimation = [ bar.opacityVar.animation(to: 0.0, during: during), texts.opacityVar.animation(to: 0.0, during: during) ].combine() let emojisAnimation = emojis.contents.enumerated().map { (index, node) in return [ node.opacityVar.animation(to: 1.0, during: during), node.placeVar.animation( // new emoji position to: emojiPlace(index: index, d: 120.0), during: during ) ].combine() }.combine() let circleAnimation = [ shadows.placeVar.animation(to: Transform.scale(sx: 0.5, sy: 0.5), during: during), score.placeVar.animation(to: Transform.move(dx: 0, dy: -20), during: during), score.opacityVar.animation(to: 0.0, during: during), icon.placeVar.animation(to: Transform.move(dx: 0, dy: -30).scale(sx: 2.0, sy: 2.0), during: during), ].combine() let animation = [hideAnimation, emojisAnimation, circleAnimation].combine() let reverseAnimation = animation.reverse()
Source: https://habr.com/ru/post/323308/
All Articles