문제

SVG 파일에 대한 ecmascript/javaScript를 작업 중이며 width 그리고 height a text 요소를 둘러싼 사각형을 크기를 조정할 수 있습니다. HTML에서는 사용할 수 있습니다 offsetWidth 그리고 offsetHeight 요소의 속성이지만 해당 속성을 사용할 수없는 것으로 보입니다.

다음은 작업해야 할 파편이 있습니다. 텍스트를 변경할 때마다 사각형의 너비를 변경해야하지만 실제를 얻는 방법을 모르겠습니다. width (픽셀)의 text 요소.

<rect x="100" y="100" width="100" height="100" />
<text>Some Text</text>

어떤 아이디어?

도움이 되었습니까?

해결책

var bbox = textElement.getBBox();
var width = bbox.width;
var height = bbox.height;

그런 다음 그에 따라 RECT의 속성을 설정하십시오.

링크: getBBox() SVG v1.1 표준에서.

다른 팁

텍스트 길이와 관련하여 링크는 bbox를 나타내는 것으로 보이며 getComputedTextLength ()는 약간 다른 값을 반환 할 수 있지만 서로 가깝습니다.

http://bl.ocks.org/mscau/58bba77cdcae42fc2f44

호환성을 위해 이와 같은 것은 어떻습니까 :

function svgElemWidth(elem) {
    var methods = [ // name of function and how to process its result
        { fn: 'getBBox', w: function(x) { return x.width; }, },
        { fn: 'getBoundingClientRect', w: function(x) { return x.width; }, },
        { fn: 'getComputedTextLength', w: function(x) { return x; }, }, // text elements only
    ];
    var widths = [];
    var width, i, method;
    for (i = 0; i < methods.length; i++) {
        method = methods[i];
        if (typeof elem[method.fn] === 'function') {
            width = method.w(elem[method.fn]());
            if (width !== 0) {
                widths.push(width);
            }
        }
    }
    var result;
    if (widths.length) {
        result = 0;
        for (i = 0; i < widths.length; i++) {
            result += widths[i];
        }
        result /= widths.length;
    }
    return result;
}

이것은 세 가지 방법의 유효한 결과의 평균을 반환합니다. 당신은 그것을 개선하여 이상치를 쫓아 내거나 선호 할 수 있습니다. getComputedTextLength 요소가 텍스트 요소 인 경우.

경고 : 의견에서 말했듯이 getBoundingClientRect 까다 롭습니다. 메소드에서 제거하거나이를 사용하는 요소에서만 사용하십시오. getBoundingClientRect 좋은 결과를 반환하므로 회전이없고 스케일링이 없을 것입니다 (?)

document.getElementById('yourTextId').getComputedTextLength();

나를 위해 일했습니다

이유는 확실하지 않지만 위의 방법 중 어느 것도 나에게 효과가 없습니다. 나는 캔버스 방법으로 약간의 성공을 거두었지만 모든 종류의 스케일 요인을 적용해야했습니다. 스케일 요인에도 불구하고 여전히 Safari, Chrome 및 Firefox 사이에 일관성이없는 결과를 얻었습니다.

그래서 나는 다음을 시도했다.

            var div = document.createElement('div');
            div.style.position = 'absolute';
            div.style.visibility = 'hidden';
            div.style.height = 'auto';
            div.style.width = 'auto';
            div.style.whiteSpace = 'nowrap';
            div.style.fontFamily = 'YOUR_FONT_GOES_HERE';
            div.style.fontSize = '100';
            div.style.border = "1px solid blue"; // for convenience when visible

            div.innerHTML = "YOUR STRING";
            document.body.appendChild(div);
            
            var offsetWidth = div.offsetWidth;
            var clientWidth = div.clientWidth;
            
            document.body.removeChild(div);
            
            return clientWidth;

굉장하고 정밀한 일을했지만 Firefox에서만 일했습니다. Chrome과 Safari의 구조에 대한 규모의 요인이지만 기쁨은 없습니다. Safari 및 Chrome 오류는 스트링 길이 또는 글꼴 크기로 선형이 아닙니다.

