raphael icon indicating copy to clipboard operation
raphael copied to clipboard

Top Left Alignment of Paper.text

Open patryk-kabaj-axomic opened this issue 11 years ago • 3 comments

It would be awesome if we had another attribute for paper.text() that could specify top-left alignment. It's difficult to put text inside a box, especially if such text is later subject to change ( for example, if it grows, then Raphael will shift it up ).

I suggest we had 'text-anchor':'leftTop' or something similar that could override the code on line 6245 of raphael.js 2.1.0 ... So

dif = a.y - bb.y;

instead of

dif = a.y - (bb.y + bb.height / 2);

if 'text-anchor': 'topLeft' is specified...

Any thoughts on that? Anybody supports this idea?

Fiddle example: http://jsfiddle.net/patrykkabaj/NGRP9/

I know why this happens - it's because by default the anchor is middle and SVG states that middle is geometrical middle of an object. However, in case of start the vertical middle stays, it would be great to be able to change this behaviour.

Example what currently happens:

Screen Shot 2013-04-18 at 17 14 04

I've quickly tried modifying the code but haven't got time now to investigate it properly.

The method I am talking about and last 3 lines:

tuneText = function (el, params) {
        if (el.type != "text" || !(params[has]("text") || params[has]("font") || params[has]("font-size") || params[has]("x") || params[has]("y"))) {
            return;
        }
        var a = el.attrs,
            node = el.node,
            fontSize = node.firstChild ? toInt(R._g.doc.defaultView.getComputedStyle(node.firstChild, E).getPropertyValue("font-size"), 10) : 10;

        if (params[has]("text")) {
            a.text = params.text;
            while (node.firstChild) {
                node.removeChild(node.firstChild);
            }
            var texts = Str(params.text).split("\n"),
                tspans = [],
                tspan;
            for (var i = 0, ii = texts.length; i < ii; i++) {
                tspan = $("tspan");
                i && $(tspan, {dy: fontSize * leading, x: a.x});
                tspan.appendChild(R._g.doc.createTextNode(texts[i]));
                node.appendChild(tspan);
                tspans[i] = tspan;
            }
        } else {
            tspans = node.getElementsByTagName("tspan");
            for (i = 0, ii = tspans.length; i < ii; i++) if (i) {
                $(tspans[i], {dy: fontSize * leading, x: a.x});
            } else {
                $(tspans[0], {dy: 0});
            }
        }
        $(node, {x: a.x, y: a.y});
        el._.dirty = 1;
        var bb = el._getBBox(),
            dif = a.y - (bb.y + bb.height / 2);
        dif && R.is(dif, "finite") && $(tspans[0], {dy: dif});
    },

patryk-kabaj-axomic avatar Apr 18 '13 16:04 patryk-kabaj-axomic

+1

filipegiusti avatar Aug 14 '14 15:08 filipegiusti

also the same opinion but change to

dif = a.y - bb.y;

not works for IE8, anybody has a workaround for IE?

rufushuang avatar Jun 04 '15 06:06 rufushuang

I think you can use the bounding size of the element to compute the top left position.

var bb1 = obj1.getBBox();

var topLeft= { x: bb1.x - bb1.width / 2, y: bb1.y - bb1.height /2 };

michaelrainerdocumatrix avatar Jun 11 '15 07:06 michaelrainerdocumatrix