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

SVG path import for custom shapes and text #16

Open
chrisgannon opened this issue May 29, 2019 · 43 comments

Comments

@chrisgannon
Copy link

commented May 29, 2019

The ability to draw a bezier path (in a vector program) and convert that path data into usable Zdog code would be very useful.

@desandro desandro changed the title Tool to convert bezier path to Zdog object SVG path parser May 30, 2019

@desandro

This comment has been minimized.

Copy link
Member

commented May 30, 2019

Add a 👍 reaction to this issue if you would like to see this feature added. Do not add +1 comments — They will be deleted.


Thanks for this feature request. Yeah, currently you have to hard code all your path commands. Adding SVG path importing would open up Zdog to a lot more custom designs, including proper typography.

@desandro desandro changed the title SVG path parser SVG path import May 30, 2019

@desandro desandro changed the title SVG path import SVG path import for custom shapes and text May 30, 2019

@chrisgannon

This comment has been minimized.

Copy link
Author

commented May 30, 2019

I have a rudimentary workflow for this using Greensock's MorphSVGPlugin method pathDataToBezier (to convert, well, path data to an array of bezier objects). You then pass that output into my own makeZdogBezier function that creates a Zdog-specific bezier structure.

I'm also animating and sequencing using Greensock.

Here's a few examples:
https://codepen.io/chrisgannon/pen/4ef3e5deaf41cf81415c52112ea2692c
https://codepen.io/chrisgannon/pen/886fb698e67c13b8369a2ec05a640900

@eeropic

This comment has been minimized.

Copy link

commented May 30, 2019

Cooool stuff!!
Was actually working on the same thing, but through Paper.JS -
it can import SVG and makes handling and conversion of the
vector objects very easy

https://codepen.io/eeropic/pen/rgQapW)

zdog-svg2

@chrisgannon

This comment has been minimized.

Copy link
Author

commented May 31, 2019

@eeropic Nice demo! It seems we're both having to use large libraries for just one conversion operation which is quite wasteful and bloated. I would love to see Zdog have this built in.

Here's another demo - this one is pure SVG (with transparency)!

https://codepen.io/chrisgannon/pen/OYadbL
Zdog-Shades

@eeropic

This comment has been minimized.

Copy link

commented May 31, 2019

Agree. But there’s just a lot of stuff to cover if you want to support using defs, embedded css classes for object styles etc. Maybe the SVG parsing part could be forked.

@eeropic

This comment has been minimized.

Copy link

commented Jun 1, 2019

@chrisgannon should we make a PoC with DOMParser? :)
Combined with something like https://github.com/jkroso/parse-svg-path/blob/master/index.js

@turbo

This comment has been minimized.

Copy link

commented Jun 2, 2019

@chrisgannon or @eeropic can either one of you please detail the workflow you've used to create and import these shapes? A short bullet point summary with code samples would be much appreciated. Trying to wrap my head around this 😅.

@chrisgannon

This comment has been minimized.

Copy link
Author

commented Jun 2, 2019

  • Create a path in AI and copy/paste into a text file.

  • Copy just the path data and paste into @greensock's pathDataToBezier method.

  • Pass the result of that into my own makeZdogBezier function

image

@turbo

This comment has been minimized.

Copy link

commented Jun 2, 2019

@chrisgannon Thx, was able to adapt that technique to vectors created with https://vectr.com.

@chrisgannon

This comment has been minimized.

Copy link
Author

commented Jun 2, 2019

If you don't have a Greensock license, https://path2bezier.netlify.com/ is an (untested) alternative to using MorphSVGPlugin to convert path data. I have tried it a few times and it seems to work fine so far.

@turbo

This comment has been minimized.

Copy link

commented Jun 3, 2019

@chrisgannon I chose vectr because its one of the few free online vector tools. I usually work in Inkscape locally. I tested your tool with a few shapes copied from vectr and it seems to work :)

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

@chrisgannon I have used your makeZDogBezier() function, after getting an array from https://path2bezier.netlify.com/. It does a great job, however 3 of my paths close, when they shouldn't. The result of which, generates diagonal lines from certain points along the bezier. You can see from the screenshot that the white outline is the result of using your function. The red shape is the pure SVG!
6AC95006-0E8D-4A50-AD2A-EE4A7ED0B664

@chrisgannon

This comment has been minimized.

Copy link
Author

commented Jun 4, 2019

Do you have closed:true on your constructor? If so set it to false.

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

@chrisgannon

This comment has been minimized.

Copy link
Author

commented Jun 4, 2019

Ok your issue is that you are using a compound path (several paths squished together into one path).

This is @greensock's MorphSVGPlugin pathDataToBezier output of your vector:

image

And this is the output from https://path2bezier.netlify.com/:

image

Greensock deals with it a bit better but I would recommend avoiding compound paths. These converters tend to prefer just one path.

In this particular instance, because of the shape of your vector, I would recommend drawing it with stroked paths instead - that way you will get decent 3D depth in Zdog.

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

@chrisgannon

This comment has been minimized.

Copy link
Author

commented Jun 4, 2019

Yes - currently you're having to fill the area meaning you don't have depth. If you then stroke it, you will add depth but you will also bloat your shape and, as you say, lose definition.

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

@chrisgannon

This comment has been minimized.

Copy link
Author

commented Jun 4, 2019

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

Can anyone tell me how I access the color of a child shape, if I create a new shape, using copyGraph() on a parent shape that has two children?

@turbo

This comment has been minimized.

Copy link

commented Jun 4, 2019

@charlesr1971 Related: #6

Right now there's no easy way to access a child of a parent copied with copyGraph.

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

@turbo Thanks for this information. It kind of makes this API difficult to use. It's one of the most basic requirements. For instance, if I want to create a sphere, I have to add one hemisphere to another. I'm also wondering, at this point, why there isn't a sphere primitive, but that's for another day. But, if I want to change the color of the child hemisphere, dynamically, there is no way to achieve this. If you have an API that allows child objects, there should be some way of accessing them.

@chrisgannon

This comment has been minimized.

Copy link
Author

commented Jun 4, 2019

@charlesr1971 @turbo I think you access the parent's children fairly easily when rendering to SVG.

  • Create an Anchor.

  • Create a Shape.

  • Add the Shape to the Anchor.

  • Apply copyGraph to the Shape several times - this essentially adds the copies to the Anchor.

  • Access the array of copies using Anchor.children

Demo (animated using @greensock) :
https://codepen.io/chrisgannon/pen/405d479f0270d31bbd77e7e7efb49fce

image

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

@turbo You are a life saver. Thank you sir!

@turbo

This comment has been minimized.

Copy link

commented Jun 4, 2019

Wrong person @charlesr1971

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

@chrisgannon Sorry. I said thank you to the wrong person. Thanks Chris. I couldn't believe there was no way to access children!

@turbo

This comment has been minimized.

Copy link

commented Jun 4, 2019

@charlesr1971 Also not sure what you mean by sphere primitive. A hemisphere is a compound shape, whereas the sphere is the default shape:

new Zdog.Shape({
  addTo: illo,
  stroke: 80, // diameter
  color: '#636',
});
@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

OK. I need to make an apology to the zDog team. In fact, you can call the 'children' property on any shape, not just anchors. I managed to access this property on my child hemisphere. Problem solved. It's just me being a stupid newbie!

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

@chrisgannon OK. So, in POV-Ray, we had spheres, boxes, triangles etc. But not hemispheres, so I assumed that a sphere is a primitive shape?

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

@chrisgannon OK. So, shape = sphere by default? Why not call it a 'sphere'?

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

Right. I was a little confused when I couldn't see sphere anywhere? Maybe I missed the default shape example in the docs. I will have another read through...

@turbo

This comment has been minimized.

Copy link

commented Jun 4, 2019

@charlesr1971 Because there is no such thing as a sphere. zDog is not a 3D engine, but a 2.5D engine. A sphere is the same thing as a point, which are both rendered using ellipses/circles on 2D canvas and SVG targets. Since there is neither perspective nor shading, it is inconsequential that "spheres" don't have depth. Again, no spheres here, just shapes.

The Box is also not an actual shape, but a compound group of Rectangles. You can skim the source code for the built-in compound groups to get an idea of how this works.

TL;DR 2.5D engines "trick" you into seeing 3D, but they are just rendering flat shapes. This very different from 3D canvas/SVG engines such as phoria.js or the (now removed) THREE.js canvas renderer.

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

@turbo Thanks for the explanation. 2.5D. Never heard of this, but I have to say I have never seen anything like zDog before. This is partly what makes it so cool. I like the fact that there is no shading. It works well for the whole flat design genre.

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

I like the way, that you can't always tell what the shape is until, it is dragged or animated. It messes with your head, which makes it, so interesting.

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

Coming from a 3D background, I need to get use to the new lingo & it's paradigm.

@turbo

This comment has been minimized.

Copy link

commented Jun 4, 2019

@charlesr1971 I think this is a good way to visualize the difference between 2.5 and 3D: http://www.kevs3d.co.uk/dev/phoria/test3.html

The point light (upper left corner) source is a "sphere" in the zDog sense. It doesn't have any depth, and is not affected by perspective (only in size (stroke in zDog)). The sphere in the centre is a conventional 3D object (which is what you're used to).

3D engines can be used in flat-shading mode to emulate zDog demo, but they will always have a viewport with perspective projection, something that doesn't exist in 2.5D (aka pseudo-3d) engines. Compare the milk demo with zDog's "Box"es - the milk carton has a vanishing point.

what the shape is until, it is dragged or animated

That's the point of 2.5D :). The idea originates from early sprite-layering games: https://images.app.goo.gl/RizABiiiGwFaa2Cz8

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

Nice stuff. I'm just off to destroy those 2 hemispheres & create a nice single default sphere like shape!😉

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

One last thing. How many units in a full rotation [not using TAU]. Do you use 360 or 1? I am doing a rotation animation and I want to detect, when the Anchor has done a half rotation?

@chrisgannon

This comment has been minimized.

Copy link
Author

commented Jun 4, 2019

@charlesr1971 Zdog (and JS) natively use radians but I work in degrees so I have to pass all my radians values to a conversion function (below) so my brain can understand it!

function radiansToDegrees (_val) { return _val * (Math.PI/180); }

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

@chrisgannon Awesome stuff. This is perfect!

@charlesr1971

This comment has been minimized.

Copy link

commented Jun 4, 2019

OK. So, inside my animation function, I have got:

foo.rotate.z += 0.03;
console.log(radiansToDegrees(foo.rotate.z));
// output: 0.00523

I was expecting your function to spit out something between 1 - 360

I need to detect when my object has rotated more than 180 degrees. But at the moment the incremental rotation value never resets itself to zero, when it has carried out a full rotation. It just increments to infinity.

@desandro

This comment has been minimized.

Copy link
Member

commented Jun 5, 2019

@charlesr1971 I love your interest and enthusiam for Zdog and this challenge. But I would appreciate that you use this issue thread to discuss general issues. This issue is currently the #1 requested issue, so back-and-forth conversation adds noise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
5 participants
You can’t perform that action at this time.