Jump to content

How to put rounded rectangle backdrop behind text


SiliconValley
 Share

Recommended Posts

For me Pixi is at the right level of abstraction to build InfoVis tools. Thanks!

My problem now is to add a nice backdrop to text labels. Using a sprite I'm able to put a rectangle below the text, But I want to use a rounded corners rectangle. Experimented with graphics, but all labels backdrops moves together and the PIXI.RoundedRectangle does nothing useful (for me). Here is the solution that works:

 

<!DOCTYPE html>
<html lang="en-us">
<head>
    <meta charset="utf-8" />
    <title>Text background</title>
    <script src="js/pixi.js"></script>
</head>
<body>
    <script>
    // Create the renderer
    var renderer = PIXI.autoDetectRenderer(400, 300, {backgroundColor: 0x1099bb});
    var stage = new PIXI.Container();
    document.body.appendChild(renderer.view);

    // Text
    var str = "This is a long text that I try to put here to see how it wraps";
    var padding = 5;
    var tx = new PIXI.Text(str, {font: '20px Calibri', fill: '#0000ff',
                                 align: 'left',    wordWrap: true, wordWrapWidth: 150});
    tx.position = {x:150+padding, y:250-padding};
    tx.anchor.set(0, 1);

    // Text background (white is a 100x100px solid white image)
    var textbg = new PIXI.Sprite.fromImage("js/scatter/white.png");
    
    // This is not a substitute for the sprite!
    //var textbg = new PIXI.RoundedRectangle(tx.position.x-padding, tx.position.y+padding, tx.width+2*padding, tx.height+2*padding, 10);
    
    // Position the white rectangle below the text
    textbg.position.x = tx.position.x-padding;
    textbg.position.y = tx.position.y+padding;
    textbg.width = tx.width+2*padding;
    textbg.height = tx.height+2*padding;
    textbg.anchor.set(0, 1);

    // Add both to the stage
    stage.addChild(textbg);
    stage.addChild(tx);

 

    // animate it, just for fun
    var delta = 2;
    function animate() {
        tx.position.x += delta;
        textbg.position.x += delta;
        if(tx.position.x > 240 || tx.position.x < 10) delta = -delta;
        renderer.render(stage);
        requestAnimationFrame(animate);
    }
    requestAnimationFrame(animate);
    </script>
    </body>
</html>
 

Any idea?

If I load a rounded corner rectangle texture, the corners are deformed depending on the size of the label.

The same problem appears when I want to add a bunch of independently moving small circles: I have to load a tiny circle as a sprite.

Thanks for your help!

mario

 

Link to comment
Share on other sites

Never mind.

As usual the simple act to ask for help triggers something that guide you to the solution.

Found my error in using PIXI.Graphics. Now I'm happy using Graphics for my symbols and as text backdrop.

The only thing that does not work is if I put text as child of Graphics and use for it coordinates supposed to be relative to the RoundedRectangle. If I do so (text position (0,0)) the text is rendered at the canvas origin, not inside the RoundedRectangle.

Again thanks for your (telepathic) help!

mario

 

<!DOCTYPE html>
<html lang="en-us">
<head>
    <meta charset="utf-8" />
    <title>Text backdrop</title>
    <script src="js/pixi.js"></script>
</head>
<body>
    <script>
    // Create the renderer
    var renderer = PIXI.autoDetectRenderer(400, 300, {backgroundColor: 0x1099bb});
    var stage = new PIXI.Container();
    document.body.appendChild(renderer.view);

    // Text
    var str = "This is a long text that I try to put here to see how it wraps";
    var padding = {x: 10, y: 5};
    var radius = 20;
    var origin = {x: 150, y: 200};
    var tx = new PIXI.Text(str, {font: '20px Calibri', fill: 0x0000FF, align: 'left', wordWrap: true, wordWrapWidth: 150});
    tx.position = {x: origin.x+padding.x, y: origin.y-padding.y};
    tx.anchor.set(0, 1);

    // backdrop
    var textbg = new PIXI.Graphics();
    textbg.beginFill(0xFFFFFF, 1);
    textbg.drawRoundedRect(origin.x, origin.y-(tx.height+2*padding.y), tx.width+2*padding.x, tx.height+2*padding.y, radius);
    textbg.endFill();

    // Add both to the stage
    stage.addChild(textbg);
    stage.addChild(tx);

    var delta = 2;
    function animate() {
        tx.position.x += delta;
        textbg.position.x += delta;
        if(tx.position.x > 240 || tx.position.x < 10) delta = -delta;

      renderer.render(stage);
      requestAnimationFrame(animate);
    }
    requestAnimationFrame(animate);
    </script>
    </body>
</html>
 

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...