mirror of
https://github.com/exyte/Macaw.git
synced 2024-09-11 13:15:35 +03:00
Disabling renderer event by individual node
This commit is contained in:
parent
c1773e4f24
commit
b4a907c0f7
@ -4,14 +4,11 @@ import RxSwift
|
||||
|
||||
class GroupRenderer: NodeRenderer {
|
||||
|
||||
var animationCache: AnimationCache
|
||||
|
||||
let group: Group
|
||||
|
||||
init(group: Group, ctx: RenderContext, animationCache: AnimationCache) {
|
||||
self.group = group
|
||||
self.animationCache = animationCache
|
||||
super.init(node: group, ctx: ctx)
|
||||
super.init(node: group, ctx: ctx, animationCache: animationCache)
|
||||
}
|
||||
|
||||
override func addObservers() {
|
||||
@ -25,6 +22,8 @@ class GroupRenderer: NodeRenderer {
|
||||
|
||||
override func render(force: Bool, opacity: Double) {
|
||||
|
||||
super.render(force, opacity: opacity)
|
||||
|
||||
if !force {
|
||||
|
||||
// Cutting animated content
|
||||
|
@ -6,9 +6,9 @@ class ImageRenderer: NodeRenderer {
|
||||
|
||||
var renderedPaths: [CGPath] = [CGPath]()
|
||||
|
||||
init(image: Image, ctx: RenderContext) {
|
||||
init(image: Image, ctx: RenderContext, animationCache: AnimationCache) {
|
||||
self.image = image
|
||||
super.init(node: image, ctx: ctx)
|
||||
super.init(node: image, ctx: ctx, animationCache: animationCache)
|
||||
}
|
||||
|
||||
override func node() -> Node {
|
||||
@ -26,6 +26,8 @@ class ImageRenderer: NodeRenderer {
|
||||
}
|
||||
|
||||
override func render(force: Bool, opacity: Double) {
|
||||
super.render(force, opacity: opacity)
|
||||
|
||||
if let uiimage = UIImage(named: image.src) {
|
||||
let imageSize = uiimage.size
|
||||
var w = CGFloat(image.w)
|
||||
|
@ -8,9 +8,11 @@ class NodeRenderer {
|
||||
|
||||
private let onNodeChange: (Any) -> Void
|
||||
private let disposables = GroupDisposable()
|
||||
let animationCache: AnimationCache
|
||||
|
||||
init(node: Node, ctx: RenderContext) {
|
||||
init(node: Node, ctx: RenderContext, animationCache: AnimationCache) {
|
||||
self.ctx = ctx
|
||||
self.animationCache = animationCache
|
||||
onNodeChange = { (_: Any) in ctx.view?.setNeedsDisplay() }
|
||||
addObservers()
|
||||
}
|
||||
@ -44,7 +46,11 @@ class NodeRenderer {
|
||||
}
|
||||
|
||||
public func render(force: Bool, opacity: Double) {
|
||||
|
||||
if animationCache.isAnimating(node()) {
|
||||
self.removeObservers()
|
||||
} else {
|
||||
self.addObservers()
|
||||
}
|
||||
}
|
||||
|
||||
public func detectTouches(location: CGPoint) -> [Shape] {
|
||||
|
@ -47,7 +47,7 @@ class RenderUtils {
|
||||
} else if let text = node as? Text {
|
||||
return TextRenderer(text: text, ctx: context, animationCache: animationCache)
|
||||
} else if let image = node as? Image {
|
||||
return ImageRenderer(image: image, ctx: context)
|
||||
return ImageRenderer(image: image, ctx: context, animationCache: animationCache)
|
||||
}
|
||||
fatalError("Unsupported node: \(node)");
|
||||
}
|
||||
|
@ -5,12 +5,9 @@ class ShapeRenderer: NodeRenderer {
|
||||
|
||||
let shape: Shape
|
||||
|
||||
let animationCache: AnimationCache
|
||||
|
||||
init(shape: Shape, ctx: RenderContext, animationCache: AnimationCache) {
|
||||
self.shape = shape
|
||||
self.animationCache = animationCache
|
||||
super.init(node: shape, ctx: ctx)
|
||||
super.init(node: shape, ctx: ctx, animationCache: animationCache)
|
||||
}
|
||||
|
||||
override func node() -> Node {
|
||||
@ -26,9 +23,11 @@ class ShapeRenderer: NodeRenderer {
|
||||
|
||||
override func render(force: Bool, opacity: Double) {
|
||||
|
||||
super.render(force, opacity: opacity)
|
||||
|
||||
if !force {
|
||||
// Cutting animated content
|
||||
if animationCache.isAnimating(shape) {
|
||||
if self.animationCache.isAnimating(shape) {
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -484,61 +483,61 @@ class ShapeRenderer: NodeRenderer {
|
||||
let color = RenderUtils.applyOpacity(strokeColor, opacity: opacity)
|
||||
CGContextSetStrokeColorWithColor(ctx, RenderUtils.mapColor(color))
|
||||
}
|
||||
|
||||
private func gradientStroke(stroke: Stroke, ctx: CGContext?, opacity: Double) {
|
||||
guard let gradient = stroke.fill as? Gradient else {
|
||||
return
|
||||
}
|
||||
CGContextReplacePathWithStrokedPath(ctx)
|
||||
drawGradient(gradient, ctx: ctx, opacity: opacity)
|
||||
}
|
||||
|
||||
private func drawGradient(gradient: Gradient, ctx: CGContext?, opacity: Double) {
|
||||
CGContextSaveGState(ctx)
|
||||
var colors: [CGColor] = []
|
||||
var stops: [CGFloat] = []
|
||||
for stop in gradient.stops {
|
||||
stops.append(CGFloat(stop.offset))
|
||||
let color = RenderUtils.applyOpacity(stop.color, opacity: opacity)
|
||||
colors.append(RenderUtils.mapColor(color))
|
||||
}
|
||||
|
||||
if let gradient = gradient as? LinearGradient {
|
||||
var start = CGPointMake(CGFloat(gradient.x1), CGFloat(gradient.y1))
|
||||
var end = CGPointMake(CGFloat(gradient.x2), CGFloat(gradient.y2))
|
||||
if gradient.userSpace {
|
||||
let bounds = CGContextGetPathBoundingBox(ctx)
|
||||
start = CGPointMake(start.x * bounds.width + bounds.minX, start.y * bounds.height + bounds.minY)
|
||||
end = CGPointMake(end.x * bounds.width + bounds.minX, end.y * bounds.height + bounds.minY)
|
||||
}
|
||||
CGContextClip(ctx)
|
||||
let cgGradient = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), colors, stops)
|
||||
CGContextDrawLinearGradient(ctx, cgGradient, start, end, [.DrawsAfterEndLocation, .DrawsBeforeStartLocation])
|
||||
} else if let gradient = gradient as? RadialGradient {
|
||||
var innerCenter = CGPointMake(CGFloat(gradient.fx), CGFloat(gradient.fy))
|
||||
var outerCenter = CGPointMake(CGFloat(gradient.cx), CGFloat(gradient.cy))
|
||||
var radius = CGFloat(gradient.r)
|
||||
if gradient.userSpace {
|
||||
var bounds = CGContextGetPathBoundingBox(ctx)
|
||||
var scaleX: CGFloat = 1
|
||||
var scaleY: CGFloat = 1
|
||||
if bounds.width > bounds.height {
|
||||
scaleY = bounds.height / bounds.width
|
||||
} else {
|
||||
scaleX = bounds.width / bounds.height
|
||||
}
|
||||
CGContextScaleCTM(ctx, scaleX, scaleY)
|
||||
bounds = CGContextGetPathBoundingBox(ctx)
|
||||
innerCenter = CGPointMake(innerCenter.x * bounds.width + bounds.minX, innerCenter.y * bounds.height + bounds.minY)
|
||||
outerCenter = CGPointMake(outerCenter.x * bounds.width + bounds.minX, outerCenter.y * bounds.height + bounds.minY)
|
||||
radius = min(radius * bounds.width, radius * bounds.height)
|
||||
|
||||
}
|
||||
CGContextClip(ctx)
|
||||
let cgGradient = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), colors, stops)
|
||||
CGContextDrawRadialGradient(ctx, cgGradient, innerCenter, 0, outerCenter, radius, [.DrawsAfterEndLocation, .DrawsBeforeStartLocation])
|
||||
}
|
||||
CGContextRestoreGState(ctx)
|
||||
}
|
||||
|
||||
private func gradientStroke(stroke: Stroke, ctx: CGContext?, opacity: Double) {
|
||||
guard let gradient = stroke.fill as? Gradient else {
|
||||
return
|
||||
}
|
||||
CGContextReplacePathWithStrokedPath(ctx)
|
||||
drawGradient(gradient, ctx: ctx, opacity: opacity)
|
||||
}
|
||||
|
||||
private func drawGradient(gradient: Gradient, ctx: CGContext?, opacity: Double) {
|
||||
CGContextSaveGState(ctx)
|
||||
var colors: [CGColor] = []
|
||||
var stops: [CGFloat] = []
|
||||
for stop in gradient.stops {
|
||||
stops.append(CGFloat(stop.offset))
|
||||
let color = RenderUtils.applyOpacity(stop.color, opacity: opacity)
|
||||
colors.append(RenderUtils.mapColor(color))
|
||||
}
|
||||
|
||||
if let gradient = gradient as? LinearGradient {
|
||||
var start = CGPointMake(CGFloat(gradient.x1), CGFloat(gradient.y1))
|
||||
var end = CGPointMake(CGFloat(gradient.x2), CGFloat(gradient.y2))
|
||||
if gradient.userSpace {
|
||||
let bounds = CGContextGetPathBoundingBox(ctx)
|
||||
start = CGPointMake(start.x * bounds.width + bounds.minX, start.y * bounds.height + bounds.minY)
|
||||
end = CGPointMake(end.x * bounds.width + bounds.minX, end.y * bounds.height + bounds.minY)
|
||||
}
|
||||
CGContextClip(ctx)
|
||||
let cgGradient = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), colors, stops)
|
||||
CGContextDrawLinearGradient(ctx, cgGradient, start, end, [.DrawsAfterEndLocation, .DrawsBeforeStartLocation])
|
||||
} else if let gradient = gradient as? RadialGradient {
|
||||
var innerCenter = CGPointMake(CGFloat(gradient.fx), CGFloat(gradient.fy))
|
||||
var outerCenter = CGPointMake(CGFloat(gradient.cx), CGFloat(gradient.cy))
|
||||
var radius = CGFloat(gradient.r)
|
||||
if gradient.userSpace {
|
||||
var bounds = CGContextGetPathBoundingBox(ctx)
|
||||
var scaleX: CGFloat = 1
|
||||
var scaleY: CGFloat = 1
|
||||
if bounds.width > bounds.height {
|
||||
scaleY = bounds.height / bounds.width
|
||||
} else {
|
||||
scaleX = bounds.width / bounds.height
|
||||
}
|
||||
CGContextScaleCTM(ctx, scaleX, scaleY)
|
||||
bounds = CGContextGetPathBoundingBox(ctx)
|
||||
innerCenter = CGPointMake(innerCenter.x * bounds.width + bounds.minX, innerCenter.y * bounds.height + bounds.minY)
|
||||
outerCenter = CGPointMake(outerCenter.x * bounds.width + bounds.minX, outerCenter.y * bounds.height + bounds.minY)
|
||||
radius = min(radius * bounds.width, radius * bounds.height)
|
||||
|
||||
}
|
||||
CGContextClip(ctx)
|
||||
let cgGradient = CGGradientCreateWithColors(CGColorSpaceCreateDeviceRGB(), colors, stops)
|
||||
CGContextDrawRadialGradient(ctx, cgGradient, innerCenter, 0, outerCenter, radius, [.DrawsAfterEndLocation, .DrawsBeforeStartLocation])
|
||||
}
|
||||
CGContextRestoreGState(ctx)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,12 +4,9 @@ import UIKit
|
||||
class TextRenderer: NodeRenderer {
|
||||
let text: Text
|
||||
|
||||
let animationCache: AnimationCache
|
||||
|
||||
init(text: Text, ctx: RenderContext, animationCache: AnimationCache) {
|
||||
self.text = text
|
||||
self.animationCache = animationCache
|
||||
super.init(node: text, ctx: ctx)
|
||||
super.init(node: text, ctx: ctx, animationCache: animationCache)
|
||||
}
|
||||
|
||||
override func node() -> Node {
|
||||
@ -27,6 +24,8 @@ class TextRenderer: NodeRenderer {
|
||||
|
||||
override func render(force: Bool, opacity: Double) {
|
||||
|
||||
super.render(force, opacity: opacity)
|
||||
|
||||
if !force {
|
||||
// Cutting animated content
|
||||
if animationCache.isAnimating(text) {
|
||||
|
@ -57,15 +57,6 @@ public class MacawView: UIView {
|
||||
}
|
||||
|
||||
override public func drawRect(rect: CGRect) {
|
||||
|
||||
if let cache = animationCache {
|
||||
if cache.containsAnimation(node) {
|
||||
renderer?.removeObservers()
|
||||
} else {
|
||||
renderer?.addObservers()
|
||||
}
|
||||
}
|
||||
|
||||
self.context.cgContext = UIGraphicsGetCurrentContext()
|
||||
|
||||
CGContextSaveGState(self.context.cgContext)
|
||||
|
Loading…
Reference in New Issue
Block a user