Captain Harlock

Graphics scale and linewidth

Recommended Posts

Is there a way to scale a Graphics without getting the linewidth scaled as well?

For instance:

var stage = new PIXI.Container();
var graphics = new PIXI.Graphics();

// Set a fill and line style.
var linewidth = 10;
graphics.beginFill(0xFF3300);
graphics.lineStyle(linewidth, 0xffd900, 1);

// Draw a shape.
graphics.moveTo(50, 50);
graphics.lineTo(250, 50);
graphics.lineTo(100, 100);
graphics.endFill();

// Now, scale this Graphics.
var scale = 5;
graphics.scale.set(scale, scale);  // all lines now have width linewidth * scale

In the example above, the vector "shape" gets properly scaled by a factor of 5. Unfortunately, so does the linewidth.

I am trying to render Graphics vector data on top of Google Maps (typically polygons over countries), and when the map gets zoomed in, I want to rescale the data without getting enormous boundaries.

Share this post


Link to post
Share on other sites

There is no out-of-box solution for that, sorry. You can look at the sources and understand why is it that difficult.

Currently, PIXI.Graphics can only use gl.TRIANGLE_STRIP according to https://github.com/pixijs/pixi.js/blob/dev/src/core/graphics/webgl/GraphicsRenderer.js#L77

If you want to make lineWidth independent from, you have to rewrite this method significantly: https://github.com/pixijs/pixi.js/blob/dev/src/core/graphics/webgl/GraphicsRenderer.js#L118 

Dont forget to add some flag that corresponds to drawing mode (triangles or lines) to https://github.com/pixijs/pixi.js/blob/dev/src/core/graphics/webgl/WebGLGraphicsData.js

Share this post


Link to post
Share on other sites

Gotcha. Yeah I looked at the code, and it seems to be triangulating around lines using normals to give them thickness, by an amount of linewidth / 2:

https://github.com/pixijs/pixi.js/blob/dev/src/core/graphics/webgl/utils/buildLine.js

What I'm looking to do is fairly simple, so I'll probably end up writing it in webgl, rather than using Pixi.

Thanks for your response Ivan!

Share this post


Link to post
Share on other sites

Actually, you can do it in pixi with webgl the way I mentioned it, it will be faster :) Just 2 weeks ago we had a coder who did that for plots, but he didnt need polygons. 

Really, hacking those three modules will be easier than doing it from scratch. That way you wont have to care about all those matrices and attributes uploading and uniforms and shaders... You can take pixi from github dev branch, change Graphics and rebuild it.

Share this post


Link to post
Share on other sites

I'm not sure I understand your solution.  Could you give me more details?

Whether it's using TRIANGLE_STRIP or LINES or LINES_STRIP, the buildLine function is still attempting to create a mesh of triangles around a line. That function is invoked if the Polygon has a non-zero lineWidth, so It seems to me that it's the one that needs to change. Am I mistaken?

Share this post


Link to post
Share on other sites

Yeah, so actually you have to create your own build functions, that will use separate WebGLGraphicsData to handle that. Its obvious that you can rebuild webGLData every frame , and builder functions are called only when you change something in the scene. 

You will have to do it in webgl anyway, but pixi takes care about matrices and shaders, and gives you a architecture to follow.

Share this post


Link to post
Share on other sites
On 7/17/2016 at 1:23 PM, ivan.popelyshev said:

Actually, PIXI.Graphics was made for polygons, to render everything as polygons. Do you need ONLY lines or do you need polygons too?

You mentioned that PIXI.Graphics was made for drawing polygons. What if I have to draw a 2D chart  with elements (circles), edges(lines) among them, labels(text), etc. Does it a good idea to use PIXI for this case ?   I tried cytoscape.js, it`s easy and quite good but when I use it with cola.js  for smooth animation and have about 2k elements and 2k edges among them it`s too laggy, so I`m looking for alternative.  I think it`s because cytoscape.js uses canvas2d rendering and I know that cola.js eats almost all CPU memory.

Share this post


Link to post
Share on other sites

@OlegVolkov When I wrote that, Graphics only rendered lines in webgl through polygons. Now there's nativeLine. To make 2k elements and 2k edges its better to understand how graphics works and may be change it somehow. Text should be pre-rendered, but PIXI does that already.

Share this post


Link to post
Share on other sites

inside you node_modules go to @pixi/graphics/lib/core.es.js create a local variable called

this.scale={x:1, y:1}

inside function Geometry around line 3876

Then go to @pixi/graphics/lib/graphics.es.js inside function buildNonNativeLine create a variable

var scales={x:graphicsGeometry.scale.x=== 0 ? 1 : graphicsGeometry.scale.x
, y:graphicsGeometry.scale.y===0 ? 1 : graphicsGeometry.scale.y
}

change all perpx*=width and all perp1x*=width to width/scales.x so the same for y

 

after that change scale in graphicsGeometry relative to graphic scale change

Edited by CamO
forgot

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.