mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-08 17:53:38 +00:00
[WIP] Stories
This commit is contained in:
parent
b64aa1445c
commit
8e5241f064
@ -422,7 +422,7 @@ public struct Transition {
|
|||||||
delay: 0.0,
|
delay: 0.0,
|
||||||
curve: curve,
|
curve: curve,
|
||||||
removeOnCompletion: true,
|
removeOnCompletion: true,
|
||||||
additive: true,
|
additive: false,
|
||||||
completion: completion
|
completion: completion
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -497,21 +497,35 @@ public struct Transition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func setTransform(layer: CALayer, transform: CATransform3D, completion: ((Bool) -> Void)? = nil) {
|
public func setTransform(layer: CALayer, transform: CATransform3D, completion: ((Bool) -> Void)? = nil) {
|
||||||
let t = layer.presentation()?.transform ?? layer.transform
|
if let animation = layer.animation(forKey: "transform") as? CABasicAnimation, let toValue = animation.toValue as? NSValue {
|
||||||
if CATransform3DEqualToTransform(t, transform) {
|
if CATransform3DEqualToTransform(toValue.caTransform3DValue, transform) {
|
||||||
if let animation = layer.animation(forKey: "transform") as? CABasicAnimation, let toValue = animation.toValue as? NSValue {
|
completion?(true)
|
||||||
if CATransform3DEqualToTransform(toValue.caTransform3DValue, transform) {
|
return
|
||||||
completion?(true)
|
}
|
||||||
return
|
} else if let animation = layer.animation(forKey: "transform") as? CAKeyframeAnimation, let toValue = animation.values?.last as? NSValue {
|
||||||
}
|
if CATransform3DEqualToTransform(toValue.caTransform3DValue, transform) {
|
||||||
} else {
|
|
||||||
completion?(true)
|
completion?(true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if CATransform3DEqualToTransform(layer.transform, transform) {
|
||||||
|
completion?(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch self.animation {
|
switch self.animation {
|
||||||
case .none:
|
case .none:
|
||||||
|
if layer.animation(forKey: "transform") != nil {
|
||||||
|
if let animation = layer.animation(forKey: "transform") as? CAKeyframeAnimation, let toValue = animation.values?.last as? NSValue {
|
||||||
|
if CATransform3DEqualToTransform(toValue.caTransform3DValue, transform) {
|
||||||
|
completion?(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
layer.removeAnimation(forKey: "transform")
|
||||||
|
}
|
||||||
layer.transform = transform
|
layer.transform = transform
|
||||||
completion?(true)
|
completion?(true)
|
||||||
case let .curve(duration, curve):
|
case let .curve(duration, curve):
|
||||||
@ -540,14 +554,19 @@ public struct Transition {
|
|||||||
public func setTransformAsKeyframes(layer: CALayer, transform: (CGFloat, Bool) -> CATransform3D, completion: ((Bool) -> Void)? = nil) {
|
public func setTransformAsKeyframes(layer: CALayer, transform: (CGFloat, Bool) -> CATransform3D, completion: ((Bool) -> Void)? = nil) {
|
||||||
let finalTransform = transform(1.0, true)
|
let finalTransform = transform(1.0, true)
|
||||||
|
|
||||||
let t = layer.presentation()?.transform ?? layer.transform
|
let t = layer.transform
|
||||||
if CATransform3DEqualToTransform(t, finalTransform) {
|
do {
|
||||||
if let animation = layer.animation(forKey: "transform") as? CABasicAnimation, let toValue = animation.toValue as? NSValue {
|
if let animation = layer.animation(forKey: "transform") as? CABasicAnimation, let toValue = animation.toValue as? NSValue {
|
||||||
if CATransform3DEqualToTransform(toValue.caTransform3DValue, finalTransform) {
|
if CATransform3DEqualToTransform(toValue.caTransform3DValue, finalTransform) {
|
||||||
completion?(true)
|
completion?(true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else if let animation = layer.animation(forKey: "transform") as? CAKeyframeAnimation, let toValue = animation.values?.last as? NSValue {
|
||||||
|
if CATransform3DEqualToTransform(toValue.caTransform3DValue, finalTransform) {
|
||||||
|
completion?(true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else if CATransform3DEqualToTransform(t, finalTransform) {
|
||||||
completion?(true)
|
completion?(true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -555,6 +574,9 @@ public struct Transition {
|
|||||||
|
|
||||||
switch self.animation {
|
switch self.animation {
|
||||||
case .none:
|
case .none:
|
||||||
|
if layer.animation(forKey: "transform") != nil {
|
||||||
|
layer.removeAnimation(forKey: "transform")
|
||||||
|
}
|
||||||
layer.transform = transform(1.0, true)
|
layer.transform = transform(1.0, true)
|
||||||
completion?(true)
|
completion?(true)
|
||||||
case let .curve(duration, curve):
|
case let .curve(duration, curve):
|
||||||
|
|||||||
@ -185,7 +185,7 @@ final class PendingStoryManager {
|
|||||||
if let currentPendingItemContext = self.currentPendingItemContext, currentPendingItemContext.item.stableId == stableId {
|
if let currentPendingItemContext = self.currentPendingItemContext, currentPendingItemContext.item.stableId == stableId {
|
||||||
next(currentPendingItemContext.progress)
|
next(currentPendingItemContext.progress)
|
||||||
} else {
|
} else {
|
||||||
next(1.0)
|
next(0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
let queue = self.queue
|
let queue = self.queue
|
||||||
|
|||||||
@ -250,15 +250,27 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private func beginHorizontalPan() {
|
private func beginHorizontalPan(translation: CGPoint) {
|
||||||
self.layer.removeAnimation(forKey: "panState")
|
if self.layer.animation(forKey: "panState") != nil {
|
||||||
|
self.layer.removeAnimation(forKey: "panState")
|
||||||
|
}
|
||||||
|
|
||||||
|
let updateImmediately = abs(translation.x) > 0.0
|
||||||
|
|
||||||
if let itemSetPanState = self.itemSetPanState, !itemSetPanState.didBegin {
|
if let itemSetPanState = self.itemSetPanState, !itemSetPanState.didBegin {
|
||||||
self.itemSetPanState = ItemSetPanState(fraction: 0.0, didBegin: true)
|
self.itemSetPanState = ItemSetPanState(fraction: 0.0, didBegin: true)
|
||||||
self.state?.updated(transition: Transition(animation: .curve(duration: 0.25, curve: .easeInOut)))
|
if !updateImmediately {
|
||||||
|
self.state?.updated(transition: Transition(animation: .curve(duration: 0.25, curve: .easeInOut)))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.itemSetPanState = ItemSetPanState(fraction: 0.0, didBegin: true)
|
self.itemSetPanState = ItemSetPanState(fraction: 0.0, didBegin: true)
|
||||||
self.state?.updated(transition: .immediate)
|
if !updateImmediately {
|
||||||
|
self.state?.updated(transition: .immediate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if updateImmediately {
|
||||||
|
self.updateHorizontalPan(translation: translation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,7 +353,7 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
@objc private func panGesture(_ recognizer: UIPanGestureRecognizer) {
|
@objc private func panGesture(_ recognizer: UIPanGestureRecognizer) {
|
||||||
switch recognizer.state {
|
switch recognizer.state {
|
||||||
case .began:
|
case .began:
|
||||||
self.beginHorizontalPan()
|
self.beginHorizontalPan(translation: recognizer.translation(in: self))
|
||||||
case .changed:
|
case .changed:
|
||||||
self.updateHorizontalPan(translation: recognizer.translation(in: self))
|
self.updateHorizontalPan(translation: recognizer.translation(in: self))
|
||||||
case .cancelled, .ended:
|
case .cancelled, .ended:
|
||||||
@ -409,14 +421,14 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
if stateValue.previousSlice == nil {
|
if stateValue.previousSlice == nil {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
self.beginHorizontalPan()
|
self.beginHorizontalPan(translation: CGPoint())
|
||||||
self.commitHorizontalPan(velocity: CGPoint(x: 100.0, y: 0.0))
|
self.commitHorizontalPan(velocity: CGPoint(x: 100.0, y: 0.0))
|
||||||
}
|
}
|
||||||
} else if location.x > currentItemView.frame.maxX {
|
} else if location.x > currentItemView.frame.maxX {
|
||||||
if stateValue.nextSlice == nil {
|
if stateValue.nextSlice == nil {
|
||||||
environment.controller()?.dismiss()
|
environment.controller()?.dismiss()
|
||||||
} else {
|
} else {
|
||||||
self.beginHorizontalPan()
|
self.beginHorizontalPan(translation: CGPoint())
|
||||||
self.commitHorizontalPan(velocity: CGPoint(x: -100.0, y: 0.0))
|
self.commitHorizontalPan(velocity: CGPoint(x: -100.0, y: 0.0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -430,10 +442,8 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if subview is ItemSetView {
|
if subview is ItemSetView {
|
||||||
if self.itemSetPanState == nil {
|
if let result = subview.hitTest(self.convert(point, to: subview), with: event) {
|
||||||
if let result = subview.hitTest(self.convert(point, to: subview), with: event) {
|
return result
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let result = subview.hitTest(self.convert(self.convert(point, to: subview), to: subview), with: event) {
|
if let result = subview.hitTest(self.convert(self.convert(point, to: subview), to: subview), with: event) {
|
||||||
@ -738,7 +748,7 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
if stateValue.nextSlice == nil {
|
if stateValue.nextSlice == nil {
|
||||||
environment.controller()?.dismiss()
|
environment.controller()?.dismiss()
|
||||||
} else {
|
} else {
|
||||||
self.beginHorizontalPan()
|
self.beginHorizontalPan(translation: CGPoint())
|
||||||
self.updateHorizontalPan(translation: CGPoint())
|
self.updateHorizontalPan(translation: CGPoint())
|
||||||
self.commitHorizontalPan(velocity: CGPoint(x: -100.0, y: 0.0))
|
self.commitHorizontalPan(velocity: CGPoint(x: -100.0, y: 0.0))
|
||||||
}
|
}
|
||||||
@ -750,7 +760,7 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.beginHorizontalPan()
|
self.beginHorizontalPan(translation: CGPoint())
|
||||||
self.updateHorizontalPan(translation: CGPoint())
|
self.updateHorizontalPan(translation: CGPoint())
|
||||||
self.commitHorizontalPan(velocity: CGPoint(x: 100.0, y: 0.0))
|
self.commitHorizontalPan(velocity: CGPoint(x: 100.0, y: 0.0))
|
||||||
}
|
}
|
||||||
@ -882,27 +892,29 @@ private final class StoryContainerScreenComponent: Component {
|
|||||||
Transition.immediate.setTransform(view: itemSetComponentView, transform: faceTransform)
|
Transition.immediate.setTransform(view: itemSetComponentView, transform: faceTransform)
|
||||||
Transition.immediate.setTransform(layer: itemSetView.tintLayer, transform: faceTransform)
|
Transition.immediate.setTransform(layer: itemSetView.tintLayer, transform: faceTransform)
|
||||||
|
|
||||||
if let previousRotationFraction = itemSetView.rotationFraction {
|
if let previousRotationFraction = itemSetView.rotationFraction, !itemSetTransition.animation.isImmediate {
|
||||||
let fromT = previousRotationFraction
|
let fromT = previousRotationFraction
|
||||||
let toT = panFraction
|
let toT = panFraction + cubeAdditionalRotationFraction
|
||||||
itemSetTransition.setTransformAsKeyframes(view: itemSetView, transform: { sourceT, isFinal in
|
itemSetTransition.setTransformAsKeyframes(view: itemSetView, transform: { sourceT, isFinal in
|
||||||
let t = fromT * (1.0 - sourceT) + toT * sourceT
|
let t = fromT * (1.0 - sourceT) + toT * sourceT
|
||||||
if abs((t + cubeAdditionalRotationFraction) - 0.0) < 0.0001 {
|
if isFinal {
|
||||||
if isFinal {
|
if abs(t - 0.0) <= 0.0001 {
|
||||||
return CATransform3DIdentity
|
return CATransform3DIdentity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return calculateCubeTransform(rotationFraction: t + cubeAdditionalRotationFraction, sideAngle: sideAngle, cubeSize: itemFrame.size)
|
return calculateCubeTransform(rotationFraction: t, sideAngle: sideAngle, cubeSize: itemFrame.size)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
if panFraction == 0.0 {
|
let updatedTransform: CATransform3D
|
||||||
itemSetTransition.setTransform(view: itemSetView, transform: CATransform3DIdentity)
|
if abs(panFraction + cubeAdditionalRotationFraction) <= 0.0001 {
|
||||||
|
updatedTransform = CATransform3DIdentity
|
||||||
} else {
|
} else {
|
||||||
itemSetTransition.setTransform(view: itemSetView, transform: calculateCubeTransform(rotationFraction: panFraction + cubeAdditionalRotationFraction, sideAngle: sideAngle, cubeSize: itemFrame.size))
|
updatedTransform = calculateCubeTransform(rotationFraction: panFraction + cubeAdditionalRotationFraction, sideAngle: sideAngle, cubeSize: itemFrame.size)
|
||||||
}
|
}
|
||||||
|
itemSetTransition.setTransform(view: itemSetView, transform: updatedTransform)
|
||||||
}
|
}
|
||||||
itemSetView.rotationFraction = panFraction
|
itemSetView.rotationFraction = panFraction + cubeAdditionalRotationFraction
|
||||||
|
|
||||||
var alphaFraction = panFraction + cubeAdditionalRotationFraction
|
var alphaFraction = panFraction + cubeAdditionalRotationFraction
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user