Jump to content

Issue with roundedRect border in Pixi


barrard
 Share

Recommended Posts

Hello all, thanks for taking time to read my post.

 

I have an app where users draw shapes in an SVG editor to create objects.  Then the shapes are rendered in Pixi to create an animation.  We used to do the animation in SVG land but Pixi has better performance.  The main issue I'm having right now is my rounded rect corners are not coming out smooth when I try to display in Pixi via the Graphics object, and we have also tried to rasterize the SVG to an image.

 

This is the SVG editor where users create shapes and place them to create objects

image.thumb.png.ed89e2205eeb88976e5f51e0e62eb0b4.png

And this is what Pixi is rendering via the Graphics object.

image.thumb.png.38e20452a2eb40b57678365e4a07df02.png

Here is how I init the Pixi App.  

```

this.app = new PIXI.Application({
  resolution: window.devicePixelRatio,
  antialias: true,
  autoDensity: true
  width: this.elRef.current.clientWidth,
  height: this.elRef.current.clientHeight,
  backgroundColor: 0x666666,
})```
 
and to draw each shape
shapes.forEach(shape => {
  let { color, opacity, width, length, borderRadius, borderThickness, borderColor, x, y } =
  shape
  color = PIXI.utils.string2hex(color)
  x = centerX + x - width / 2
  y = centerY + y - length / 2
  Gfx.beginFill(color, opacity)
  Gfx.lineStyle(borderThickness, borderColor)
  Gfx.drawRoundedRect(x, y, width, length, borderRadius)
  Gfx.endFill()
})
let texture = this.app.renderer.generateTexture(Gfx)
 
 
Thanks again for any help!
 
 
EDIT:  
Originally I was using a raterize approach, where I would render the SVG element into an `<img/>` tag, but it was also giving blurry results.
 
SVG RASTERIZE VERSION
image.png.a4be565c6d2493b774743d256d81b0fd.png
Here is example code for this
let svg = (
<svg
width={totalWidth}
height={totalLength}
// x={isPerson ? 35 : 0}
// y={isPerson ? -35 : 0}
viewBox={isPerson ? `0 0 ${172} ${172}` : null}
xmlns='http://www.w3.org/2000/svg'
>
<defs>{patterns}</defs>
 
<rect
className='rect single-resizer'
width={width}
height={length}
x={leftAdj} // strokeWidth / 2
y={topAdj} // strokeWidth / 2
opacity={__typename === 'Zone' ? '0.5' : '1'}
fill={color}
style={{
strokeWidth: __typename === 'Structure' ? 0 : borderThickness, // borderThickness,
stroke: '#000000',
}}
/>
 
let svgRender = ReactDOMServer.renderToStaticMarkup(svg)
 
let blob = new Blob([svgRender], { type: 'image/svg+xml' })
 
let url = URL.createObjectURL(blob)
 
var img = new Image()
img.src = url
 
//nd then making my texxture
const base = new PIXI.BaseTexture(img)
let texture = new PIXI.Texture(base)
Edited by barrard
Link to comment
Share on other sites

The problem with Graphics inside a renderTexture is that it doesnt have antialias, you have to use tricks with new MSAA support (only in webGL2!) , like here for the circle: https://pixijs.io/examples/#/plugin-picture/blend-modes.js

graphics-smooth is alternative - it uses mega-shader, its faster than antialias, but it has some problems on fills.

Link to comment
Share on other sites

Thanks for the response Ivan.  This helped a bit as you can see.

image.png.c9f882608c20319514cc2a0a6e5b0bba.png

Is there some kind of resolution option I can adjust?  Or other trick, like maybe generate the Graphic as very large then reduce to normal size to get a crisper render?

Link to comment
Share on other sites

Upscale?  I would love to try and trow together  a minimal demo, but I think I found some more clues that may help.

 

I found that when i do render.generateTexture(Gfx)  I can also add some scale and resolution params, so I got a much better render now with

this.app.renderer.generateTexture(
Gfx,
PIXI.SCALE_MODES.LINEAR,
10
)

image.png.7a49b9f2ea41c6edef4f3a310932c715.png 

The shapes I'm drawing are coming from SVG properties.  Our SVG editor can only do squares (currently), so to make circles we just add border radius.  Do you know if the borderRadius of an SVG maps well to a Graphics.drawRoundedRect?  Looks like the border radius is not playing well maybe?   

Thanks again for your help Ivan!

 

Link to comment
Share on other sites

if you use that texture in a sprite that will be scaled 10 times, then yes, you need resolution 10 :)

SVG  is always pain when you work with it in canvas2d or webgl. So far no one made universal solution, there are always problems with scaling. 

As for border-radius, i think you can make minimal example of what you want for it?

Link to comment
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...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...