Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add readonly property view.transformedPath #102

Open
ahmedk92 opened this issue Aug 27, 2017 · 5 comments
Open

Add readonly property view.transformedPath #102

ahmedk92 opened this issue Aug 27, 2017 · 5 comments

Comments

@ahmedk92
Copy link

ahmedk92 commented Aug 27, 2017

It might be useful if SVGLayer had a readonly property to access the path with the rendering transformation applied.


Original title: path.contains(point) correctly works only when SVGImageView contentMode is bottomeLeft

I'm building a fill-on-tap demo on top of the Demo-iOS project.

I added a UITapGestureRecognizer to the SVGImageView. I'm aiming to fill the subpath under the tapped point with a color. My code so far:

@IBAction func didTapImageView(_ sender: UITapGestureRecognizer) {

    let svgView = sender.view as! SVGImageView
    let point = sender.location(in: svgView)
    
    svgView.paths = svgView.paths.map { path in
        var p: SVGBezierPath = path
        
        if path.contains(point) {
            p = path.settingSVGAttributes(["fill": colors[colorIndex].cgColor])
            colorIndex = (colorIndex + 1) % colors.count
        }
        
        print(point)
        print(p)
        
        return p
    }
}

This correctly works only if the contentMode of the SVGImageView is bottomLeft. Other modes acknowledges the tapped point while it's actually rendered somewhere else. Any ideas what may be wrong?

@arielelkin
Copy link
Collaborator

Hi @ahmedk92

can you please attach a project that would allow us to reproduce the issue?

@arielelkin arielelkin self-assigned this Aug 27, 2017
@ahmedk92
Copy link
Author

For convenience, I made a fork with the changed demo, and added you as a collaborator to it.

@arielelkin
Copy link
Collaborator

Thanks, I have it clearer now.

The issue here is that paths don't get updated when we change the contentMode of the SVGImageView.

@fjolnir any thoughts on how to catch touches on specific SVG paths when the container frame changes?

If the paths property should not get updated when we redraw the image view, then we should mention in the docs that they are independent of the container's frame.

@ahmedk92
Copy link
Author

@arielelkin Any news or a workaround?

@fjolnir
Copy link
Member

fjolnir commented Sep 24, 2017

It always works "correctly", you're just trying to do something that path.containsPoint does not do. The scaling of the view does not change the path, it simply renders it differently. So the view coordinate and path coordinate are only guaranteed to coincide if the content mode is bottom left (start from 0,0 with no scaling applied). If you want to map a point in the view to the path, you'll have to do a reverse transformation of the point to the path's coordinate space, which could get a little tricky.

To scale a frame using a content mode, PocketSVG uses SVGAdjustCGRectForContentsGravity

FOUNDATION_EXTERN CGRect SVGAdjustCGRectForContentsGravity(CGRect aRect, CGSize aSize, NSString *aGravity);
Using that you'll be able to figure out the actual bounds of the path as rendered in the view, and then transform the point to path space that way. (Difference between path.bounds, and SVGAdjustCGRectForContentsGravity(path.bounds, view.bounds.size, view.layer.contentsGravity))

There's no workaround or anything that PocketSVG will do to make it easier for now, you're going to have to implement it by yourself unless you have a lot of time to wait for us to get around to it.

@fjolnir fjolnir changed the title path.contains(point) correctly works only when SVGImageView contentMode is bottomeLeft Add readonly property view.transformedPath ~~~path.contains(point) correctly works only when SVGImageView contentMode is bottomeLeft~~~ Sep 24, 2017
@fjolnir fjolnir changed the title Add readonly property view.transformedPath ~~~path.contains(point) correctly works only when SVGImageView contentMode is bottomeLeft~~~ Add readonly property view.transformedPath ~path.contains(point) correctly works only when SVGImageView contentMode is bottomeLeft~ Sep 24, 2017
@fjolnir fjolnir changed the title Add readonly property view.transformedPath ~path.contains(point) correctly works only when SVGImageView contentMode is bottomeLeft~ Add readonly property view.transformedPath ~~path.contains(point) correctly works only when SVGImageView contentMode is bottomeLeft~~ Sep 24, 2017
@fjolnir fjolnir changed the title Add readonly property view.transformedPath ~~path.contains(point) correctly works only when SVGImageView contentMode is bottomeLeft~~ Add readonly property view.transformedPath Sep 24, 2017
barakwei pushed a commit to Lightricks/PocketSVG that referenced this issue Sep 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants