exyte / Macaw

Powerful and easy-to-use vector graphics Swift library with SVG support
MIT License
6.02k stars 557 forks source link

Performance Issue with complex SVGs #608

Closed glennposadas closed 4 years ago

glennposadas commented 5 years ago

Huge edit:

When applying fill changes of shapes in a large numbers of shapes, hence the title complex SVGs, the performance is way too slow.

GET ALL SHAPES:

extension Node {
    var allShapes: [Shape] {
        get {
            var shapes = [Shape]()

            if let shape = self as? Shape {
                if shape.tag.count > 0 {
                    shapes.append(shape)
                }
            } else if let group = self as? Group {
                group.contents.forEach { (node) in
                    node.allShapes.forEach { (shape) in
                        shapes.append(shape)
                    }
                }
            }

            return shapes
        }
    }
}

ADDING TAPS TO EACH SHAPE

self.svgScrollView.svgView.node.allShapes.forEach { shape in
    shape.fill = Color.clear
    shape.onTap { [weak self] (tapEvent) in
        self?.changeColor(color: "\(Constants.selectColor)", shape: shape)
    }
}

CHANGE FILL/COLOR

func changeColor(color: String, shape: Shape) {
    let fill = Int(color.replacingOccurrences(of: "#", with: "") , radix: 16)
    let color = Color(val: fill!)
    shape.fill = color
}

Is there something wrong I'm doing here? Help please! Thank you!

glennposadas commented 5 years ago

Hi Yuri @ystrot! Shamelessly tagging you, sorry! But I think I made the question more straightforward, maybe you can help me here? And to other Macaw team. Thank you so much!

ystrot commented 5 years ago

Hi @glennposadas,

I don't see explicit issues in your code. Probably you don't need to call color.replacingOccurrences(of: "#", with: "") for every node, just calculate Color once and use it.

Most probably your issue relates to performance of complex SVG rendering. You may try to profile your app to find the bottleneck. One of the most common way to optimize your rendering is to draw complex parts to images and then draw images (which is usually much faster).