-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Fix clipping on css-transformed elements #1084
Conversation
2dbd1e3
to
3aafe82
Compare
This would a good PR. Plus the webdriver task it's being skipped and at least is the first PR sucessful since long time ago. |
@eKoopmans, just implemented this in my own fork, and found that it caused text to not render. The included examples basically rendered as if the the text had a transparent colour. The if function is throwing an error when it tries to check
I fixed this by changing the NodeContainer.prototype.computedStyle = function(type) {
if (this.node.nodeType !== 3) {
return this.node.ownerDocument.defaultView.getComputedStyle(this.node, type);
}
return this.node.ownerDocument.defaultView.getComputedStyle(window.document.createElement('div'), type);
}; Unfortunately, this meant I needed to also update your var drawShadow = function(shadow) {
if (shadow !== "") {
var info = parseShadow(shadow);
if (!info.inset) {
context.shadowOffsetX = info.x;
context.shadowOffsetY = info.y;
context.shadowColor = info.color;
context.shadowBlur = info.blur;
context.fill();
}
}
}; |
Hi @haxxxton, definitely interesting, I wasn't able to reproduce though: Fiddle (text shows up fine for me in this). You'll notice here that for All that said, it should be sufficient to change line 72 of canvas.js to |
@eKoopmans, huge apologies about this.. as this isnt a pull request on a repo im in control of, i had to copy-paste the changes across, and i missed that subtle difference of If you're interested in an npm accessible version of html2canvas that has a number of these PR's merged, you can have a look here. |
Hey @haxxxton, no worries, glad it was a simple fix. Thanks for the npm link! |
Hey @eKoopmans I believe this is causing a issue with:
Check out this fiddle Thanks for your work! |
Hi @gharwood1, you're right that rotations still aren't handled correctly by this pull request (though it's still an improvement) - see issue #1138 for a bit more info, specifically this fiddle illustrates the problem. I've also created a modified version of your fiddle using divs, again to illustrate that clipping isn't being done correctly. On Chrome at least, the fiddle you posted illustrates a second issue, which is that spans (and anything that's not Back to the original clipping issue: As I mentioned at #1138, fixing the clipping issue on rotated spans would require a much more serious rewrite of how clipping is being done in html2canvas. Right now html2canvas stores a stack of bounds information for all of an element's ancestors, and when drawing each element it applies the full stack of clips based on those bounds. Since the rotated element needs a rotated clip, either the bounds need to be stored in a rotated form and all further bounds need to have that rotation as part of their bounds calculation, or (better IMO) clipping and transforms can be applied as html2canvas descends through its children, so it can be applied correctly once and used for all children. |
Important update: This PR introduces new issues for certain CSS transformations and should be used with caution (see my last comment for more info). I apologize for any problems it may have caused. @niklasvh, what are your thoughts on applying each node's clipping to the canvas as you descend down the tree, and restoring the canvas to its previous state on the way back out, rather than the current method of keeping an array of clipping bounds? |
@eKoopmans I had a stab at overflows last night (as well as with transforms). They certainly are a bit problematic. I think we cannot just apply the clips as we descend the tree as the drawing order of the canvas is based on stacking contexts instead of the DOM tree order (which overflows use). One alternative I thought about was applying transforms on a node level instead of globally for the whole stack and descendants, that way you could apply the clips along with the transforms together, in the right order. I've yet to try it out, and probably will first focus on getting the v1.0.0 branch up to par with the current functionality before I continue working on this. |
Right, fair enough. The other alternative could be to keep things as is but apply transforms to the clip vectors... Not sure if that would cause other problems. |
That could be an alternative as well, but may get quite tricky with border-radius bezier curves etc? |
Yeah that was what stopped me when I started going down that path originally. I don't understand all the bezier calculations, especially with the inner and outer borders. |
Will need to think about this a bit more, but for now focusing on getting the remaining features in first. |
932773c
to
1584357
Compare
The idea is that the root element coincides with the canvas, so anything outside the bounds of the root element would be outside the canvas anyway. This isn't quite true in the fancy of fancy CSS transforms, but it's true in normal cases. Mainly, it works around a bug in html2canvas where parent clipping regions are applied incorrectly when rendering child elements. In TerriaJS, this manifests as point markers (e.g. in `#test`'s TerriaJS Test Data -> GeoJSON -> Test overriding styled and unstyled features) not showing up in the generated image. More details of the html2canvas issue can be found here: niklasvh#1084
Bug: Clipping on CSS-transformed elements
Elements with
transform
CSS apply a transformation directly to the canvas, adjusting all canvas actions. This causes incorrectclip
bounds, since the transformations are not considered when calculating bounds.Fix
Any canvas
transform
is temporarily undone while applying clips, then re-applied before rendering the element. This involved givingclip
access to thecontainer
object to test for transforms.Related issues/pull requests
#220, #349, #510, #978