-
-
Notifications
You must be signed in to change notification settings - Fork 792
Support stand-alone Path objects in Canvas #4163
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
base: main
Are you sure you want to change the base?
Conversation
Shouldn't break anything.
HalfWhitt
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realize this is till in flux, and I've only skimmed through its current state, but one big API question occurs to me. In JavaScript...
path.rect(10, 10, 100, 100);
ctx.stroke(path);
path.rect(120, 10, 100, 100);...this will draw one rectangle. If I'm not mistaken, the way you're writing it so far — treating Paths essentially like States — would draw two.
We might want to consider some method of copying paths upon use, so that the recorded drawing actions remember the version of the path that was supplied. That copy would then be an attribute of the drawing action, and could always be edited later, but the "default" JS-like interface that we expose to new / general / most users would remain linear.
I think you're correct about the current behaviour, and yes, the high-level API is in flux precisely because of things like this.
I think it should just be a matter of doing something like: def fill(
self,
color: ColorT | None = None,
fill_rule: FillRule = FillRule.NONZERO,
path: Path2D | None = None,
) -> Fill:
"""Fill the current path...
"""
path = Path2D(path) # copy the path
fill = Fill(color, fill_rule, path)
self._action_target.append(fill)
return fillAlthough right now that does a deep copy, and that may not be right. One question in the API design would be what would you expect the following to do? path1 = Path2D()
circle = path1.arc(100, 100, 10)
path2 = Path2D(path1)
circle.radius = 20Is the radius of the circle in |
Hm, that's a good question. I don't think either implementation is wrong, seeing as how this is outside the HTML-matching API and into our (potentially-useful-but-ever-confusing) nonlinear editing API, so ultimately we get to make the call... My off-the-cuff thought is that in the conceptual framework we've been using, it should be as if we're "going back in time" and altering what the radius was, as if the circle had been created that way from the start — in which case, it should update in both paths. This would imply that path-copying should be shallow. However, I'm open to being convinced otherwise. |
Thinking about it a bit, I could be convinced either way, but I'm currently leaning towards shallow copy being more "pythonic"; and |
|
I think we're approaching the point where this needs to wait for #4159 since there's overlap between the two at the public API level, and I want this to match the outcome from that. One question is what to do about things like this once #4159 is merged: path = Path2D()
path.arc(30, 20, 10)
with canvas.root_state.fill(path=path) as fill:
fill.rect(10, 20, 30, 40)Currently this will ignore the |
I agree, that makes sense. |
|
Thinking about the
|
This is experimental right now - backend only, and checking that I haven't broken anything.
Some tests should fail with coverage errors.
PR Checklist: