Vector Graphics

So github is updated, still using the old object method.

What you can see now is both the face and the icecream (coincidentally the face is looking happily at the icecream…).

If you look at the icecream creation code you’ll see a few values you can tweak:

[lua]    – Create the ice cream polygon object

    local icecream = polygons:new{

        file                = “assets/icecream.json”,

        parent              = sceneGroup,

        bezierSubdivisions  = 5,

        strokeWidthScalar   = 2,

        makeOpenShapesLines = true,

    }[/lua]The first 3 parameters should be obvious enough. I chucked in strokeWidthScalar as the lines here appear to be too thin to me. This value (defaults to 1) simply multiplies up all the strokeWidth values in the file.

makeOpenShapesLines is the boolean to toggle for the two types of behaviour as detailed in an earlier post.

The default is false, and when false, open filled shapes are drawn as closed filled shapes.

When true, they are drawn as a line, only covering the correct border.

I will probably have to tweak this value so it only gets used in the subset of appropriate cases (open filled shape with border - for now it applies to any open filled shape I think).

Same error unfortunately. Using latest daily build 2013.1244

Kilopop - that isn’t a graphics 2.0 daily build, just a normal one.

Any graphics 2.0 daily build has the subversion number greater than 2000 (yours is 1244).

Go here to grab it: https://developer.coronalabs.com/downloads/graphics-daily-builds

I’m about to do my final github update for the day. It has some useful changes.

Get the latest working project here: https://github.com/Rakoonic/Vector-Importer

Here, for example, is the code used to import and create the objects:

[lua]--------------------------------------------------------------

– SETUP -----------------------------------------------------

local __G            = require( “libs.globals” )

local vectorImporter = require( “libs.vectorimporter” )

local storyboard     = require( “storyboard” )

local scene          = storyboard.newScene()


– STORYBOARD ------------------------------------------------

function scene:createScene( event )

    local sceneGroup = self.view

    – Create the ice cream polygon object

    local icecream = vectorImporter:new{

        file                = “assets/icecream.json”,

        parent              = sceneGroup,

        bezierSubdivisions  = 5,

        strokeWidthScalar   = 2,

        makeOpenShapesLines = false,

        autoCenter          = true,

        x                   = __G.screenWidth * 0.3,

        y                   = __G.screenHeight / 2,

    }

    – Create the face polygon object

    local face = vectorImporter:new{

        file               = “assets/face.json”,

        parent             = sceneGroup,

        bezierSubdivisions = 15,

        autoCenter         = true,

        x                  = __G.screenWidth * 0.7,

        y                  = __G.screenHeight / 2,

        scale              = 0.8,

        rotation           = -10,

    }

end


– STORYBOARD LISTENERS --------------------------------------

scene:addEventListener( “createScene”, scene )


– RETURN STORYBOARD OBJECT ----------------------------------

return scene[/lua]So, important tweaks are the changing of the library name (big wow, right?), and some additional properties. Here are all the properties you can pass when creating the object.

  • file - Must be the full path from the root of your project.
  • directory - Must either be a standard Corona directory identifier (system.DocumentsDirectory etc), or a string. The string can be either “docs” or “documents” for system.DocumentsDirectory, or anything else for system.ResourceDirectory (although probably best to stick with “resource” for clarity). Defaults to the resource directory if not supplied.
  • parent - A parent group that this object will be placed into if passed.
  • bezierSubdivisions - How much to subdivide each bezier curve. Note that this produces ‘bezierSubdivisions + 1’ line segments (making 0 a valid option for no subdivision). Defaults to 5 if not supplied.
  • strokeWidthscalar - How much to scale up stroke width values in the file. Defaults to 1 (no change) if not supplied.
  • makeOpenShapesLines - Determines how to handle open filled shapes. Probably needs additional work :wink: Defaults to true.
  • autoCenter - creates the objects at the origin - IE regardless of the actual values of the imported files, it moves all these so the object is centered at 0,0 within the object group. An example is if you look at the face JSON file - the face as a whole is located somewhere around 7000,-7000. If you placed the imported object at 0,0, you aren’t going to see it because it is waaaay off screen. autoCenter can help you position things correctly. Note that this also affects where the object will rotate and scale from. Defaults to false if not supplied.
  • x - The x location you want the object to be drawn at. Defaults to 0 if not supplied.
  • y - The y location you want the object to be drawn at. Defaults to 0 if not supplied.
  • rotation - The rotation of the object. Defaults to 0 if not supplied.
  • scale - The scale of the object. Defaults to 1 (no change) if not supplied.

The object / display group returned also contains a few new functions:

  • obj:getCenter() – Returns the overall center of all the vector objects drawn within the object. Note if you use autoCenter, then this will be 0, 0.
  • obj:getSize() – Returns the overall width and height of all the vector objects drawn within the object.

These two functions are hooks into the object. bounds property which is the bounding rectangle of the entire file imported.

If you wish to access sub-objects, then these are merely the children of the object, so you could access them like this:

[lua]local firstSubObject = obj[1][/lua]etc.

Each sub-object has an additional property called . bounds , which is the bounding rectangle of just that sub-object (similar to the object. bounds ).

The final big change is that the object model now uses a display group as the container for the object, so when you use vectorImporter:new() it returns a display group.

So you can later then just manipulate your vector image in one go by changing the X, Y, scale etc values of this object, and in fact can also chuck it into transitions and whatever (although changing the alpha probably isn’t going to have the effect you want if it has too many overlapping layers).

Final note (for now):

If you want to apply an effect to your vector object, you are going to have to chuck it into a snapshot. This is actually now quite simple, as you can find out the bounds / sizes easily. So something might look like this:

[lua]local border        = 10

local width, height = obj:getSize()

local snapshot      = display.newSnapshot( width + border * 2, height + border * 2 )

snapshot.group:insert( obj )[/lua]

Then you could happily go about adding filters to the snapshot.

Why the border value? Because if you want to add a filter that extends beyond the border of the actual image (say a gaussian blur), then you need this border for the effect to bleed into.

Doh… downloading now.

Thanks for the docs there.

Out of interest, here is the svg for face… it does name the layers and seems to use co-ordinates which are even closer to newPolygon’s attributes:

<?xml version=“1.0” encoding=“utf-8”?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC “-//W3C//DTD SVG 1.1//EN” “http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd”>
<svg version=“1.1” xmlns=“http://www.w3.org/2000/svg” xmlns:xlink=“http://www.w3.org/1999/xlink” x=“0px” y=“0px” width=“1024px”
     height=“768px” viewBox=“0 0 1024 768” enable-background=“new 0 0 1024 768” xml:space=“preserve”>
<g id=“head”>
    <path fill-rule=“evenodd” clip-rule=“evenodd” fill="#FFCCCC" stroke="#000000" stroke-width=“4” stroke-miterlimit=“22.9256” d="
        M595.177,236.692c55.279,30.529,93.466,95.708,93.466,171.19c0,104.746-73.531,259.828-164.236,259.828
        c-90.705,0-164.235-155.082-164.235-259.828c0-74.953,37.655-139.743,92.306-170.541l-53.872-14.949l74.285-20.613l-37.952-67.104
        l67.104,37.952l20.613-74.286l20.613,74.286l67.104-37.952l-37.951,67.104l74.285,20.613L595.177,236.692z"/>
</g>
<g id=“mouth”>
    <path fill-rule=“evenodd” clip-rule=“evenodd” d=“M493.407,464.122c19.311,3.767,38.62,3.741,57.932,0
        c5.27-1.021,9.76,4.392,9.76,9.76s-4.465,8.877-9.76,9.76c-19.312,3.221-38.621,3.606-57.932,0c-5.277-0.985-9.76-4.392-9.76-9.76
        S488.039,464.122,493.407,464.122z”/>
</g>
<g id=“ball”>
    <path fill-rule=“evenodd” clip-rule=“evenodd” fill="#FFFFFF" d=“M468.884,437.882c26.27,0,47.695-21.426,47.695-47.695
        c0-26.271-21.426-47.696-47.695-47.696c-26.27,0-47.696,21.425-47.696,47.696C421.188,416.456,442.614,437.882,468.884,437.882z”/>
    <path fill-rule=“evenodd” clip-rule=“evenodd” fill="#FFFFFF" d=“M570.778,437.882c26.27,0,47.696-21.426,47.696-47.695
        c0-26.271-21.427-47.696-47.696-47.696s-47.695,21.425-47.695,47.696C523.083,416.456,544.509,437.882,570.778,437.882z”/>
</g>
<g id=“pupils”>
    <path fill-rule=“evenodd” clip-rule=“evenodd” d=“M451.595,401.474c10.698,0,19.423-8.726,19.423-19.423
        s-8.726-19.422-19.423-19.422s-19.423,8.725-19.423,19.422S440.897,401.474,451.595,401.474z”/>
    <path fill-rule=“evenodd” clip-rule=“evenodd” d=“M554.306,401.474c10.698,0,19.423-8.726,19.423-19.423
        s-8.725-19.422-19.423-19.422c-10.697,0-19.423,8.725-19.423,19.422S543.608,401.474,554.306,401.474z”/>
</g>
</svg>
 

The ID looks very useful indeed I must admit, but… XML NOOOOO! I hate XML with a passion :slight_smile:

This is gonna have to wait though, I’ve already spent more time on it than I’d planned, and I have a backlog of stuff to finish before my trip, so unless someone else does it, progress might well have to wait until the middle of November (I’m back before then but I’ll have plenty to do then, and it is the deadline for the Corona G2 compo the 14th, so I’ll definitely be busy until then).

Brilliant work @rakoonic. Thanks for your generous time. Good luck with the comp!

kilopop

www.yoozoobooks.com

Also, a very simple solution to the open polygon problem just occurred to me - instead of trying to do it in 1 shape, you do it in two - one is the fill without border, and the other is the border done as a line. So, a solution does indeed exist for that.

Yes, just a bit order to the Illustrator files will do it. No boolean means some think arounds as well at time of drafting in Illustrator. Objects on new layers - line, fill…

Object id would be useful for animation and effects…

Could the illustrator plugin drawscri that generates the .json tweak drawscri to output ids?

Or could .svgs be converted into .json?

Found this link:

http://petesaia.com/2011/11/svg-to-json/

No, I waas referring to the fact that the importer could do it automatically - when it determines a shape is like this, it splits it into 2. I imagine most people aren’t going to want object-level control particularly on the imported stuff, so it makes sense to keep the workflow within Illustrator or whatever as close to normal as possible and let the importer do the hard work.

As for the SVG format, I’d have to spend time looking at it - obviously the format is a bit more complicated than the JSON (which leaves stuff out - did you notice that there are no gradient fills in the JSON one? This is actually something you can almost certainly do in Corona now, and would be rather useful to get in).

The bottom line is I started with JSON because it was the easiest to understand, but I kinda figured it wasn’t going to be the most useful one. What we have now is proof of concept, but it still remains to be seen when I’ll have time to actually get SVG import in. The first thing I’d have to do I imagine is find a detailled breakdown of the SVG format but I doubt that’s tricky, there are probably docs floating around the intrawebs.

@kilopop - sorry, somehow the first time I read your last message I didn’t see that link. Just opened it up now. It looks… short. I’m not sure what it actually does to be honest, as I’ve zero skill in regular expressions. But might be a starting place. I *think* though that lua has an XML import library no? If so, that would go a long way to simplifying things as well.

This is a very interesting topic. However even though JSON can be used to export this kind of data, it’s not specifically designed for vector graphics, and it feels unnecessary to re-invent the wheel when we have SVG. I understand that JSON was a great “proof-of-concept” stepping stone, but I think the way forward would be to somehow build a SVG parser for Corona.

I’m planning to look at this myself. I found the SVG specs here for anyone interested.

http://www.w3.org/TR/SVG/

The problem is: Why is there always so much fun stuff to look into, and so little time to do it?  :wink:

@rakoonic, you’ve done an amazing job in getting this started in a very short amount of time! Much appreciated!

@ingemar: It does seem that taking advantage of the svg format would make sense, especially when you get the benefits of gradients, named layers, etc. Here’s a small sample from Illustrator that has just two simple shapes, one with a gradient. Each is on a separately named layer (“test1” and “test2”:

<?xml version=“1.0” encoding=“utf-8”?>

<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->

<!DOCTYPE svg PUBLIC “-//W3C//DTD SVG 1.1//EN” “http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd”>

<svg version=“1.1” xmlns=“http://www.w3.org/2000/svg” xmlns:xlink=“http://www.w3.org/1999/xlink” x=“0px” y=“0px” width=“792px”

     height=“612px” viewBox=“0 0 792 612” enable-background=“new 0 0 792 612” xml:space=“preserve”>

<g id=“test1”>

    <polygon fill="#ED1C24" stroke="#000000" stroke-miterlimit=“10” points="220.006,148.871 295.466,148.871 306.509,208.994 

        229.822,229.239 216.938,173.411     "/>

</g>

<g id=“test2”>

    <linearGradient id=“SVGID_1_” gradientUnits=“userSpaceOnUse” x1=“261.7236” y1=“178.3193” x2=“360.4971” y2=“178.3193”>

        <stop  offset=“0” style=“stop-color:#FFFFFF”/>

        <stop  offset=“1” style=“stop-color:#000000”/>

    </linearGradient>

    <polygon fill=“url(#SVGID_1_)” stroke="#000000" stroke-miterlimit=“10” points="283.81,125.558 261.724,183.84 297.307,235.988 

        360.497,192.43 314.485,120.65     "/>

</g>

</svg>

Thanks Jeff.

I’ve got the Adobe CS6 collection and was able to open your SVG in Illustrator. A nice and simple start.

I’m planning on putting aside some time this weekend to see what can be done…

I found a lua based importer for XML that reads in the SVG files you guys gave me ok (is called simpleXML).

Together with the specs list Ingemar found, I think that it should be doable. As he points out though, the issue is time, not whether it is possible or not :frowning:

Drawscript is a solution that outputs Illustrator shapes to graphics code for Obj-C, C++, Javascript, CreateJS, Action Script, JSON… but no Corona port yet.

http://www.drawscri.pt/

If you want a Corona port add to the requests in the Drawscript forum to build support here:

http://forums.adobe.com/thread/1175097

Yes, anti-aliasing is supported as long as the device supports HW (GPU-based) anti-aliasing.

Ok, Graphics 2.0 is gonna deliver something I’ve been waiting for since I started using Corona a few years ago… the ability to create custom shapes and texture them with an image! This has so many applications in 2D game development and allows much better workflow in terms of level design, creation & storage!

But!.. and there’s always a but… I cant believe we still dont have a simple UI that would even just allow us place an object on the screen… Of course, we have coded our own, used (& paid for) 3rd party tools, or simply grabbed coords from PS or AI… or whatever art tool you use… so until now, we’ve got around this. But now, this comes to the surface again!

Corona, lets be honest, most of us dont want to use a square, rectangle or triangle or some other flat sided shape in G.2.0… we want to be able to create nice smooth/curved bezier shapes… and fill them with pretty graphics… to create all sorts of objects, terrain… whatever!

Instead, we are now waiting on a 3rd party tool that allows us do this and supports the newPolygon functions… in G2.0.

Am I being unfair? Is it too much to ask? Can you tell me how you “expected” us to use this great new feature? Where we just expected to use simple shapes that we can plot the coords for? Or procedurally generated random stuff?

Personally, I think predesigned level terrain is gonna be one of the biggest use cases for custom shapes with image fill…

But I have no way to draw it… well, not easily/quickly at the moment.

@Walter? Am I being unreasonable to expect a simple interface builder from Corona for my $$$s?

Cheers

This is kind of what I was expecting (hoping for) as well. We currently create all our artwork in Illustrator which is fantastic of course for outputting bitmaps a various sizes. However… There are many cases where it would be amazing to import a vector shape and then be able to change its properties like fill color, etc. Is there some major limitation that prevents Corona from including something like the following to import svg graphics? 

display.newImage Vect ( [parentGroup,] filename, [baseDirectory] width, height )

Thanks!

Jeff

It would likely be fairly simple to write a convertor for the JSON output.

Obviously a fair amount of what Illustrator handles can’t be done or doesn’t have a direct alternative in Corona, but it should be feasible, certainly. I quite like the idea of this and would look into it myself but I don’t use Illustrator and haven’t touched anything beyond the most basic of vector shapes in a looooooong time :frowning:

Go on Rakoonic - you know you want to. Port port port.

But yeah it’s going to be limited. newPolygon doesn’t have beziers so you’d have to turn curves into straight paths in Illustrator. But if you can animate points, vector graphics would transform output work you could do in Corona. I’m scratching my head as to why Illustrator and Corona haven’t quite met - there is only a small bridge between them now with Graphics 2.0…

Who can join them together? Surely there’ll be something to do this? Even via SVG?