mirror of
https://github.com/mastodon/mastodon-ios.git
synced 2025-01-26 15:24:54 +01:00
feat: add motion effect for welcome illustration elements
This commit is contained in:
parent
daba138c0e
commit
fc9310de20
@ -38,7 +38,7 @@
|
||||
2D38F20825CD491300561493 /* DisposeBagCollectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F20725CD491300561493 /* DisposeBagCollectable.swift */; };
|
||||
2D3F9E0425DFA133004262D9 /* UITapGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D3F9E0325DFA133004262D9 /* UITapGestureRecognizer.swift */; };
|
||||
2D42FF6125C8177C004A627A /* ActiveLabel in Frameworks */ = {isa = PBXBuildFile; productRef = 2D42FF6025C8177C004A627A /* ActiveLabel */; };
|
||||
2D42FF6B25C817D2004A627A /* MastodonContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D42FF6A25C817D2004A627A /* MastodonContent.swift */; };
|
||||
2D42FF6B25C817D2004A627A /* TootContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D42FF6A25C817D2004A627A /* TootContent.swift */; };
|
||||
2D42FF7E25C82218004A627A /* ActionToolBarContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D42FF7D25C82218004A627A /* ActionToolBarContainer.swift */; };
|
||||
2D42FF8525C8224F004A627A /* HitTestExpandedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D42FF8425C8224F004A627A /* HitTestExpandedButton.swift */; };
|
||||
2D42FF8F25C8228A004A627A /* UIButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D42FF8E25C8228A004A627A /* UIButton.swift */; };
|
||||
@ -160,6 +160,7 @@
|
||||
DB9D6C2425E502C60051B173 /* MosaicImageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6C2225E502C60051B173 /* MosaicImageViewModel.swift */; };
|
||||
DB9D6C2E25E504AC0051B173 /* Attachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6C2D25E504AC0051B173 /* Attachment.swift */; };
|
||||
DB9D6C3825E508BE0051B173 /* Attachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6C3725E508BE0051B173 /* Attachment.swift */; };
|
||||
DB9E0D6F25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9E0D6E25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift */; };
|
||||
DBABE3EC25ECAC4B00879EE5 /* WelcomeIllustrationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBABE3EB25ECAC4B00879EE5 /* WelcomeIllustrationView.swift */; };
|
||||
DBD9149025DF6D8D00903DFD /* APIService+Onboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBD9148F25DF6D8D00903DFD /* APIService+Onboarding.swift */; };
|
||||
DBE0821525CD382600FD6BBD /* MastodonRegisterViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE0821425CD382600FD6BBD /* MastodonRegisterViewController.swift */; };
|
||||
@ -248,7 +249,7 @@
|
||||
2D38F1FD25CD481700561493 /* StatusProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusProvider.swift; sourceTree = "<group>"; };
|
||||
2D38F20725CD491300561493 /* DisposeBagCollectable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisposeBagCollectable.swift; sourceTree = "<group>"; };
|
||||
2D3F9E0325DFA133004262D9 /* UITapGestureRecognizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITapGestureRecognizer.swift; sourceTree = "<group>"; };
|
||||
2D42FF6A25C817D2004A627A /* MastodonContent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MastodonContent.swift; sourceTree = "<group>"; };
|
||||
2D42FF6A25C817D2004A627A /* TootContent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TootContent.swift; sourceTree = "<group>"; };
|
||||
2D42FF7D25C82218004A627A /* ActionToolBarContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionToolBarContainer.swift; sourceTree = "<group>"; };
|
||||
2D42FF8425C8224F004A627A /* HitTestExpandedButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HitTestExpandedButton.swift; sourceTree = "<group>"; };
|
||||
2D42FF8E25C8228A004A627A /* UIButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIButton.swift; sourceTree = "<group>"; };
|
||||
@ -380,6 +381,7 @@
|
||||
DB9D6C2225E502C60051B173 /* MosaicImageViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MosaicImageViewModel.swift; sourceTree = "<group>"; };
|
||||
DB9D6C2D25E504AC0051B173 /* Attachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Attachment.swift; sourceTree = "<group>"; };
|
||||
DB9D6C3725E508BE0051B173 /* Attachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Attachment.swift; sourceTree = "<group>"; };
|
||||
DB9E0D6E25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIInterpolatingMotionEffect.swift; sourceTree = "<group>"; };
|
||||
DBABE3EB25ECAC4B00879EE5 /* WelcomeIllustrationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeIllustrationView.swift; sourceTree = "<group>"; };
|
||||
DBD9148F25DF6D8D00903DFD /* APIService+Onboarding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Onboarding.swift"; sourceTree = "<group>"; };
|
||||
DBE0821425CD382600FD6BBD /* MastodonRegisterViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonRegisterViewController.swift; sourceTree = "<group>"; };
|
||||
@ -801,6 +803,7 @@
|
||||
2D61335525C1886800CAE157 /* Service */,
|
||||
DB8AF55525C1379F002E6C99 /* Scene */,
|
||||
DB8AF54125C13647002E6C99 /* Coordinator */,
|
||||
DB9E0D6925EDFFE500CFDD76 /* Helper */,
|
||||
DB8AF56225C138BC002E6C99 /* Extension */,
|
||||
2D5A3D0125CF8640002347D6 /* Vender */,
|
||||
DB5086CB25CC0DB400C2C187 /* Preference */,
|
||||
@ -1000,22 +1003,22 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DB084B5125CBC56300F898ED /* CoreDataStack */,
|
||||
DB0140CE25C42AEE00F9F3CF /* OSLog.swift */,
|
||||
2D3F9E0325DFA133004262D9 /* UITapGestureRecognizer.swift */,
|
||||
DB8AF55C25C138B7002E6C99 /* UIViewController.swift */,
|
||||
2D46975D25C2A54100CF4AA9 /* NSLayoutConstraint.swift */,
|
||||
2D46976325C2A71500CF4AA9 /* UIIamge.swift */,
|
||||
DB9E0D6425EDFF5600CFDD76 /* MastodonSDK */,
|
||||
2DF123A625C3B0210020F248 /* ActiveLabel.swift */,
|
||||
2D46975D25C2A54100CF4AA9 /* NSLayoutConstraint.swift */,
|
||||
DB68586325E619B700F0A850 /* NSKeyValueObservation.swift */,
|
||||
2D42FF6A25C817D2004A627A /* MastodonContent.swift */,
|
||||
2D939AB425EDD8A90076FA61 /* String.swift */,
|
||||
DB0140CE25C42AEE00F9F3CF /* OSLog.swift */,
|
||||
DB68A06225E905E000CFDF14 /* UIApplication.swift */,
|
||||
DB45FAB525CA5485005A8AC7 /* UIAlertController.swift */,
|
||||
2D42FF8E25C8228A004A627A /* UIButton.swift */,
|
||||
DB45FAD625CA6C76005A8AC7 /* UIBarButtonItem.swift */,
|
||||
2D32EAB925CB9B0500C9ED86 /* UIView.swift */,
|
||||
0FAA101B25E10E760017CCDE /* UIFont.swift */,
|
||||
2D650FAA25ECDC9300851B58 /* Mastodon+Entidy+ErrorDetailReason.swift */,
|
||||
2D939AB425EDD8A90076FA61 /* String.swift */,
|
||||
2D46976325C2A71500CF4AA9 /* UIIamge.swift */,
|
||||
2D32EAB925CB9B0500C9ED86 /* UIView.swift */,
|
||||
DB8AF55C25C138B7002E6C99 /* UIViewController.swift */,
|
||||
2D3F9E0325DFA133004262D9 /* UITapGestureRecognizer.swift */,
|
||||
DB9E0D6E25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift */,
|
||||
);
|
||||
path = Extension;
|
||||
sourceTree = "<group>";
|
||||
@ -1078,6 +1081,22 @@
|
||||
path = ViewModel;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DB9E0D6425EDFF5600CFDD76 /* MastodonSDK */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2D650FAA25ECDC9300851B58 /* Mastodon+Entidy+ErrorDetailReason.swift */,
|
||||
);
|
||||
path = MastodonSDK;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DB9E0D6925EDFFE500CFDD76 /* Helper */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2D42FF6A25C817D2004A627A /* TootContent.swift */,
|
||||
);
|
||||
path = Helper;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DBABE3F125ECAC4E00879EE5 /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1486,6 +1505,7 @@
|
||||
2D38F1EB25CD477000561493 /* HomeTimelineViewModel+LoadLatestState.swift in Sources */,
|
||||
DBD9149025DF6D8D00903DFD /* APIService+Onboarding.swift in Sources */,
|
||||
DB98337F25C9452D00AD9700 /* APIService+APIError.swift in Sources */,
|
||||
DB9E0D6F25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift in Sources */,
|
||||
2DF123A725C3B0210020F248 /* ActiveLabel.swift in Sources */,
|
||||
DBE0822425CD3F1E00FD6BBD /* MastodonRegisterViewModel.swift in Sources */,
|
||||
2DF75B9B25D0E27500694EC8 /* StatusProviderFacade.swift in Sources */,
|
||||
@ -1540,7 +1560,7 @@
|
||||
2D76317D25C14DF500929FB9 /* PublicTimelineViewController+StatusProvider.swift in Sources */,
|
||||
2D5A3D2825CF8BC9002347D6 /* HomeTimelineViewModel+Diffable.swift in Sources */,
|
||||
DB98339C25C96DE600AD9700 /* APIService+Account.swift in Sources */,
|
||||
2D42FF6B25C817D2004A627A /* MastodonContent.swift in Sources */,
|
||||
2D42FF6B25C817D2004A627A /* TootContent.swift in Sources */,
|
||||
2DF75BA725D10E1000694EC8 /* APIService+Favorite.swift in Sources */,
|
||||
DB9D6C3825E508BE0051B173 /* Attachment.swift in Sources */,
|
||||
DB8AF52E25C13561002E6C99 /* ViewStateStore.swift in Sources */,
|
||||
|
@ -17,12 +17,12 @@
|
||||
<key>Mastodon - Release.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>1</integer>
|
||||
<integer>3</integer>
|
||||
</dict>
|
||||
<key>Mastodon.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>0</integer>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
|
@ -4,6 +4,7 @@
|
||||
//
|
||||
// Created by sxiaojian on 2021/3/1.
|
||||
//
|
||||
|
||||
import MastodonSDK
|
||||
|
||||
extension Mastodon.Entity.ErrorDetailReason {
|
30
Mastodon/Extension/UIInterpolatingMotionEffect.swift
Normal file
30
Mastodon/Extension/UIInterpolatingMotionEffect.swift
Normal file
@ -0,0 +1,30 @@
|
||||
//
|
||||
// UIInterpolatingMotionEffect.swift
|
||||
// Mastodon
|
||||
//
|
||||
// Created by MainasuK Cirno on 2021-3-2.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
extension UIInterpolatingMotionEffect {
|
||||
static func motionEffect(
|
||||
minX: CGFloat,
|
||||
maxX: CGFloat,
|
||||
minY: CGFloat,
|
||||
maxY: CGFloat
|
||||
) -> UIMotionEffectGroup {
|
||||
let motionEffectX = UIInterpolatingMotionEffect(keyPath: "layer.transform.translation.x", type: .tiltAlongHorizontalAxis)
|
||||
motionEffectX.minimumRelativeValue = minX
|
||||
motionEffectX.maximumRelativeValue = maxX
|
||||
|
||||
let motionEffectY = UIInterpolatingMotionEffect(keyPath: "layer.transform.translation.y", type: .tiltAlongVerticalAxis)
|
||||
motionEffectY.minimumRelativeValue = minY
|
||||
motionEffectY.maximumRelativeValue = maxY
|
||||
|
||||
let motionEffectGroup = UIMotionEffectGroup()
|
||||
motionEffectGroup.motionEffects = [motionEffectX, motionEffectY]
|
||||
|
||||
return motionEffectGroup
|
||||
}
|
||||
}
|
@ -84,6 +84,7 @@ internal enum Asset {
|
||||
}
|
||||
internal static let mastodonLogo = ImageAsset(name: "Welcome/mastodon.logo")
|
||||
internal static let mastodonLogoLarge = ImageAsset(name: "Welcome/mastodon.logo.large")
|
||||
internal static let welcomeLogo = ImageAsset(name: "Welcome/welcome.logo")
|
||||
}
|
||||
}
|
||||
// swiftlint:enable identifier_name line_length nesting type_body_length type_name
|
||||
|
@ -1,5 +1,5 @@
|
||||
//
|
||||
// MastodonContent.swift
|
||||
// TootContent.swift
|
||||
// Mastodon
|
||||
//
|
||||
// Created by MainasuK Cirno on 2021/2/1.
|
@ -10,7 +10,13 @@ import UIKit
|
||||
final class WelcomeIllustrationView: UIView {
|
||||
|
||||
static let artworkImageSize = CGSize(width: 870, height: 2000)
|
||||
let artworkImageView = UIImageView()
|
||||
|
||||
let cloudBaseImageView = UIImageView()
|
||||
let rightHillImageView = UIImageView()
|
||||
let leftHillImageView = UIImageView()
|
||||
let centerHillImageView = UIImageView()
|
||||
let lineDashTwoImageView = UIImageView()
|
||||
let elephantTwoImageView = UIImageView()
|
||||
|
||||
// layout outside
|
||||
let elephantOnAirplaneWithContrailImageView: UIImageView = {
|
||||
@ -47,6 +53,7 @@ final class WelcomeIllustrationView: UIView {
|
||||
}
|
||||
|
||||
extension WelcomeIllustrationView {
|
||||
|
||||
private func _init() {
|
||||
backgroundColor = Asset.Welcome.Illustration.backgroundCyan.color
|
||||
|
||||
@ -60,65 +67,108 @@ extension WelcomeIllustrationView {
|
||||
topPaddingView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
])
|
||||
|
||||
artworkImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(artworkImageView)
|
||||
cloudBaseImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(cloudBaseImageView)
|
||||
NSLayoutConstraint.activate([
|
||||
artworkImageView.topAnchor.constraint(equalTo: topPaddingView.bottomAnchor),
|
||||
artworkImageView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
artworkImageView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
artworkImageView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||
artworkImageView.widthAnchor.constraint(equalTo: artworkImageView.heightAnchor, multiplier: WelcomeIllustrationView.artworkImageSize.width / WelcomeIllustrationView.artworkImageSize.height),
|
||||
cloudBaseImageView.topAnchor.constraint(equalTo: topPaddingView.bottomAnchor),
|
||||
cloudBaseImageView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
cloudBaseImageView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
||||
cloudBaseImageView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||
cloudBaseImageView.widthAnchor.constraint(equalTo: cloudBaseImageView.heightAnchor, multiplier: WelcomeIllustrationView.artworkImageSize.width / WelcomeIllustrationView.artworkImageSize.height),
|
||||
])
|
||||
|
||||
|
||||
[
|
||||
rightHillImageView,
|
||||
leftHillImageView,
|
||||
centerHillImageView,
|
||||
lineDashTwoImageView,
|
||||
elephantTwoImageView,
|
||||
].forEach { imageView in
|
||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(imageView)
|
||||
NSLayoutConstraint.activate([
|
||||
imageView.topAnchor.constraint(equalTo: cloudBaseImageView.topAnchor),
|
||||
imageView.leadingAnchor.constraint(equalTo: cloudBaseImageView.leadingAnchor),
|
||||
imageView.trailingAnchor.constraint(equalTo: cloudBaseImageView.trailingAnchor),
|
||||
imageView.bottomAnchor.constraint(equalTo: cloudBaseImageView.bottomAnchor),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
artworkImageView.image = WelcomeIllustrationView.artworkImage()
|
||||
updateImage()
|
||||
}
|
||||
|
||||
static func artworkImage() -> UIImage {
|
||||
let size = artworkImageSize
|
||||
let width = artworkImageSize.width
|
||||
let height = artworkImageSize.height
|
||||
let image = UIGraphicsImageRenderer(size: size).image { context in
|
||||
private func updateImage() {
|
||||
let size = WelcomeIllustrationView.artworkImageSize
|
||||
let width = size.width
|
||||
let height = size.height
|
||||
|
||||
let elephantFourOnGrassWithTreeTwoImage = Asset.Welcome.Illustration.elephantFourOnGrassWithTreeTwo.image
|
||||
let elephantThreeOnGrassWithTreeFourImage = Asset.Welcome.Illustration.elephantThreeOnGrassWithTreeFour.image
|
||||
let elephantThreeOnGrassImage = Asset.Welcome.Illustration.elephantThreeOnGrass.image
|
||||
let elephantTwoImage = Asset.Welcome.Illustration.elephantTwo.image
|
||||
let lineDashTwoImage = Asset.Welcome.Illustration.lineDashTwo.image
|
||||
|
||||
|
||||
cloudBaseImageView.image = UIGraphicsImageRenderer(size: size).image { context in
|
||||
// clear background
|
||||
UIColor.clear.setFill()
|
||||
context.fill(CGRect(origin: .zero, size: artworkImageSize))
|
||||
context.fill(CGRect(origin: .zero, size: size))
|
||||
|
||||
// draw cloud
|
||||
let cloudBaseImage = Asset.Welcome.Illustration.cloudBase.image
|
||||
cloudBaseImage.draw(at: CGPoint(x: 0, y: height - cloudBaseImage.size.height))
|
||||
|
||||
let elephantFourOnGrassWithTreeTwoImage = Asset.Welcome.Illustration.elephantFourOnGrassWithTreeTwo.image
|
||||
let elephantThreeOnGrassWithTreeFourImage = Asset.Welcome.Illustration.elephantThreeOnGrassWithTreeFour.image
|
||||
let elephantThreeOnGrassImage = Asset.Welcome.Illustration.elephantThreeOnGrass.image
|
||||
let elephantTwoImage = Asset.Welcome.Illustration.elephantTwo.image
|
||||
let lineDashTwoImage = Asset.Welcome.Illustration.lineDashTwo.image
|
||||
|
||||
// let elephantOnAirplaneWithContrailImageView = Asset.Welcome.Illustration.elephantOnAirplaneWithContrail.image
|
||||
|
||||
// draw elephantFourOnGrassWithTreeTwo
|
||||
// elephantFourOnGrassWithTreeTwo.bottomY + 40 align to elephantThreeOnGrassImage.centerY
|
||||
elephantFourOnGrassWithTreeTwoImage.draw(at: CGPoint(x: 0, y: height - 0.5 * elephantThreeOnGrassImage.size.height - elephantFourOnGrassWithTreeTwoImage.size.height - 40))
|
||||
|
||||
}
|
||||
|
||||
rightHillImageView.image = UIGraphicsImageRenderer(size: size).image { context in
|
||||
// clear background
|
||||
UIColor.clear.setFill()
|
||||
context.fill(CGRect(origin: .zero, size: size))
|
||||
|
||||
// draw elephantThreeOnGrassWithTreeFour
|
||||
// elephantThreeOnGrassWithTreeFour.bottomY + 40 align to elephantThreeOnGrassImage.centerY
|
||||
elephantThreeOnGrassWithTreeFourImage.draw(at: CGPoint(x: width - elephantThreeOnGrassWithTreeFourImage.size.width, y: height - 0.5 * elephantThreeOnGrassImage.size.height - elephantThreeOnGrassWithTreeFourImage.size.height - 40))
|
||||
|
||||
// draw elephantThreeOnGrass
|
||||
elephantThreeOnGrassImage.draw(at: CGPoint(x: 0, y: height - elephantThreeOnGrassImage.size.height))
|
||||
|
||||
// darw ineDashTwoImage
|
||||
lineDashTwoImage.draw(at: CGPoint(x: 0.5 * elephantThreeOnGrassImage.size.width + 60, y: height - elephantThreeOnGrassImage.size.height - 50))
|
||||
|
||||
// draw elephantTwo.image
|
||||
elephantTwoImage.draw(at: CGPoint(x: 0, y: height - elephantTwoImage.size.height - 125))
|
||||
|
||||
// draw elephantOnAirplaneWithContrailImageView
|
||||
// elephantOnAirplaneWithContrailImageView.draw(at: CGPoint(x: 0, y: height - cloudBaseImage.size.height - 0.5 * elephantOnAirplaneWithContrailImageView.size.height))
|
||||
}
|
||||
|
||||
return image
|
||||
leftHillImageView.image = UIGraphicsImageRenderer(size: size).image { context in
|
||||
// clear background
|
||||
UIColor.clear.setFill()
|
||||
context.fill(CGRect(origin: .zero, size: size))
|
||||
|
||||
// draw elephantFourOnGrassWithTreeTwo
|
||||
// elephantFourOnGrassWithTreeTwo.bottomY + 40 align to elephantThreeOnGrassImage.centerY
|
||||
elephantFourOnGrassWithTreeTwoImage.draw(at: CGPoint(x: 0, y: height - 0.5 * elephantThreeOnGrassImage.size.height - elephantFourOnGrassWithTreeTwoImage.size.height - 40))
|
||||
}
|
||||
|
||||
centerHillImageView.image = UIGraphicsImageRenderer(size: size).image { context in
|
||||
// clear background
|
||||
UIColor.clear.setFill()
|
||||
context.fill(CGRect(origin: .zero, size: size))
|
||||
|
||||
// draw elephantThreeOnGrass
|
||||
elephantThreeOnGrassImage.draw(at: CGPoint(x: 0, y: height - elephantThreeOnGrassImage.size.height))
|
||||
}
|
||||
|
||||
lineDashTwoImageView.image = UIGraphicsImageRenderer(size: size).image { context in
|
||||
// clear background
|
||||
UIColor.clear.setFill()
|
||||
context.fill(CGRect(origin: .zero, size: size))
|
||||
|
||||
// darw ineDashTwoImage
|
||||
lineDashTwoImage.draw(at: CGPoint(x: 0.5 * elephantThreeOnGrassImage.size.width + 60, y: height - elephantThreeOnGrassImage.size.height - 50))
|
||||
}
|
||||
|
||||
elephantTwoImageView.image = UIGraphicsImageRenderer(size: size).image { context in
|
||||
// clear background
|
||||
UIColor.clear.setFill()
|
||||
context.fill(CGRect(origin: .zero, size: size))
|
||||
|
||||
// draw elephantTwo.image
|
||||
elephantTwoImage.draw(at: CGPoint(x: 0, y: height - elephantTwoImage.size.height - 125))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -75,6 +75,25 @@ extension WelcomeViewController {
|
||||
])
|
||||
view.backgroundColor = .black
|
||||
welcomeIllustrationView.alpha = 0.9
|
||||
|
||||
welcomeIllustrationView.cloudBaseImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -5, maxX: 5, minY: -5, maxY: 5)
|
||||
)
|
||||
welcomeIllustrationView.rightHillImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -12, maxX: 12, minY: -12, maxY: 12)
|
||||
)
|
||||
welcomeIllustrationView.leftHillImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -12, maxX: 12, minY: -20, maxY: 20)
|
||||
)
|
||||
welcomeIllustrationView.centerHillImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -14, maxX: 14, minY: -30, maxY: 30)
|
||||
)
|
||||
welcomeIllustrationView.lineDashTwoImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -25, maxX: 25, minY: -40, maxY: 40)
|
||||
)
|
||||
welcomeIllustrationView.elephantTwoImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -30, maxX: 30, minY: -30, maxY: 30)
|
||||
)
|
||||
}
|
||||
|
||||
view.addSubview(logoImageView)
|
||||
@ -122,12 +141,26 @@ extension WelcomeViewController {
|
||||
welcomeIllustrationView.elephantOnAirplaneWithContrailImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.addSubview(welcomeIllustrationView.elephantOnAirplaneWithContrailImageView)
|
||||
NSLayoutConstraint.activate([
|
||||
welcomeIllustrationView.elephantOnAirplaneWithContrailImageView.leftAnchor.constraint(equalTo: view.leftAnchor),
|
||||
view.leftAnchor.constraint(equalTo: welcomeIllustrationView.elephantOnAirplaneWithContrailImageView.leftAnchor, constant: 12), // add 12pt bleeding
|
||||
welcomeIllustrationView.elephantOnAirplaneWithContrailImageView.bottomAnchor.constraint(equalTo: sloganLabel.topAnchor),
|
||||
// make a little bit large
|
||||
welcomeIllustrationView.elephantOnAirplaneWithContrailImageView.widthAnchor.constraint(equalToConstant: 656 / traitCollection.displayScale * imageSizeScale),
|
||||
welcomeIllustrationView.elephantOnAirplaneWithContrailImageView.heightAnchor.constraint(equalToConstant: 195 / traitCollection.displayScale * imageSizeScale),
|
||||
])
|
||||
|
||||
welcomeIllustrationView.cloudFirstImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -30, maxX: 30, minY: -20, maxY: 10)
|
||||
)
|
||||
welcomeIllustrationView.cloudSecondImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -10, maxX: 30, minY: -8, maxY: 10)
|
||||
)
|
||||
welcomeIllustrationView.cloudThirdImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -20, maxX: 10, minY: -6, maxY: 10)
|
||||
)
|
||||
welcomeIllustrationView.elephantOnAirplaneWithContrailImageView.addMotionEffect(
|
||||
UIInterpolatingMotionEffect.motionEffect(minX: -20, maxX: 12, minY: -20, maxY: 12) // maxX should not larger then the bleeding (12pt)
|
||||
)
|
||||
|
||||
view.bringSubviewToFront(logoImageView)
|
||||
view.bringSubviewToFront(sloganLabel)
|
||||
}
|
||||
|
@ -40,12 +40,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
|
||||
extension AppDelegate {
|
||||
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
|
||||
#if DEBUG
|
||||
return .all
|
||||
#else
|
||||
return UIDevice.current.userInterfaceIdiom == .pad ? .all : .portrait
|
||||
#endif
|
||||
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
|
||||
return UIDevice.current.userInterfaceIdiom == .phone ? .portrait : .all
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user