এসভিজি পাঠ্য উপাদানের প্রস্থ পান


105

আমি একটি এসভিজি ফাইলের জন্য কিছু ইসসিএমএসক্রিপ্ট / জাভাস্ক্রিপ্টে কাজ করছি widthএবং heightএর textআশেপাশের একটি আয়তক্ষেত্রটি পুনরায় আকার দিতে পারব বলে একটি উপাদানটি পাওয়া দরকার । এইচটিএমএলে আমি উপাদানটিতে বৈশিষ্ট্যগুলি offsetWidthএবং offsetHeightবৈশিষ্ট্যগুলি ব্যবহার করতে সক্ষম হব তবে মনে হয় যে এই বৈশিষ্ট্যগুলি অনুপলব্ধ।

এখানে একটি খণ্ড যা আমার সাথে কাজ করা প্রয়োজন। আমি যখনই পাঠ্যটি পরিবর্তন করি তখন আমাকে আয়তক্ষেত্রটির প্রস্থ পরিবর্তন করতে হবে তবে আমি কীভাবে উপাদানটির আসল width(পিক্সেলে) পেতে পারি তা জানি না text

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

কোন ধারনা?

উত্তর:


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

এবং তারপরে রেক্টরের বৈশিষ্ট্যগুলি সেট করুন।

লিঙ্ক: getBBox()এসভিজি ভি 1.1 মানক।


4
ধন্যবাদ। আমি আরও একটি ফাংশন পেয়েছি যা প্রস্থে সহায়তা করতে পারে। textElement.getComputedTextLength ()। আমি আজ রাতে দু'বার চেষ্টা করে দেখব যা আমার পক্ষে আরও ভাল কাজ করে।
স্টিফেন সোরেনসেন

5
আমি এই গত সপ্তাহে সঙ্গে খেলছিলাম; getComputesTextLength () পদ্ধতিটি আমি চেষ্টা করেছি সেগুলির জন্য getBBox ()। প্রস্থের মতো একই ফলাফলটি ফিরে পেয়েছে, তাই আমি কেবল প্রস্থ এবং বাক্সটি নিয়েছিলাম, কারণ আমার প্রস্থ এবং উচ্চতা উভয়ই প্রয়োজন। আমি নিশ্চিত নই যে পাঠ্য দৈর্ঘ্য প্রস্থের চেয়ে পৃথক হবে এমন কোনও পরিস্থিতি রয়েছে কিনা: আমি মনে করি সম্ভবত একাধিক লাইনের উপরে পাঠ্য বিভাজনের মতো পাঠ্য বিন্যাসে সহায়তা করার জন্য এই পদ্ধতিটি সরবরাহ করা হয়েছিল, তবে সীমাবদ্ধ বাক্সটি একটি জেনেরিক পদ্ধতি উপলব্ধ সমস্ত (?) উপাদানগুলিতে।
নিকফিটজ

2
সমস্যাটি হচ্ছে, যদি পাঠ্যটি কোনও পাথ অনুসরণ করে, তবে প্রস্থটি পাঠ্যের আসল প্রস্থ নয় (উদাহরণস্বরূপ পাঠ্যটি যদি একটি বৃত্তের পথ অনুসরণ করে তবে বাক্সটি সেই বৃত্তটি ঘিরে রাখে এবং সেই অংশের প্রস্থটি পায় পাঠ্যের প্রস্থটি বৃত্তের চারদিকে ঘুরতে যাওয়ার আগে এর প্রস্থ নয় t আরেকটি বিষয় হ'ল bbox.width 2 এর একটি ফ্যাক্টর দ্বারা বৃহত্তর, সুতরাং যদি উপাদান পরিদর্শক 200 প্রস্থ দেখায় তবে bbox.width 400 হয় I'm আমি নিশ্চিত নই কেন।
trusktr

দৈর্ঘ্যটি আঁকানোর আগে আপনি কীভাবে কাজ করতে পারেন?
নিকোস

7

পাঠ্যটির দৈর্ঘ্য সম্পর্কে লিঙ্কটি মনে হয় যে বিবিক্সকে নির্দেশ করে এবং কম্পিউটারে টেক্সটলেংথ () সামান্য ভিন্ন মান ফিরে পেতে পারে তবে একে অপরের সাথে মোটামুটি কাছাকাছি অবস্থিত ones

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


এই লিঙ্কের জন্য আপনাকে ধন্যবাদ !! আমাকে নিজের মতো করে সমস্ত দৃশ্যের মধ্য দিয়ে যেতে হয়েছিল, তবে এটি সত্যিই খুব ভাল সংক্ষিপ্তসার ... আমার সমস্যাটি ফায়ারফক্সের একটি স্প্যান উপাদানটিতে getBox () ব্যবহার করছিল ... এটি আরও নির্দিষ্ট এবং বিরক্তিকর বিষয় হতে পারে না .. . আবার ধন্যবাদ!
আন্দ্রেস এলিজান্দো

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

আমার জন্য কাজ


আপনার সমাধানটি পাঠ্যের উপাদানটির আসল দৈর্ঘ্যটি দেয় যা সঠিক উত্তর। কিছু উত্তর getBox () ব্যবহার করে যা পাঠ্যটি ঘোরানো না হলে সঠিক হতে পারে।
Netsi1964

2

সামঞ্জস্যতার জন্য এই জাতীয় কিছু সম্পর্কে কীভাবে:

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ভাল ফলাফল আসবে, সুতরাং কোনও আবর্তন এবং সম্ভবত কোনও স্কেলিং (?)


1
getBoundingClientRect অন্য দুটির সাথে একটি সম্ভাব্য ভিন্নতর সমন্বয় ব্যবস্থাতে কাজ করে।
রবার্ট লঙ্গসন

2

নিশ্চিত না কেন, তবে উপরের কোনও পদ্ধতিই আমার পক্ষে কাজ করে না। ক্যানভাস পদ্ধতিতে আমার কিছুটা সাফল্য ছিল, তবে আমাকে সমস্ত ধরণের স্কেল ফ্যাক্টর প্রয়োগ করতে হয়েছিল। এমনকি স্কেল ফ্যাক্টরগুলির সাথে আমার এখনও সাফারি, ক্রোম এবং ফায়ারফক্সের মধ্যে বেমানান ফলাফল রয়েছে।

সুতরাং, আমি নিম্নলিখিত চেষ্টা করেছিলাম:

            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;

দুর্দান্ত এবং দুর্দান্ত সুনির্দিষ্টভাবে কাজ করেছে, তবে কেবল ফায়ারফক্সে। ক্রোম এবং সাফারির জন্য উদ্ধার করার জন্য স্কেল উপাদানগুলি, কিন্তু কোনও আনন্দ নেই। দেখা যাচ্ছে যে সাফারি এবং ক্রোম ত্রুটিগুলি স্ট্রিং দৈর্ঘ্য বা ফন্টের আকারের সাথে লিনিয়ার নয়।

সুতরাং, দুই নম্বর পদ্ধতির। আমি নিষ্ঠুর বলের পদ্ধতির জন্য খুব বেশি যত্ন নিই না, তবে বছরের পর বছর ধরে এ নিয়ে লড়াই করার পরে আমি চেষ্টা করে দেখার চেষ্টা করেছি। আমি প্রতিটি পৃথক মুদ্রণযোগ্য চরিত্রের জন্য ধ্রুবক মান উত্পন্ন করার সিদ্ধান্ত নিয়েছি। সাধারণত এটি এক ধরণের ক্লান্তিকর হবে তবে ভাগ্যক্রমে ফায়ারফক্স খুব নির্ভুল হতে পারে। এখানে আমার দুই অংশের ব্রুট ফোর্স সলিউশনটি দেওয়া হল:

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

দ্রষ্টব্য: উপরের স্নিপেটকে ফায়ারফক্সে এক্সিকিউট করতে হবে মানগুলির একটি সঠিক অ্যারে তৈরি করতে। এছাড়াও, আপনাকে কনসোল লগের অ্যারে আইটেম 32 স্পেস প্রস্থের মান সহ প্রতিস্থাপন করতে হবে।

আমি কেবল ফায়ারফক্সকে স্ক্রিনের পাঠ্যে অনুলিপি করে আমার জাভাস্ক্রিপ্ট কোডে আটকান। আমার মুদ্রণযোগ্য অক্ষর দৈর্ঘ্যের অ্যারে থাকাকালীন আমি একটি 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;
    }

ঠিক আছে, এটা। হিংস্র বল, তবে এটি তিনটি ব্রাউজারেই অত্যন্ত নির্ভুল এবং আমার হতাশার স্তরটি শূন্যে চলে গেছে। ব্রাউজারগুলি বিকশিত হওয়ার সাথে সাথে এটি কতদিন স্থায়ী হবে তা নিশ্চিত নয়, তবে আমার এসভিজি পাঠ্যের জন্য একটি দৃust় ফন্ট ম্যাট্রিক্স প্রযুক্তি বিকাশ করা আমার পক্ষে যথেষ্ট দীর্ঘ হওয়া উচিত।


এখন পর্যন্ত সেরা সমাধান! ভাগ করে নেওয়ার জন্য ধন্যবাদ!
23_18

এটি কার্নিং পরিচালনা করে না
প্যাট করুন

সত্য, তবে আমি যে ফন্টগুলি ব্যবহার করি তার জন্য কিছু আসে যায় না। আমি কিছু সময় পেলে পরের বছর এই পুনরায় ঘুরে দেখব। আমার ক্ষেত্রে কেস বাহ্যিক পদ্ধতির ব্যবহার না করে পাঠ্য মেট্রিকগুলি আরও নির্ভুল করে তোলার বিষয়ে আমার কিছু ধারণা রয়েছে।
এজেন্ট-পি

গ্রেট। স্থানীয় স্ক্রিপ্টে ফ্লাইতে প্রান্তিককরণের চেয়ে আমাকে এসভিজি চার্ট লেবেল স্থিতিশীলভাবে বিন্যস্ত করার অনুমতি দেয়। আরআর থেকে রুবিতে চার্ট দেওয়ার সময় এটি জীবনকে অনেক সহজ করে তোলে। ধন্যবাদ!
লেকস লিন্ডসে

0

এসভিজি স্পেকের এই তথ্যটি ফেরত দেওয়ার জন্য একটি নির্দিষ্ট পদ্ধতি রয়েছে: getComputedTextLength()

var width = textElement.getComputedTextLength(); // returns a pixel number
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.