따라서 2 번 접근하십시오. 나는 무차별 인력 접근법을별로 신경 쓰지 않지만, 몇 년 동안 이것으로 어려움을 겪은 후 나는 그것을 시도하기로 결정했습니다. 각 개별 인쇄용 문자에 대해 일정한 값을 생성하기로 결정했습니다. 일반적으로 이것은 일종의 지루한 일이지만 운 좋게도 Firefox는 매우 정확합니다. 다음은 두 부분 Brute Force 솔루션입니다.

<body>
        <script>
            
            var div = document.createElement('div');
            div.style.position = 'absolute';
            div.style.height = 'auto';
            div.style.width = 'auto';
            div.style.whiteSpace = 'nowrap';
            div.style.fontFamily = 'YOUR_FONT';
            div.style.fontSize = '100';          // large enough for good resolution
            div.style.border = "1px solid blue"; // for visible convenience
            
            var character = "";
            var string = "array = [";
            for(var i=0; i<127; i++) {
                character = String.fromCharCode(i);
                div.innerHTML = character;
                document.body.appendChild(div);
                
                var offsetWidth = div.offsetWidth;
                var clientWidth = div.clientWidth;
                console.log("ASCII: " + i + ", " + character + ", client width: " + div.clientWidth);
                
                string = string + div.clientWidth;
                if(i<126) {
                    string = string + ", ";
                }

                document.body.removeChild(div);
                
            }
        
            var space_string = "! !";
            div.innerHTML = space_string;
            document.body.appendChild(div);
            var space_string_width = div.clientWidth;
            document.body.removeChild(div);
            var no_space_string = "!!";
            div.innerHTML = no_space_string;
            document.body.appendChild(div);
            var no_space_string_width = div.clientWidth;
            console.log("space width: " + (space_string_width - no_space_string_width));
            document.body.removeChild(div);


            string = string + "]";
            div.innerHTML = string;
            document.body.appendChild(div);
            </script>
    </body>

참고 : 위의 스 니펫은 정확한 값 배열을 생성하기 위해 Firefox로 실행되어야합니다. 또한 어레이 항목 32를 콘솔 로그의 공간 너비 값으로 바꿔야합니다.

화면 텍스트에 Firefox를 복사하여 JavaScript 코드에 붙여 넣습니다. 인쇄 가능한 문자 길이의 배열이 있으므로 Get 너비 기능을 구현할 수 있습니다. 코드는 다음과 같습니다.

const LCARS_CHAR_SIZE_ARRAY = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 26, 46, 63, 42, 105, 45, 20, 25, 25, 47, 39, 21, 34, 26, 36, 36, 28, 36, 36, 36, 36, 36, 36, 36, 36, 27, 27, 36, 35, 36, 35, 65, 42, 43, 42, 44, 35, 34, 43, 46, 25, 39, 40, 31, 59, 47, 43, 41, 43, 44, 39, 28, 44, 43, 65, 37, 39, 34, 37, 42, 37, 50, 37, 32, 43, 43, 39, 43, 40, 30, 42, 45, 23, 25, 39, 23, 67, 45, 41, 43, 42, 30, 40, 28, 45, 33, 52, 33, 36, 31, 39, 26, 39, 55];


    static getTextWidth3(text, fontSize) {
        let width = 0;
        let scaleFactor = fontSize/100;
        
        for(let i=0; i<text.length; i++) {
            width = width + LCARS_CHAR_SIZE_ARRAY[text.charCodeAt(i)];
        }
        
        return width * scaleFactor;
    }

글쎄, 그게 다야. 무자비한 힘이지만 3 개의 브라우저 모두에서 매우 정확하며 좌절 수준은 0으로갔습니다. 브라우저가 발전함에 따라 얼마나 오래 지속 될지 확실하지 않지만 SVG 텍스트에 대한 강력한 글꼴 메트릭 기술을 개발하기에 충분히 길어야합니다.

SVG Spec에는이 정보를 반환하는 특정 방법이 있습니다. getComputedTextLength()

var width = textElement.getComputedTextLength(); // returns a pixel number
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top