chore(onboarding): Improve airplane movement add clouds movement
This commit is contained in:
parent
6d241495a2
commit
0675bdb7db
|
@ -12,168 +12,179 @@ import MastodonUI
|
|||
import MastodonLocalization
|
||||
|
||||
fileprivate extension CGFloat {
|
||||
static let centerHillStartPosition = 20.0
|
||||
static let airplaneStartPosition = -178.0
|
||||
static let leftHillStartPosition = 30.0
|
||||
static let rightHillStartPosition = -161.0
|
||||
|
||||
static let airplaneSpeed = 50.0
|
||||
static let leftHillSpeed = 20.0
|
||||
static let centerHillSpeed = 40.0
|
||||
static let rightHillSpeed = 20.0
|
||||
static let cloudsStartPosition = 0.0
|
||||
static let centerHillStartPosition = 20.0
|
||||
static let airplaneStartPosition = -178.0
|
||||
static let leftHillStartPosition = 30.0
|
||||
static let rightHillStartPosition = -161.0
|
||||
static let leftHillSpeed = 20.0
|
||||
static let centerHillSpeed = 40.0
|
||||
static let rightHillSpeed = 20.0
|
||||
}
|
||||
|
||||
final class WelcomeIllustrationView: UIView {
|
||||
|
||||
private let cloudBaseImage = Asset.Scene.Welcome.Illustration.cloudBase.image
|
||||
private let cloudBaseExtendImage = Asset.Scene.Welcome.Illustration.cloudBaseExtend.image
|
||||
private let elephantThreeOnGrassWithTreeTwoImage = Asset.Scene.Welcome.Illustration.elephantThreeOnGrassWithTreeTwo.image
|
||||
private let elephantThreeOnGrassWithTreeThreeImage = Asset.Scene.Welcome.Illustration.elephantThreeOnGrassWithTreeThree.image
|
||||
private let elephantThreeOnGrassImage = Asset.Scene.Welcome.Illustration.elephantThreeOnGrass.image
|
||||
private let elephantThreeOnGrassExtendImage = Asset.Scene.Welcome.Illustration.elephantThreeOnGrassExtend.image
|
||||
private let cloudBaseImage = Asset.Scene.Welcome.Illustration.cloudBase.image
|
||||
private let cloudBaseExtendImage = Asset.Scene.Welcome.Illustration.cloudBaseExtend.image
|
||||
private let elephantThreeOnGrassWithTreeTwoImage = Asset.Scene.Welcome.Illustration.elephantThreeOnGrassWithTreeTwo.image
|
||||
private let elephantThreeOnGrassWithTreeThreeImage = Asset.Scene.Welcome.Illustration.elephantThreeOnGrassWithTreeThree.image
|
||||
private let elephantThreeOnGrassImage = Asset.Scene.Welcome.Illustration.elephantThreeOnGrass.image
|
||||
private let elephantThreeOnGrassExtendImage = Asset.Scene.Welcome.Illustration.elephantThreeOnGrassExtend.image
|
||||
|
||||
var elephantOnAirplaneLeftConstraint: NSLayoutConstraint?
|
||||
var leftHillLeftConstraint: NSLayoutConstraint?
|
||||
var centerHillLeftConstraint: NSLayoutConstraint?
|
||||
var rightHillRightConstraint: NSLayoutConstraint?
|
||||
var cloudsLeftAnchor: NSLayoutConstraint?
|
||||
var elephantOnAirplaneLeftConstraint: NSLayoutConstraint?
|
||||
var leftHillLeftConstraint: NSLayoutConstraint?
|
||||
var centerHillLeftConstraint: NSLayoutConstraint?
|
||||
var rightHillRightConstraint: NSLayoutConstraint?
|
||||
|
||||
let elephantOnAirplaneWithContrailImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: Asset.Scene.Welcome.Illustration.elephantOnAirplaneWithContrail.image)
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.contentMode = .scaleAspectFill
|
||||
return imageView
|
||||
}()
|
||||
let elephantOnAirplaneWithContrailImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: Asset.Scene.Welcome.Illustration.elephantOnAirplaneWithContrail.image)
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.contentMode = .scaleAspectFill
|
||||
return imageView
|
||||
}()
|
||||
|
||||
let rightHillImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: Asset.Scene.Welcome.Illustration.elephantThreeOnGrassWithTreeTwo.image)
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.contentMode = .scaleAspectFill
|
||||
return imageView
|
||||
}()
|
||||
let rightHillImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: Asset.Scene.Welcome.Illustration.elephantThreeOnGrassWithTreeTwo.image)
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.contentMode = .scaleAspectFill
|
||||
return imageView
|
||||
}()
|
||||
|
||||
let leftHillImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: Asset.Scene.Welcome.Illustration.elephantThreeOnGrassWithTreeThree.image)
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.contentMode = .scaleAspectFill
|
||||
return imageView
|
||||
}()
|
||||
let leftHillImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: Asset.Scene.Welcome.Illustration.elephantThreeOnGrassWithTreeThree.image)
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.contentMode = .scaleAspectFill
|
||||
return imageView
|
||||
}()
|
||||
|
||||
let centerHillImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: Asset.Scene.Welcome.Illustration.elephantThreeOnGrass.image)
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.contentMode = .scaleAspectFill
|
||||
return imageView
|
||||
}()
|
||||
let centerHillImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: Asset.Scene.Welcome.Illustration.elephantThreeOnGrass.image)
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.contentMode = .scaleAspectFill
|
||||
return imageView
|
||||
}()
|
||||
|
||||
let cloudBaseImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: Asset.Scene.Welcome.Illustration.cloudBase.image)
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.contentMode = .scaleAspectFit
|
||||
imageView.alpha = 0.3
|
||||
return imageView
|
||||
}()
|
||||
let cloudBaseImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: Asset.Scene.Welcome.Illustration.cloudBase.image)
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
imageView.contentMode = .scaleAspectFill
|
||||
imageView.alpha = 0.3
|
||||
return imageView
|
||||
}()
|
||||
|
||||
var aspectLayoutConstraint: NSLayoutConstraint!
|
||||
var aspectLayoutConstraint: NSLayoutConstraint!
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
_init()
|
||||
}
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
_init()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
_init()
|
||||
}
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
_init()
|
||||
}
|
||||
|
||||
// modifiers for animations
|
||||
private lazy var cloudsDrag: CGFloat = -(bounds.width / 64)
|
||||
private lazy var airplaneDrag: CGFloat = bounds.width / 64
|
||||
}
|
||||
|
||||
extension WelcomeIllustrationView {
|
||||
|
||||
private func _init() {
|
||||
backgroundColor = Asset.Scene.Welcome.Illustration.backgroundCyan.color
|
||||
private func _init() {
|
||||
backgroundColor = Asset.Scene.Welcome.Illustration.backgroundCyan.color
|
||||
|
||||
cloudBaseImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(cloudBaseImageView)
|
||||
NSLayoutConstraint.activate([
|
||||
cloudBaseImageView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
cloudBaseImageView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
cloudBaseImageView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||
cloudBaseImageView.topAnchor.constraint(equalTo: topAnchor)
|
||||
])
|
||||
cloudBaseImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(cloudBaseImageView)
|
||||
|
||||
let rightHillRightConstraint = rightAnchor.constraint(equalTo: rightHillImageView.rightAnchor, constant: .rightHillStartPosition)
|
||||
addSubview(rightHillImageView)
|
||||
NSLayoutConstraint.activate([
|
||||
rightHillImageView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.64),
|
||||
rightHillRightConstraint,
|
||||
bottomAnchor.constraint(equalTo: rightHillImageView.bottomAnchor, constant: 149),
|
||||
])
|
||||
self.rightHillRightConstraint = rightHillRightConstraint
|
||||
let cloudsLeftAnchor = cloudBaseImageView.leftAnchor.constraint(equalTo: leftAnchor, constant: .cloudsStartPosition)
|
||||
NSLayoutConstraint.activate([
|
||||
cloudsLeftAnchor,
|
||||
cloudBaseImageView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 1.4),
|
||||
cloudBaseImageView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||
cloudBaseImageView.topAnchor.constraint(equalTo: topAnchor)
|
||||
])
|
||||
self.cloudsLeftAnchor = cloudsLeftAnchor
|
||||
|
||||
let leftHillLeftConstraint = leftAnchor.constraint(equalTo: leftHillImageView.leftAnchor, constant: .leftHillStartPosition)
|
||||
addSubview(leftHillImageView)
|
||||
NSLayoutConstraint.activate([
|
||||
leftHillImageView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.72),
|
||||
leftHillLeftConstraint,
|
||||
bottomAnchor.constraint(equalTo: leftHillImageView.bottomAnchor, constant: 187),
|
||||
])
|
||||
let rightHillRightConstraint = rightAnchor.constraint(equalTo: rightHillImageView.rightAnchor, constant: .rightHillStartPosition)
|
||||
addSubview(rightHillImageView)
|
||||
NSLayoutConstraint.activate([
|
||||
rightHillImageView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.64),
|
||||
rightHillRightConstraint,
|
||||
bottomAnchor.constraint(equalTo: rightHillImageView.bottomAnchor, constant: 149),
|
||||
])
|
||||
self.rightHillRightConstraint = rightHillRightConstraint
|
||||
|
||||
self.leftHillLeftConstraint = leftHillLeftConstraint
|
||||
let leftHillLeftConstraint = leftAnchor.constraint(equalTo: leftHillImageView.leftAnchor, constant: .leftHillStartPosition)
|
||||
addSubview(leftHillImageView)
|
||||
NSLayoutConstraint.activate([
|
||||
leftHillImageView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.72),
|
||||
leftHillLeftConstraint,
|
||||
bottomAnchor.constraint(equalTo: leftHillImageView.bottomAnchor, constant: 187),
|
||||
])
|
||||
|
||||
let centerHillLeftConstraint = leftAnchor.constraint(equalTo: centerHillImageView.leftAnchor, constant: .centerHillStartPosition)
|
||||
self.leftHillLeftConstraint = leftHillLeftConstraint
|
||||
|
||||
addSubview(centerHillImageView)
|
||||
NSLayoutConstraint.activate([
|
||||
centerHillLeftConstraint,
|
||||
bottomAnchor.constraint(equalTo: centerHillImageView.bottomAnchor, constant: -18),
|
||||
centerHillImageView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 1.2),
|
||||
])
|
||||
let centerHillLeftConstraint = leftAnchor.constraint(equalTo: centerHillImageView.leftAnchor, constant: .centerHillStartPosition)
|
||||
|
||||
self.centerHillLeftConstraint = centerHillLeftConstraint
|
||||
addSubview(centerHillImageView)
|
||||
NSLayoutConstraint.activate([
|
||||
centerHillLeftConstraint,
|
||||
bottomAnchor.constraint(equalTo: centerHillImageView.bottomAnchor, constant: -18),
|
||||
centerHillImageView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 1.2),
|
||||
])
|
||||
|
||||
addSubview(elephantOnAirplaneWithContrailImageView)
|
||||
self.centerHillLeftConstraint = centerHillLeftConstraint
|
||||
|
||||
let elephantOnAirplaneLeftConstraint = elephantOnAirplaneWithContrailImageView.leftAnchor.constraint(equalTo: leftAnchor, constant: .airplaneStartPosition) // add 12pt bleeding
|
||||
NSLayoutConstraint.activate([
|
||||
elephantOnAirplaneLeftConstraint,
|
||||
elephantOnAirplaneWithContrailImageView.bottomAnchor.constraint(equalTo: leftHillImageView.topAnchor),
|
||||
// make a little bit large
|
||||
elephantOnAirplaneWithContrailImageView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.84),
|
||||
])
|
||||
addSubview(elephantOnAirplaneWithContrailImageView)
|
||||
|
||||
self.elephantOnAirplaneLeftConstraint = elephantOnAirplaneLeftConstraint
|
||||
}
|
||||
let elephantOnAirplaneLeftConstraint = elephantOnAirplaneWithContrailImageView.leftAnchor.constraint(equalTo: leftAnchor, constant: .airplaneStartPosition) // add 12pt bleeding
|
||||
NSLayoutConstraint.activate([
|
||||
elephantOnAirplaneLeftConstraint,
|
||||
elephantOnAirplaneWithContrailImageView.bottomAnchor.constraint(equalTo: leftHillImageView.topAnchor),
|
||||
// make a little bit large
|
||||
elephantOnAirplaneWithContrailImageView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.84),
|
||||
])
|
||||
|
||||
func setup() {
|
||||
|
||||
// set illustration
|
||||
guard superview == nil else {
|
||||
return
|
||||
self.elephantOnAirplaneLeftConstraint = elephantOnAirplaneLeftConstraint
|
||||
}
|
||||
contentMode = .scaleAspectFit
|
||||
|
||||
cloudBaseImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -5, maxX: 5, minY: -5, maxY: 5)
|
||||
)
|
||||
rightHillImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -15, maxX: 25, minY: -10, maxY: 10)
|
||||
)
|
||||
leftHillImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -25, maxX: 15, minY: -15, maxY: 15)
|
||||
)
|
||||
centerHillImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -14, maxX: 14, minY: -5, maxY: 25)
|
||||
)
|
||||
func setup() {
|
||||
|
||||
elephantOnAirplaneWithContrailImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -20, maxX: 12, minY: -20, maxY: 12) // maxX should not larger then the bleeding (12pt)
|
||||
)
|
||||
}
|
||||
// set illustration
|
||||
guard superview == nil else {
|
||||
return
|
||||
}
|
||||
contentMode = .scaleAspectFit
|
||||
|
||||
func update(contentOffset: CGFloat) {
|
||||
elephantOnAirplaneLeftConstraint?.constant = contentOffset / .airplaneSpeed + .airplaneStartPosition
|
||||
leftHillLeftConstraint?.constant = contentOffset / .leftHillSpeed + .leftHillStartPosition
|
||||
centerHillLeftConstraint?.constant = contentOffset / .centerHillSpeed + .centerHillStartPosition
|
||||
rightHillRightConstraint?.constant = contentOffset / .rightHillSpeed + .rightHillStartPosition
|
||||
}
|
||||
cloudBaseImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -5, maxX: 5, minY: -5, maxY: 5)
|
||||
)
|
||||
rightHillImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -15, maxX: 25, minY: -10, maxY: 10)
|
||||
)
|
||||
leftHillImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -25, maxX: 15, minY: -15, maxY: 15)
|
||||
)
|
||||
centerHillImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -14, maxX: 14, minY: -5, maxY: 25)
|
||||
)
|
||||
|
||||
elephantOnAirplaneWithContrailImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -20, maxX: 12, minY: -20, maxY: 12) // maxX should not larger then the bleeding (12pt)
|
||||
)
|
||||
}
|
||||
|
||||
func update(contentOffset: CGFloat) {
|
||||
cloudsLeftAnchor?.constant = {
|
||||
let val = contentOffset / cloudsDrag + .cloudsStartPosition
|
||||
print(val)
|
||||
return val
|
||||
}()
|
||||
elephantOnAirplaneLeftConstraint?.constant = contentOffset / airplaneDrag + .airplaneStartPosition
|
||||
leftHillLeftConstraint?.constant = contentOffset / .leftHillSpeed + .leftHillStartPosition
|
||||
centerHillLeftConstraint?.constant = contentOffset / .centerHillSpeed + .centerHillStartPosition
|
||||
rightHillRightConstraint?.constant = contentOffset / .rightHillSpeed + .rightHillStartPosition
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue