mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
WIP
This commit is contained in:
parent
89eb03c241
commit
1725af4c9e
16
submodules/GradientBackground/BUILD
Normal file
16
submodules/GradientBackground/BUILD
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||||
|
|
||||||
|
swift_library(
|
||||||
|
name = "GradientBackground",
|
||||||
|
module_name = "GradientBackground",
|
||||||
|
srcs = glob([
|
||||||
|
"Sources/**/*.swift",
|
||||||
|
]),
|
||||||
|
deps = [
|
||||||
|
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
||||||
|
"//submodules/Display:Display",
|
||||||
|
],
|
||||||
|
visibility = [
|
||||||
|
"//visibility:public",
|
||||||
|
],
|
||||||
|
)
|
265
submodules/GradientBackground/Sources/GradientBackground.swift
Normal file
265
submodules/GradientBackground/Sources/GradientBackground.swift
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import Display
|
||||||
|
import AsyncDisplayKit
|
||||||
|
|
||||||
|
private struct GradientPoint {
|
||||||
|
var color: UIColor
|
||||||
|
var position: CGPoint
|
||||||
|
}
|
||||||
|
|
||||||
|
private func applyTransformerToPoints(step: Int, substep: Int) -> [GradientPoint] {
|
||||||
|
var points: [GradientPoint] = []
|
||||||
|
|
||||||
|
var firstSet: [CGPoint]
|
||||||
|
var secondSet: [CGPoint]
|
||||||
|
|
||||||
|
let colors: [UIColor] = [
|
||||||
|
UIColor(rgb: 0x7FA381),
|
||||||
|
UIColor(rgb: 0xFFF5C5),
|
||||||
|
UIColor(rgb: 0x336F55),
|
||||||
|
UIColor(rgb: 0xFBE37D)
|
||||||
|
]
|
||||||
|
|
||||||
|
let firstStepPoints: [CGPoint] = [
|
||||||
|
CGPoint(x: 0.823, y: 0.086),
|
||||||
|
CGPoint(x: 0.362, y: 0.254),
|
||||||
|
CGPoint(x: 0.184, y: 0.923),
|
||||||
|
CGPoint(x: 0.648, y: 0.759)
|
||||||
|
]
|
||||||
|
|
||||||
|
let nextStepPoints: [CGPoint] = [
|
||||||
|
CGPoint(x: 0.59, y: 0.16),
|
||||||
|
CGPoint(x: 0.28, y: 0.58),
|
||||||
|
CGPoint(x: 0.42, y: 0.83),
|
||||||
|
CGPoint(x: 0.74, y: 0.42)
|
||||||
|
]
|
||||||
|
|
||||||
|
if step % 2 == 0 {
|
||||||
|
firstSet = shiftArray(array: firstStepPoints, offset: step / 2)
|
||||||
|
secondSet = shiftArray(array: nextStepPoints, offset: step / 2)
|
||||||
|
} else {
|
||||||
|
firstSet = shiftArray(array: nextStepPoints, offset: step / 2)
|
||||||
|
secondSet = shiftArray(array: firstStepPoints, offset: step / 2 + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
for index in 0 ..< colors.count {
|
||||||
|
let point = transformPoint(
|
||||||
|
points: (firstSet[index], secondSet[index]),
|
||||||
|
substep: substep
|
||||||
|
)
|
||||||
|
|
||||||
|
points.append(GradientPoint(
|
||||||
|
color: colors[index],
|
||||||
|
position: point
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
return points
|
||||||
|
}
|
||||||
|
|
||||||
|
private func shiftArray(array: [CGPoint], offset: Int) -> [CGPoint] {
|
||||||
|
var newArray = array
|
||||||
|
var offset = offset
|
||||||
|
while offset > 0 {
|
||||||
|
let element = newArray.removeFirst()
|
||||||
|
newArray.append(element)
|
||||||
|
offset -= 1
|
||||||
|
}
|
||||||
|
return newArray
|
||||||
|
}
|
||||||
|
|
||||||
|
private func transformPoint(points: (first: CGPoint, second: CGPoint), substep: Int) -> CGPoint {
|
||||||
|
let delta = CGFloat(substep) / CGFloat(30)
|
||||||
|
let x = points.first.x + (points.second.x - points.first.x) * delta
|
||||||
|
let y = points.first.y + (points.second.y - points.first.y) * delta
|
||||||
|
|
||||||
|
return CGPoint(x: x, y: y)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func generateGradientComponent(size: CGSize, color: UIColor) -> UIImage? {
|
||||||
|
UIGraphicsBeginImageContextWithOptions(size, false, 1.0)
|
||||||
|
|
||||||
|
let c = UIGraphicsGetCurrentContext()
|
||||||
|
|
||||||
|
c?.clear(CGRect(origin: CGPoint.zero, size: size))
|
||||||
|
|
||||||
|
c?.setBlendMode(.normal)
|
||||||
|
|
||||||
|
var gradLocs: [CGFloat] = [0, 0.1, 0.35, 1]
|
||||||
|
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||||
|
let radius = min(size.width / 2.0, size.height / 2.0)
|
||||||
|
|
||||||
|
let colors = [
|
||||||
|
color.cgColor,
|
||||||
|
color.withAlphaComponent(0.8).cgColor,
|
||||||
|
color.withAlphaComponent(0.3).cgColor,
|
||||||
|
color.withAlphaComponent(0).cgColor
|
||||||
|
]
|
||||||
|
|
||||||
|
let grad = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &gradLocs)
|
||||||
|
if let grad = grad {
|
||||||
|
let newPoint = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
|
||||||
|
|
||||||
|
c?.drawRadialGradient(grad, startCenter: newPoint, startRadius: 0, endCenter: newPoint, endRadius: radius, options: [])
|
||||||
|
}
|
||||||
|
|
||||||
|
let image = UIGraphicsGetImageFromCurrentImageContext()
|
||||||
|
UIGraphicsEndImageContext()
|
||||||
|
|
||||||
|
return image
|
||||||
|
}
|
||||||
|
|
||||||
|
private func generateGradient(with size: CGSize, gradPointArray gradPoints: [GradientPoint]) -> UIImage? {
|
||||||
|
UIGraphicsBeginImageContextWithOptions(size, true, 1.0)
|
||||||
|
|
||||||
|
let c = UIGraphicsGetCurrentContext()
|
||||||
|
|
||||||
|
c?.setFillColor(UIColor.white.cgColor)
|
||||||
|
c?.fill(CGRect(origin: CGPoint.zero, size: size))
|
||||||
|
|
||||||
|
c?.setBlendMode(.multiply)
|
||||||
|
|
||||||
|
var gradLocs: [CGFloat] = [0, 0.0, 0.35, 1]
|
||||||
|
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||||
|
let radius = max(size.width, size.height)
|
||||||
|
|
||||||
|
for point in gradPoints {
|
||||||
|
let colors = [
|
||||||
|
point.color.cgColor,
|
||||||
|
point.color.withAlphaComponent(0.8).cgColor,
|
||||||
|
point.color.withAlphaComponent(0.3).cgColor,
|
||||||
|
point.color.withAlphaComponent(0).cgColor
|
||||||
|
]
|
||||||
|
|
||||||
|
let grad = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &gradLocs)
|
||||||
|
if let grad = grad {
|
||||||
|
let newPoint = point.position.applying(
|
||||||
|
.init(scaleX: size.width, y: size.height)
|
||||||
|
)
|
||||||
|
|
||||||
|
c?.drawRadialGradient(grad, startCenter: newPoint, startRadius: 0, endCenter: newPoint, endRadius: radius, options: [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let i = UIGraphicsGetImageFromCurrentImageContext()
|
||||||
|
|
||||||
|
UIGraphicsEndImageContext()
|
||||||
|
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class GradientBackgroundNode: ASDisplayNode {
|
||||||
|
//private let imageView: UIImageView
|
||||||
|
|
||||||
|
private var pointImages: [UIImageView] = []
|
||||||
|
|
||||||
|
private let firstStepPoints: [CGPoint] = [
|
||||||
|
CGPoint(x: 0.823, y: 0.086),
|
||||||
|
CGPoint(x: 0.362, y: 0.254),
|
||||||
|
CGPoint(x: 0.184, y: 0.923),
|
||||||
|
CGPoint(x: 0.648, y: 0.759)
|
||||||
|
]
|
||||||
|
|
||||||
|
private let nextStepPoints: [CGPoint] = [
|
||||||
|
CGPoint(x: 0.59, y: 0.16),
|
||||||
|
CGPoint(x: 0.28, y: 0.58),
|
||||||
|
CGPoint(x: 0.42, y: 0.83),
|
||||||
|
CGPoint(x: 0.74, y: 0.42)
|
||||||
|
]
|
||||||
|
|
||||||
|
private var phase: Int = 0
|
||||||
|
|
||||||
|
private var timer: Timer?
|
||||||
|
|
||||||
|
private var validLayout: CGSize?
|
||||||
|
|
||||||
|
override public init() {
|
||||||
|
//self.imageView = UIImageView()
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
self.phase = 3
|
||||||
|
|
||||||
|
self.backgroundColor = .white
|
||||||
|
self.clipsToBounds = true
|
||||||
|
|
||||||
|
//self.view.addSubview(self.imageView)
|
||||||
|
|
||||||
|
/*let compositingModes: [String] = CIFilter
|
||||||
|
.filterNames(inCategory: nil) // fetch all the available filters
|
||||||
|
.filter { $0.contains("Compositing")} // retrieve only the compositing ones
|
||||||
|
.map {
|
||||||
|
let capitalizedFilter = $0.dropFirst(2) // drop the CIn prefix
|
||||||
|
let first = capitalizedFilter.first! // fetch the first letter
|
||||||
|
// lowercase the first letter and drop the `Compositing` suffix
|
||||||
|
return "\(first.lowercased())\(capitalizedFilter.dropFirst().dropLast("Compositing".count))"
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//print("compositingModes: \(compositingModes)")
|
||||||
|
|
||||||
|
//self.imageView.alpha = 0.5
|
||||||
|
//self.imageView.layer.compositingFilter = "multiplyBlendMode"
|
||||||
|
|
||||||
|
let colors: [UIColor] = [
|
||||||
|
UIColor(rgb: 0xfff6bf),
|
||||||
|
UIColor(rgb: 0x76a076),
|
||||||
|
UIColor(rgb: 0xf6e477),
|
||||||
|
UIColor(rgb: 0x316b4d)
|
||||||
|
]
|
||||||
|
|
||||||
|
for color in colors {
|
||||||
|
let pointImage = UIImageView(image: generateGradientComponent(size: CGSize(width: 800.0, height: 800.0), color: color.withMultiplied(hue: 1.0, saturation: 1.2, brightness: 1.0)))
|
||||||
|
pointImage.layer.compositingFilter = "multiplyBlendMode"
|
||||||
|
//pointImage.layer.compositingFilter = "additionBlendMode"
|
||||||
|
pointImage.alpha = 0.7
|
||||||
|
self.view.addSubview(pointImage)
|
||||||
|
self.pointImages.append(pointImage)
|
||||||
|
}
|
||||||
|
|
||||||
|
if #available(iOS 10.0, *) {
|
||||||
|
let timer = Timer(timeInterval: 2.0, repeats: true, block: { [weak self] _ in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
strongSelf.phase = (strongSelf.phase + 1) % 4
|
||||||
|
if let size = strongSelf.validLayout {
|
||||||
|
strongSelf.updateLayout(size: size, transition: .animated(duration: 0.5, curve: .spring))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
self.timer = timer
|
||||||
|
RunLoop.main.add(timer, forMode: .common)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
self.timer?.invalidate()
|
||||||
|
}
|
||||||
|
|
||||||
|
public func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) {
|
||||||
|
self.validLayout = size
|
||||||
|
|
||||||
|
let positions: [CGPoint]
|
||||||
|
|
||||||
|
if self.phase % 2 == 0 {
|
||||||
|
positions = shiftArray(array: firstStepPoints, offset: self.phase / 2)
|
||||||
|
} else {
|
||||||
|
positions = shiftArray(array: nextStepPoints, offset: self.phase / 2 + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0 ..< firstStepPoints.count {
|
||||||
|
if self.pointImages.count <= i {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
let pointCenter = CGPoint(x: size.width * positions[i].x, y: size.height * positions[i].y)
|
||||||
|
let pointSide = max(size.width, size.height) * 2.0
|
||||||
|
let pointSize = CGSize(width: pointSide, height: pointSide)
|
||||||
|
transition.updateFrame(view: self.pointImages[i], frame: CGRect(origin: CGPoint(x: pointCenter.x - pointSize.width / 2.0, y: pointCenter.y - pointSize.height / 2.0), size: pointSize))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*self.imageView.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
|
self.imageView.layer.magnificationFilter = .linear
|
||||||
|
|
||||||
|
self.imageView.image = generateGradient(with: size.fitted(CGSize(width: 64.0, height: 64.0)), gradPointArray: applyTransformerToPoints(step: 0, substep: 0))*/
|
||||||
|
}
|
||||||
|
}
|
@ -221,6 +221,7 @@ swift_library(
|
|||||||
"//submodules/PeerInfoAvatarListNode:PeerInfoAvatarListNode",
|
"//submodules/PeerInfoAvatarListNode:PeerInfoAvatarListNode",
|
||||||
"//submodules/DebugSettingsUI:DebugSettingsUI",
|
"//submodules/DebugSettingsUI:DebugSettingsUI",
|
||||||
"//submodules/ImportStickerPackUI:ImportStickerPackUI",
|
"//submodules/ImportStickerPackUI:ImportStickerPackUI",
|
||||||
|
"//submodules/GradientBackground:GradientBackground",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -16,6 +16,7 @@ import TelegramUniversalVideoContent
|
|||||||
import ChatInterfaceState
|
import ChatInterfaceState
|
||||||
import FastBlur
|
import FastBlur
|
||||||
import ConfettiEffect
|
import ConfettiEffect
|
||||||
|
import GradientBackground
|
||||||
|
|
||||||
final class VideoNavigationControllerDropContentItem: NavigationControllerDropContentItem {
|
final class VideoNavigationControllerDropContentItem: NavigationControllerDropContentItem {
|
||||||
let itemNode: OverlayMediaItemNode
|
let itemNode: OverlayMediaItemNode
|
||||||
@ -300,6 +301,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let backgroundNode: WallpaperBackgroundNode
|
let backgroundNode: WallpaperBackgroundNode
|
||||||
|
let gradientBackgroundNode: GradientBackgroundNode?
|
||||||
let backgroundImageDisposable = MetaDisposable()
|
let backgroundImageDisposable = MetaDisposable()
|
||||||
let historyNode: ChatHistoryListNode
|
let historyNode: ChatHistoryListNode
|
||||||
var blurredHistoryNode: ASImageNode?
|
var blurredHistoryNode: ASImageNode?
|
||||||
@ -466,6 +468,8 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
|
|
||||||
self.backgroundNode = WallpaperBackgroundNode()
|
self.backgroundNode = WallpaperBackgroundNode()
|
||||||
self.backgroundNode.displaysAsynchronously = false
|
self.backgroundNode.displaysAsynchronously = false
|
||||||
|
|
||||||
|
self.gradientBackgroundNode = GradientBackgroundNode()
|
||||||
|
|
||||||
self.titleAccessoryPanelContainer = ChatControllerTitlePanelNodeContainer()
|
self.titleAccessoryPanelContainer = ChatControllerTitlePanelNodeContainer()
|
||||||
self.titleAccessoryPanelContainer.clipsToBounds = true
|
self.titleAccessoryPanelContainer.clipsToBounds = true
|
||||||
@ -598,6 +602,9 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
self.historyNode.enableExtractedBackgrounds = true
|
self.historyNode.enableExtractedBackgrounds = true
|
||||||
|
|
||||||
self.addSubnode(self.backgroundNode)
|
self.addSubnode(self.backgroundNode)
|
||||||
|
if let gradientBackgroundNode = self.gradientBackgroundNode {
|
||||||
|
self.addSubnode(gradientBackgroundNode)
|
||||||
|
}
|
||||||
self.addSubnode(self.historyNodeContainer)
|
self.addSubnode(self.historyNodeContainer)
|
||||||
self.addSubnode(self.navigateButtons)
|
self.addSubnode(self.navigateButtons)
|
||||||
self.addSubnode(self.titleAccessoryPanelContainer)
|
self.addSubnode(self.titleAccessoryPanelContainer)
|
||||||
@ -1282,6 +1289,12 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
|
|
||||||
transition.updateFrame(node: self.backgroundNode, frame: contentBounds)
|
transition.updateFrame(node: self.backgroundNode, frame: contentBounds)
|
||||||
self.backgroundNode.updateLayout(size: contentBounds.size, transition: transition)
|
self.backgroundNode.updateLayout(size: contentBounds.size, transition: transition)
|
||||||
|
|
||||||
|
if let gradientBackgroundNode = self.gradientBackgroundNode {
|
||||||
|
transition.updateFrame(node: gradientBackgroundNode, frame: contentBounds)
|
||||||
|
gradientBackgroundNode.updateLayout(size: contentBounds.size, transition: transition)
|
||||||
|
}
|
||||||
|
|
||||||
transition.updateFrame(node: self.historyNodeContainer, frame: contentBounds)
|
transition.updateFrame(node: self.historyNodeContainer, frame: contentBounds)
|
||||||
transition.updateBounds(node: self.historyNode, bounds: CGRect(origin: CGPoint(), size: contentBounds.size))
|
transition.updateBounds(node: self.historyNode, bounds: CGRect(origin: CGPoint(), size: contentBounds.size))
|
||||||
transition.updatePosition(node: self.historyNode, position: CGPoint(x: contentBounds.size.width / 2.0, y: contentBounds.size.height / 2.0))
|
transition.updatePosition(node: self.historyNode, position: CGPoint(x: contentBounds.size.width / 2.0, y: contentBounds.size.height / 2.0))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user