如何根据它包含的文本行设置Raphael JS矩形的宽度和高度?

时间:2013-01-03 05:05:17

标签: javascript size raphael

我正在创建一个矩形元素,我想稍后将其用作SVG圆元素的工具提示。现在,我试图想出一些逻辑来设置矩形元素的高度和宽度,它应该根据它包含的文本行进行更改。我只是创建一个Raphael文本元素并将其翻译在矩形上,以便看起来好像矩形'确实'包含文本。 (这是因为我不应该使用任何第三方工具提示插件,也不能使用jQuery创建和修改它。我也不能使用gRaphael。我应该只使用Raphael矩形元素作为工具提示。)

这就是我在做什么 -

var tipText = "Asoo ok m ml palksksk feesf k\nWeek:X-VAL\nRank:Y-VAL";
//splitting tipText for "\n"
var tipText_seperate = tipText.split("\n");
var tipText_seperate_len = tipText_seperate.length;

var line_len = [];
for(var i=0;i<tipText_seperate_len;i++){
 line_len[i] = tipText_seperate[i].length;  
}

var a = Math.max.apply(Math, line_len);//getting the length of largest line

//setting the width and height of the rectangle
var box = {};
box.width = (a*5)+5;
box.height = tipText_seperate_len*25;

var c = {};
c.x = 10;
c.y = 10;
c.r = paper.rect(c.x,c.y,box.width,box.height,5).attr({fill:'#000000', opacity:0.7});
c.t = paper.text(c.x,c.y,tipText).attr({fill:'#FFFFFF'});
c.t.transform("t"+box.width/2+","+box.height/2);

现在,矩形的大小会针对某些文本行进行调整,而对于某些文本行则不会。在这种情况下,我必须更改box.width的值,这似乎是不正确的。有没有任何有效和逻辑上正确的方法来实现这一目标?请帮忙......

1 个答案:

答案 0 :(得分:3)

诀窍是创建文本元素并使用getBBox获取文本元素的边界框,该边框提供尺寸以及xy值。

以下是一个示例和demo

// Create Raphael and circle set
var Paper = new Raphael('canvas', 300, 300),
    circles = Paper.set();

// Add circles to canvas, setting the tooltip text as a
// data attribute
circles.push(
    Paper.circle(100, 150, 25).data('tooltip', 'Here is some text'),
    Paper.circle(200, 150, 25).data('tooltip', 'And here is \nsome longer text')
);

// Some base styles
circles.attr({
    fill: 'red',
    stroke: 0
});

// Positioning of the tooltip box
var margin = 10,
    padding = 5;

// Hover functions
circles.hover(
    // On hover, create and show tooltip
    function() {
        // If the tooltip already exists on the element, simply
        // show it. If it doesn't then we need to create it.
        if (this.tooltip && this.tooltip.box) {
            this.tooltip.show();
            this.tooltip.box.show();
        } else {
            // Get the x and y positions.
            // We get the 'true y' by deducting the radius
            var x = this.attr('cx'),
                y = this.attr('cy') - this.attr('r');

            // Create the tooltip text, attaching it to the
            // circle itself
            this.tooltip = Paper.text(x, y, this.data('tooltip'));

            // Calculate the bounding box of our text element
            var bounds = this.tooltip.getBBox();

            // Shift the text element in to correct position
            this.tooltip.attr({
                // At this point `y` is equal to the top of the
                // circle arc. When creating a text element, the
                // `x` and `y` values are center points by default,
                // so by deducting half the height we can fake
                // a bottom align. Finally deducting our `margin`
                // value creates the space between the circle and
                // the tooltip.
                y: y - (bounds.height / 2) - margin,
                fill: '#fff'
            });

            // Create the tooltip box, again attaching it to the
            // circle element.
            //
            // The `x`, `y` and dimensions are dynamically calculated
            // using the text element's bounding box and margin/padding
            // values.
            //
            // The `y` value again needs some special treatment,
            // creating the fake bottom align by deducting half the
            // text element's height. We then adjust the `y` further
            // by deducting the sum of the `padding` and `margin`.
            // The `margin` value is needed to create space between
            // the circle and the tooltip, and the `padding` value
            // shifts the box a little higher to create the illusion of
            // padding.
            //
            // Try adjusting the `margin` and `padding` values.
            this.tooltip.box = Paper.rect(bounds.x - padding, bounds.y - (bounds.height / 2) - (padding + margin), bounds.width + (padding * 2), bounds.height + (padding * 2));

            // Style the box and put it behind text element
            this.tooltip.box.attr({
                fill: '#000',
                stroke: 0
            }).toBack();
        }
    },
    // On hover out, hide previously created tooltip
    function() {
        // Hide the tooltip elements
        this.tooltip.box.hide();
        this.tooltip.hide();
    }
);​