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

SVGLoader: Added fill-opacity style support. #15922

Merged
merged 9 commits into from
Mar 26, 2019
Merged

SVGLoader: Added fill-opacity style support. #15922

merged 9 commits into from
Mar 26, 2019

Conversation

flo-Ty
Copy link
Contributor

@flo-Ty flo-Ty commented Mar 7, 2019

@WestLangley
Copy link
Collaborator

/ping @yomboprime

@yomboprime
Copy link
Collaborator

Seems all right to me 👍

@yomboprime
Copy link
Collaborator

yomboprime commented Mar 8, 2019

Now that I think on it, the SVGLoader code is adding the fillOpacity member to the ShapePath instances.
Is that okay?
Previously it was only used the color member, which is defined in the ShapePath class.

@WestLangley
Copy link
Collaborator

I am not sure what is best... Someone who is more-familiar with this will have to speak up.

@yomboprime
Copy link
Collaborator

(I think @Mugen87 can throw light on this.)

According to mrdoob: #15170 (comment)

It seems the SVGLoader should not export the SVG tags, but better the SVG node itself, in the object ShapePath.userData.

So the SVGLoader should put path.userData = { node: node }. And fillOpacity should be obtained by the user with path.userData.node.getAttribute( 'fill-opacity' ) instead of path.fillOpacity.

Additionally I think new functions svgLoader.getRootNode() and svgLoader.getNodePathMap() (map from nodes to paths) could be called (after the SVG is loaded) if the SVG node tree is needed (see linked PR above)

Exporting the SVG tags allows the user to render things like strokes, which are a nice feature to have. For example, the tiger.svg has some shape outlines and not-closed paths that have got tags like stroke-color and stroke-width. They are not rendered currently.

To not break old user code, a new flag svgLoader.exportOnlyVisible or exportOnlyFillShapes, which defaults to true, could be added to let export (when false) the stroke paths which have the fill-color set to none and thus are currently non-visible and are not exported.

If this is done I can also implement a function that generates, given the path points and the stroke SVG properties, the stroke shape (with miter line joining and no linecaps). I can implement later the tags strokeLinejoin, strokeLinecap and strokeMiterLimit among others.

The stroke creation could also be useful for shapes generated from Font text.

@flo-Ty
Copy link
Contributor Author

flo-Ty commented Mar 9, 2019

Okay, this is a little above my experience level, but I would be willing to put in the work to figure out how to do it if it would be useful.

@yomboprime
Copy link
Collaborator

yomboprime commented Mar 9, 2019

Please, let's wait for some feedback. I am no authority here 😊

If my idea is approved, these are the changes:

  • Keep your changes to the parseStyle() function, they are all right.
  • Put path.userData = { node: node }; just after the line paths.push( path );.
  • Revert your other changes to the SVGLoader.

With only this, you can access in your application any SVG tag as I said: path.userData.node.getAttribute( 'fill-opacity' )

Later other tags can be added to the style and I can do a PR for the stroke creation.

About the node map, you can also add it if you want:

  • Add a new this.nodeMap = new Map(); instance variable to the constructor.
  • Add a new this.rootNode = null; instance variable to the constructor.
  • Put nodeMap.set( node, path ); just after the line paths.push( path );.
  • Put this.rootNode = xml.documentElement; just after the line parseNode( xml.documentElement, { fill: '#000' } );

That's all. A getter function for the map and another for the rootNode are optional.

@WestLangley
Copy link
Collaborator

To not break old user code

I wouldn't worry about that in this case. You can always add a migration note.

Please, let's wait for some feedback. I am no authority here

...and I'll defer to @mrdoob and @Mugen87. :-)

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 10, 2019

The suggestion of @mrdoob was to introduce userData to ShapePath which is also done in other classes of three.js. Exposing the entire node is probably the most flexible approach rather than exposing individual node properties over ShapePath.

The problem was that the OP of #15170 never implemented his feedback. This PR could be a good opportunity to finally do so 😉

@flo-Ty
Copy link
Contributor Author

flo-Ty commented Mar 11, 2019

Okay great, I'll get started on implementing the changes @yomboprime suggested in the next couple of days then.

@yomboprime
Copy link
Collaborator

Another thought: As the node properties are not inherited between the nodes, I would also add the style to userData, i.e.:
path.userData = { node: node, style: style };

(The styles do inherit properties from upper nodes)

@yomboprime
Copy link
Collaborator

Looks good. I got already working the stroke creation. In some days I can make a PR.

Screenshot_20190313_012207

I need to implement stroke-miterlimit to limit the miter that goes away in some places as you can see. Will implement also round and bevel joins and also linecaps.

@flo-Ty
Copy link
Contributor Author

flo-Ty commented Mar 13, 2019

Awesome. 👍

@flo-Ty
Copy link
Contributor Author

flo-Ty commented Mar 13, 2019

Woops, had left in the line this.rootNode = xml.documentElement; from the nodeMap suggestion. The final decision was to exclude the nodeMap correct?

@yomboprime
Copy link
Collaborator

Even if the map is out, the root node can be useful. I would leave it. (And declare it in the constructor also, please)

@flo-Ty
Copy link
Contributor Author

flo-Ty commented Mar 13, 2019

K, how does that look?

@yomboprime
Copy link
Collaborator

All right. You keep toggling code 😊

@flo-Ty
Copy link
Contributor Author

flo-Ty commented Mar 13, 2019

Haha, yeah, sorry, had a long day today. :)

@mrdoob mrdoob added this to the r103 milestone Mar 15, 2019
@mrdoob
Copy link
Owner

mrdoob commented Mar 15, 2019

@WestLangley @Mugen87 @yomboprime thanks for the help here guys!

@mrdoob
Copy link
Owner

mrdoob commented Mar 15, 2019

@yomboprime these strokes are looking great!

@mrdoob mrdoob changed the title Add fill-opacity style support to SVGloader.js SVGLoader: Added fill-opacity style support. Mar 15, 2019
@yomboprime
Copy link
Collaborator

yomboprime commented Mar 15, 2019

@yomboprime these strokes are looking great!

I'm making progress... 😃
strokes_20190315_022443

strokes2

@yomboprime
Copy link
Collaborator

I've got the strokes working right.

It is a long function (720 js lines) in THREE.SVGLoader.pointsToStroke( points, style, arcDivisions ) which returns a BufferGeometry.

I could move it to another place like its own class StrokeGeometry in examples/js/geometries/. What do you think?

@mrdoob
Copy link
Owner

mrdoob commented Mar 15, 2019

@yomboprime I was expecting that 😁 I would add it to SVGLoader so it's self contained

@yomboprime
Copy link
Collaborator

@yomboprime I was expecting that grin I would add it to SVGLoader so it's self contained

Do you mean that I have a verbose coding habit? 😃

@yomboprime
Copy link
Collaborator

@btevc You should also modify the svgloader example for the new change in returned data.

@flo-Ty
Copy link
Contributor Author

flo-Ty commented Mar 15, 2019

@yomboprime Oh right, so far only updated my own example.

@mrdoob
Copy link
Owner

mrdoob commented Mar 15, 2019

Do you mean that I have a verbose coding habit? 😃

Not at all! I just suspected converting strokes to geometry was going to be arduous 🙈

@yomboprime
Copy link
Collaborator

yomboprime commented Mar 15, 2019

@btevc You should do:

loader.load( url, function ( data ) {
    var paths = data.paths;

And leave the for loop as it was before

@flo-Ty
Copy link
Contributor Author

flo-Ty commented Mar 16, 2019

@yomboprime Ah, mkay. Will fix this shortly.

@@ -161,9 +161,9 @@
group.position.y = 70;
group.scale.y *= - 1;

for ( var i = 0; i < paths.length; i ++ ) {
for ( key in paths['paths'] ) {
Copy link
Owner

@mrdoob mrdoob Mar 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems over complicated...
You should be able to keep the previous code and just add these lines:

loader.load( url, function ( data ) {
var paths = data.paths;

for ( var i = 0; i < paths.length; i ++ ) {

@flo-Ty
Copy link
Contributor Author

flo-Ty commented Mar 16, 2019

So checks still not passing, anyone know what might be going on here?

@yomboprime
Copy link
Collaborator

yomboprime commented Mar 16, 2019

So checks still not passing, anyone know what might be going on here?

It seems something related to webvr renderer files. I have no Idea, could be a Github bug.

Other PRs seem to be affected by the same webvr files. But the files in the repo do not contain the error.

@yomboprime
Copy link
Collaborator

Bonus: Stroke Font text. I copied the webgl_geometry_text_shapes example and converted the line text to stroke text with minor changes.
strokesText

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 16, 2019

So checks still not passing, anyone know what might be going on here?

Don't worry about that. The travis build was temporarily broken. Should be fixed now.

@yomboprime
Copy link
Collaborator

@Mugen87 Can I make my PR if it depends on this one? I'm not a git expert.

@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 20, 2019

I guess it's better to wait until @mrdoob approves this PR. It has to merged before yours in any event.

BTW: This PR here needs to be mentioned in the migration guide since the parameter of the onLoad() function has changed. User will have to adjust their code similar to webgl_loader_svg.

@mrdoob mrdoob merged commit 00337d9 into mrdoob:dev Mar 26, 2019
@mrdoob
Copy link
Owner

mrdoob commented Mar 26, 2019

Thanks!

@flo-Ty
Copy link
Contributor Author

flo-Ty commented Mar 28, 2019

@yomboprime @WestLangley @Mugen87 @mrdoob Thank you all for helping me through this PR, exciting to participate in this library, even if in a very small way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants