HTML5 ক্যানভাস ctx.fillText লাইন ব্রেক করবে না?


108

লেখাটিতে "\ n" অন্তর্ভুক্ত করা থাকলে আমি ক্যানভাসে পাঠ্য যোগ করতে সক্ষম হতে পারি বলে মনে হচ্ছে না। মানে লাইন বিরতিগুলি / কাজ দেখায় না।

ctxPaint.fillText("s  ome \n \\n <br/> thing", x, y);

উপরের কোডটি আঁকবে "s ome \n <br/> thing" এক লাইনে ।

এটি কি ফিলটেক্সটের একটি সীমাবদ্ধতা বা আমি এটি ভুল করছি? "\ n" গুলি সেখানে রয়েছে, এবং মুদ্রিত হয় না, তবে সেগুলিও কাজ করে না।


1
আপনি কি শেষের দিকে পৌঁছে স্বয়ংক্রিয়ভাবে মোড়ানো করতে চান? বা কেবল পাঠ্যটিতে উপস্থিত নিউলাইন চরগুলি বিবেচনার জন্য?
গ্যাব্রিয়েল পেট্রিওলি

একাধিক লাইনে পাঠ্য মোড়ানো।
টাওয়ার

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


টিএল; ডিআর: হয় fillText()একাধিকবার কল করুন এবং আলাদা করতে আপনার ফন্টের উচ্চতাটি ব্যবহার করুন, বা বিকাশকারী.মোজিলা.আর.ইন.ইউএস / ডকস / ওয়েব / এপিআই / টেক্সটমেট্রিক্স ডেভেলপার.মোজিলা.আর.ইউইউএস / ডকস / ওয়েবে / এপিআই /… - বা, নীচে খুব জটিল "সমাধানগুলি" এর মধ্যে একটি ব্যবহার করুন যা টেক্সটমেট্রিক্স ব্যবহার করে না ...
অ্যান্ড্রু

উত্তর:


62

আমি ভয় পাচ্ছি এটি ক্যানভাসের সীমাবদ্ধতা ' fillText । মাল্টি-লাইন সমর্থন নেই। সবচেয়ে খারাপ, লাইনের উচ্চতা পরিমাপের কোনও অন্তর্নির্মিত উপায় নেই, কেবল প্রস্থ, এটি নিজেকে আরও শক্ত করে তোলা!

অনেক লোক তাদের নিজস্ব মাল্টি-লাইন সমর্থন লিখেছেন, সম্ভবত সবচেয়ে উল্লেখযোগ্য প্রকল্প যা মজিলা স্কাই রাইটার

পাঠ্যটির fillTextউচ্চতা প্রতিবারের জন্য y মান যুক্ত করার সময় আপনাকে একাধিক কল করতে হবে তার সংক্ষিপ্তসার । (এম এর প্রস্থ পরিমাপ করা স্কাই রাইটাররা আনুমানিক পাঠ্যের জন্য যা করেন, আমি বিশ্বাস করি))


ধন্যবাদ! আমার মনে হয়েছিল এটি বিরক্তিকর হবে ... স্কাইওয়াইটার সম্পর্কে জানতে পেরে ভাল লাগছে, তবে ফিলটেক্সট () উন্নত না হওয়া পর্যন্ত আমি কেবল "অপেক্ষা" করব। এটি আমার ক্ষেত্রে মারাত্মক গুরুত্বপূর্ণ চুক্তি ছিল না। হাহ, কোনও লাইনের উচ্চতা নেই, এটি উদ্দেশ্য মতো কেউ করেছে। : ডি
স্পেকট্রালজাম্প

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

1
কিছু অতিরিক্ত বৈশিষ্ট্য জন্য measureText()যোগ করা হয়েছে যা আমি সমস্যা সমাধানের করতে পারে মনে। Chrome সক্ষম করার জন্য একটি পতাকা রয়েছে, তবে অন্যান্য ব্রাউজারগুলি এখনও তা করে না!
SWdV

@ এসডাব্লুডিভি কেবল স্পষ্ট করে বলতে, এগুলি বছরের পর বছর ধরে চলেছিল, আমাদের ব্যবহারের যথেষ্ট পরিমাণ গ্রহণ না হওয়া অবধি এটি এখনও কয়েক বছর হতে পারে :(
সাইমন স্যারিস

67

আপনি যদি কেবলমাত্র পাঠ্যের নতুন লাইনের চরিত্রের যত্ন নিতে চান তবে আপনি নতুন লাইনে পাঠ্যকে বিভক্ত করে এবং একাধিকবার কল করে তা অনুকরণ করতে পারেন fillText()

Http://jsfiddle.net/BaG4J/1/ এর মতো কিছু

var c = document.getElementById('c').getContext('2d');
c.font = '11px Courier';
    console.log(c);
var txt = 'line 1\nline 2\nthird line..';
var x = 30;
var y = 30;
var lineheight = 15;
var lines = txt.split('\n');

for (var i = 0; i<lines.length; i++)
    c.fillText(lines[i], x, y + (i*lineheight) );
canvas{background-color:#ccc;}
<canvas id="c" width="150" height="150"></canvas>


আমি শুধু (ধারণা একটি মোড়ানো প্রমাণ করেছেন নিদিষ্ট প্রস্থ এ পরম মোড়ানো। কোন হ্যান্ডলিং, ব্রেকিং এখনো শব্দ )
উদাহরণ http://jsfiddle.net/BaG4J/2/

var c = document.getElementById('c').getContext('2d');
c.font = '11px Courier';

var txt = 'this is a very long text to print';

printAt(c, txt, 10, 20, 15, 90 );


function printAt( context , text, x, y, lineHeight, fitWidth)
{
    fitWidth = fitWidth || 0;
    
    if (fitWidth <= 0)
    {
         context.fillText( text, x, y );
        return;
    }
    
    for (var idx = 1; idx <= text.length; idx++)
    {
        var str = text.substr(0, idx);
        console.log(str, context.measureText(str).width, fitWidth);
        if (context.measureText(str).width > fitWidth)
        {
            context.fillText( text.substr(0, idx-1), x, y );
            printAt(context, text.substr(idx-1), x, y + lineHeight, lineHeight,  fitWidth);
            return;
        }
    }
    context.fillText( text, x, y );
}
canvas{background-color:#ccc;}
<canvas id="c" width="150" height="150"></canvas>


এবং একটি শব্দ-মোড়ানো ( স্পেসে ব্রেকিং ) ধারণার প্রমাণ। http://jsfiddle.net/BaG4J/5/
এ উদাহরণ

var c = document.getElementById('c').getContext('2d');
c.font = '11px Courier';

var txt = 'this is a very long text. Some more to print!';

printAtWordWrap(c, txt, 10, 20, 15, 90 );


function printAtWordWrap( context , text, x, y, lineHeight, fitWidth)
{
    fitWidth = fitWidth || 0;
    
    if (fitWidth <= 0)
    {
        context.fillText( text, x, y );
        return;
    }
    var words = text.split(' ');
    var currentLine = 0;
    var idx = 1;
    while (words.length > 0 && idx <= words.length)
    {
        var str = words.slice(0,idx).join(' ');
        var w = context.measureText(str).width;
        if ( w > fitWidth )
        {
            if (idx==1)
            {
                idx=2;
            }
            context.fillText( words.slice(0,idx-1).join(' '), x, y + (lineHeight*currentLine) );
            currentLine++;
            words = words.splice(idx-1);
            idx = 1;
        }
        else
        {idx++;}
    }
    if  (idx > 0)
        context.fillText( words.join(' '), x, y + (lineHeight*currentLine) );
}
canvas{background-color:#ccc;}
<canvas id="c" width="150" height="150"></canvas>


দ্বিতীয় এবং তৃতীয় উদাহরণগুলিতে আমি সেই measureText()পদ্ধতিটি ব্যবহার করছি যা দেখায় যে মুদ্রণের সময় একটি স্ট্রিংটি কত দীর্ঘ হবে ( পিক্সেলগুলিতে )।


কিভাবে পুরো দীর্ঘ লেখার ন্যায্যতা?
আমিরহোসেইন টারমাস্ট

আপনার যদি দীর্ঘ, ন্যায়সঙ্গত পাঠ্যের প্রয়োজন হয় তবে আপনি কেন একটি ক্যানভাস ব্যবহার করবেন?
মাইক 'পোম্যাক্স' কামারম্যানস

39

সম্ভবত এই দলে কিছুটা দেরি হচ্ছে, তবে আমি ক্যানভাসে নিখুঁতভাবে মোড়ানোর জন্য নিম্নলিখিত টিউটোরিয়ালটি পেয়েছি।

http://www.html5canvastutorials.com/tutorials/html5-canvas-wrap-text-tutorial/

সেখান থেকে আমি বহু লাইনগুলি কাজ করার কথা ভাবতে সক্ষম হয়েছি (দুঃখিত রামিরেজ, আপনারা আমার পক্ষে কাজ করেননি!)। ক্যানভাসে পাঠ্য মোড়ানোর জন্য আমার সম্পূর্ণ কোডটি নিম্নরূপ:

<script type="text/javascript">

     // http: //www.html5canvastutorials.com/tutorials/html5-canvas-wrap-text-tutorial/
     function wrapText(context, text, x, y, maxWidth, lineHeight) {
        var cars = text.split("\n");

        for (var ii = 0; ii < cars.length; ii++) {

            var line = "";
            var words = cars[ii].split(" ");

            for (var n = 0; n < words.length; n++) {
                var testLine = line + words[n] + " ";
                var metrics = context.measureText(testLine);
                var testWidth = metrics.width;

                if (testWidth > maxWidth) {
                    context.fillText(line, x, y);
                    line = words[n] + " ";
                    y += lineHeight;
                }
                else {
                    line = testLine;
                }
            }

            context.fillText(line, x, y);
            y += lineHeight;
        }
     }

     function DrawText() {

         var canvas = document.getElementById("c");
         var context = canvas.getContext("2d");

         context.clearRect(0, 0, 500, 600);

         var maxWidth = 400;
         var lineHeight = 60;
         var x = 20; // (canvas.width - maxWidth) / 2;
         var y = 58;


         var text = document.getElementById("text").value.toUpperCase();                

         context.fillStyle = "rgba(255, 0, 0, 1)";
         context.fillRect(0, 0, 600, 500);

         context.font = "51px 'LeagueGothicRegular'";
         context.fillStyle = "#333";

         wrapText(context, text, x, y, maxWidth, lineHeight);
     }

     $(document).ready(function () {

         $("#text").keyup(function () {
             DrawText();
         });

     });

    </script>

cআমার ক্যানভাসের আইডি কোথায় এবং textআমার পাঠ্যবক্সের আইডি।

আপনি সম্ভবত দেখতে পাচ্ছেন যে একটি অ-মানক ফন্ট ব্যবহার করছি। আপনি @ ফন্ট-ফেস ব্যবহার করতে পারবেন যতক্ষণ না আপনি ক্যানভাসের হেরফের জন্য কিছু পাঠ্য PRIOR এ ফন্ট ব্যবহার করেছেন - অন্যথায় ক্যানভাস ফন্টটি তুলবে না font

আশা করি এটি কাউকে সাহায্য করবে।


26

পাঠ্যগুলিকে লাইনে বিভক্ত করুন এবং প্রতিটি আলাদাভাবে আঁকুন:

function fillTextMultiLine(ctx, text, x, y) {
  var lineHeight = ctx.measureText("M").width * 1.2;
  var lines = text.split("\n");
  for (var i = 0; i < lines.length; ++i) {
    ctx.fillText(lines[i], x, y);
    y += lineHeight;
  }
}

17

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

CanvasRenderingContext2D.prototype.wrapText = function (text, x, y, maxWidth, lineHeight) {

    var lines = text.split("\n");

    for (var i = 0; i < lines.length; i++) {

        var words = lines[i].split(' ');
        var line = '';

        for (var n = 0; n < words.length; n++) {
            var testLine = line + words[n] + ' ';
            var metrics = this.measureText(testLine);
            var testWidth = metrics.width;
            if (testWidth > maxWidth && n > 0) {
                this.fillText(line, x, y);
                line = words[n] + ' ';
                y += lineHeight;
            }
            else {
                line = testLine;
            }
        }

        this.fillText(line, x, y);
        y += lineHeight;
    }
}

বেসিক ব্যবহার:

var myCanvas = document.getElementById("myCanvas");
var ctx = myCanvas.getContext("2d");
ctx.fillStyle = "black";
ctx.font = "12px sans-serif";
ctx.textBaseline = "top";
ctx.wrapText("Hello\nWorld!",20,20,160,16);

আমি একত্রিত একটি বিক্ষোভ এখানে: http://jsfiddle.net/7RdbL/


কবজির মতো কাজ করেছেন। ধন্যবাদ.
কুজ্জি

13

আমি সবেমাত্র ক্যানভাস রেন্ডারিং কনটেক্সট 2 ডি প্রসারিত করেছি যাতে দুটি ফাংশন যুক্ত হয়েছে: এমিলফিলটেক্সট এবং এমএল স্ট্রোকটেক্সট।

আপনি গিটহাবের শেষ সংস্করণটি খুঁজে পেতে পারেন :

এই ফাংশনগুলির সাহায্যে আপনি একটি বাক্সে মিলটিলাইন পাঠ্য / স্ট্রোক করতে পারেন। আপনি পাঠ্যটি উল্লম্ব এবং অনুভূমিক সারিবদ্ধ করতে পারেন। (এটি অ্যাকাউন্টে নেয় \ n এবং এটি পাঠ্যকেও ন্যায়সঙ্গত করতে পারে)।

প্রোটোটাইপগুলি হ'ল:

mlFillText ফাংশন (পাঠ্য, এক্স, ওয়াই, ডাব্লু, এইচ, ভি, এলাইন, এইচাইনাইন, লাইন হাইট); ফাংশন এমএল স্ট্রোকটেক্সট (পাঠ্য, এক্স, ওয়াই, ডাব্লু, এইচ, ভিএলাইন, এইচাইনাইন, লাইনহাইট);

যেখানে vAlign হতে পারে: "শীর্ষ", "কেন্দ্র" বা "বোতাম" এবং hAlign হতে পারে: "বাম", "কেন্দ্র", "ডান" বা "ন্যায়সঙ্গত"

আপনি এখানে lib পরীক্ষা করতে পারেন: http://jsfiddle.net/4WRZj/1/

এখানে চিত্র বর্ণনা লিখুন

লাইব্রেরির কোডটি এখানে:

// Library: mltext.js
// Desciption: Extends the CanvasRenderingContext2D that adds two functions: mlFillText and mlStrokeText.
//
// The prototypes are: 
//
// function mlFillText(text,x,y,w,h,vAlign,hAlign,lineheight);
// function mlStrokeText(text,x,y,w,h,vAlign,hAlign,lineheight);
// 
// Where vAlign can be: "top", "center" or "button"
// And hAlign can be: "left", "center", "right" or "justify"
// Author: Jordi Baylina. (baylina at uniclau.com)
// License: GPL
// Date: 2013-02-21

function mlFunction(text, x, y, w, h, hAlign, vAlign, lineheight, fn) {
    text = text.replace(/[\n]/g, " \n ");
    text = text.replace(/\r/g, "");
    var words = text.split(/[ ]+/);
    var sp = this.measureText(' ').width;
    var lines = [];
    var actualline = 0;
    var actualsize = 0;
    var wo;
    lines[actualline] = {};
    lines[actualline].Words = [];
    i = 0;
    while (i < words.length) {
        var word = words[i];
        if (word == "\n") {
            lines[actualline].EndParagraph = true;
            actualline++;
            actualsize = 0;
            lines[actualline] = {};
            lines[actualline].Words = [];
            i++;
        } else {
            wo = {};
            wo.l = this.measureText(word).width;
            if (actualsize === 0) {
                while (wo.l > w) {
                    word = word.slice(0, word.length - 1);
                    wo.l = this.measureText(word).width;
                }
                if (word === "") return; // I can't fill a single character
                wo.word = word;
                lines[actualline].Words.push(wo);
                actualsize = wo.l;
                if (word != words[i]) {
                    words[i] = words[i].slice(word.length, words[i].length);
                } else {
                    i++;
                }
            } else {
                if (actualsize + sp + wo.l > w) {
                    lines[actualline].EndParagraph = false;
                    actualline++;
                    actualsize = 0;
                    lines[actualline] = {};
                    lines[actualline].Words = [];
                } else {
                    wo.word = word;
                    lines[actualline].Words.push(wo);
                    actualsize += sp + wo.l;
                    i++;
                }
            }
        }
    }
    if (actualsize === 0) lines[actualline].pop();
    lines[actualline].EndParagraph = true;

    var totalH = lineheight * lines.length;
    while (totalH > h) {
        lines.pop();
        totalH = lineheight * lines.length;
    }

    var yy;
    if (vAlign == "bottom") {
        yy = y + h - totalH + lineheight;
    } else if (vAlign == "center") {
        yy = y + h / 2 - totalH / 2 + lineheight;
    } else {
        yy = y + lineheight;
    }

    var oldTextAlign = this.textAlign;
    this.textAlign = "left";

    for (var li in lines) {
        var totallen = 0;
        var xx, usp;
        for (wo in lines[li].Words) totallen += lines[li].Words[wo].l;
        if (hAlign == "center") {
            usp = sp;
            xx = x + w / 2 - (totallen + sp * (lines[li].Words.length - 1)) / 2;
        } else if ((hAlign == "justify") && (!lines[li].EndParagraph)) {
            xx = x;
            usp = (w - totallen) / (lines[li].Words.length - 1);
        } else if (hAlign == "right") {
            xx = x + w - (totallen + sp * (lines[li].Words.length - 1));
            usp = sp;
        } else { // left
            xx = x;
            usp = sp;
        }
        for (wo in lines[li].Words) {
            if (fn == "fillText") {
                this.fillText(lines[li].Words[wo].word, xx, yy);
            } else if (fn == "strokeText") {
                this.strokeText(lines[li].Words[wo].word, xx, yy);
            }
            xx += lines[li].Words[wo].l + usp;
        }
        yy += lineheight;
    }
    this.textAlign = oldTextAlign;
}

(function mlInit() {
    CanvasRenderingContext2D.prototype.mlFunction = mlFunction;

    CanvasRenderingContext2D.prototype.mlFillText = function (text, x, y, w, h, vAlign, hAlign, lineheight) {
        this.mlFunction(text, x, y, w, h, hAlign, vAlign, lineheight, "fillText");
    };

    CanvasRenderingContext2D.prototype.mlStrokeText = function (text, x, y, w, h, vAlign, hAlign, lineheight) {
        this.mlFunction(text, x, y, w, h, hAlign, vAlign, lineheight, "strokeText");
    };
})();

এবং এখানে ব্যবহার উদাহরণ:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

var T = "This is a very long line line with a CR at the end.\n This is the second line.\nAnd this is the last line.";
var lh = 12;

ctx.lineWidth = 1;

ctx.mlFillText(T, 10, 10, 100, 100, 'top', 'left', lh);
ctx.strokeRect(10, 10, 100, 100);

ctx.mlFillText(T, 110, 10, 100, 100, 'top', 'center', lh);
ctx.strokeRect(110, 10, 100, 100);

ctx.mlFillText(T, 210, 10, 100, 100, 'top', 'right', lh);
ctx.strokeRect(210, 10, 100, 100);

ctx.mlFillText(T, 310, 10, 100, 100, 'top', 'justify', lh);
ctx.strokeRect(310, 10, 100, 100);

ctx.mlFillText(T, 10, 110, 100, 100, 'center', 'left', lh);
ctx.strokeRect(10, 110, 100, 100);

ctx.mlFillText(T, 110, 110, 100, 100, 'center', 'center', lh);
ctx.strokeRect(110, 110, 100, 100);

ctx.mlFillText(T, 210, 110, 100, 100, 'center', 'right', lh);
ctx.strokeRect(210, 110, 100, 100);

ctx.mlFillText(T, 310, 110, 100, 100, 'center', 'justify', lh);
ctx.strokeRect(310, 110, 100, 100);

ctx.mlFillText(T, 10, 210, 100, 100, 'bottom', 'left', lh);
ctx.strokeRect(10, 210, 100, 100);

ctx.mlFillText(T, 110, 210, 100, 100, 'bottom', 'center', lh);
ctx.strokeRect(110, 210, 100, 100);

ctx.mlFillText(T, 210, 210, 100, 100, 'bottom', 'right', lh);
ctx.strokeRect(210, 210, 100, 100);

ctx.mlFillText(T, 310, 210, 100, 100, 'bottom', 'justify', lh);
ctx.strokeRect(310, 210, 100, 100);

ctx.mlStrokeText("Yo can also use mlStrokeText!", 0 , 310 , 420, 30, 'center', 'center', lh);

Uncaught ReferenceError: Words is not definedআমি যদি ফন্ট পরিবর্তন করার চেষ্টা করি। উদাহরণস্বরূপ: ctx.font = '40px Arial';-
এটিকে

বিটিডব্লিউ, নরকটি Words(কেস-সংবেদনশীল) পরিবর্তনশীল কোথা থেকে আসে ?? এটি কোথাও সংজ্ঞায়িত করা হয়নি।
কোডটির

1
@psychobrm আপনি নিখুঁতভাবে ঠিক বলেছেন এটি একটি বাগ (আমি ইতিমধ্যে এটি ঠিক করেছি)। কোডের এই অংশটি কেবল তখনই কার্যকর করা হয় যদি আপনি কোনও শব্দ দুটি লাইনে বিভক্ত করতে হয়। ধন্যবাদ!
jbaylina

আমি আমার প্রয়োজনীয় কিছু আপগ্রেড করেছি: স্পেস রেন্ডার করা, শীর্ষস্থানীয় / পিছনে নতুন লাইনের রেন্ডার করা, স্ট্রোক রেন্ডার এবং একটি কল পূরণ করুন (দু'বার পাঠ্য মাপবেন না), আমারও পুনরাবৃত্তি পরিবর্তন করতে হয়েছে, যেহেতু for inবর্ধিত সঙ্গে ভাল কাজ করে না Array.prototype। আপনি কি এটি গিথুবে রাখতে পারেন যাতে আমরা এটিতে পুনরাবৃত্তি করতে পারি?
psycho brm

@psychobrm আমি আপনার পরিবর্তনগুলি একত্রিত করেছি। ধন্যবাদ!
jbaylina

8

জাভাস্ক্রিপ্ট ব্যবহার করে আমি একটি সমাধান তৈরি করেছি। এটি সুন্দর নয় তবে এটি আমার জন্য কাজ করেছে:


function drawMultilineText(){

    // set context and formatting   
    var context = document.getElementById("canvas").getContext('2d');
    context.font = fontStyleStr;
    context.textAlign = "center";
    context.textBaseline = "top";
    context.fillStyle = "#000000";

    // prepare textarea value to be drawn as multiline text.
    var textval = document.getElementByID("textarea").value;
    var textvalArr = toMultiLine(textval);
    var linespacing = 25;
    var startX = 0;
    var startY = 0;

    // draw each line on canvas. 
    for(var i = 0; i < textvalArr.length; i++){
        context.fillText(textvalArr[i], x, y);
        y += linespacing;
    }
}

// Creates an array where the <br/> tag splits the values.
function toMultiLine(text){
   var textArr = new Array();
   text = text.replace(/\n\r?/g, '<br/>');
   textArr = text.split("<br/>");
   return textArr;
}

আশা করি এইটি কাজ করবে!


1
হ্যালো, আমি অনুমান আমার টেক্সট এই Var টেক্সট = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" মত হয়; তাহলে ক্যানভাসে কি হ'ল ???
অমল নাভসূপে

এটি ক্যানভাসের বাইরে চলে যাবে, কারণ @ রামিরেজ ম্যাক্সউইথের প্যারামিটারটি পূরণের জন্য দেয়নি :)
KaHa6uc

6

@ গেবি পেট্রোলি দ্বারা প্রদত্ত শব্দ মোড়ানোর জন্য (স্পেসে বিরতি) কোডটি খুব সহায়ক। নিউলাইন চরিত্রগুলির জন্য সমর্থন সরবরাহ করার জন্য আমি তার কোডটি প্রসারিত করেছি \n। এছাড়াও, প্রায়শই এটি সীমাবদ্ধ বাক্সের মাত্রাগুলি রাখার জন্য দরকারী, সুতরাং multiMeasureText()প্রস্থ এবং উচ্চতা উভয়ই প্রদান করে।

আপনি কোডটি এখানে দেখতে পারেন: http://jsfiddle.net/jeffchan/WHgaY/76/


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

5

এখানে কলিনের একটি সংস্করণ রয়েছে wrapText()যা এর সাথে উল্লম্ব কেন্দ্রীভূত পাঠ্যকে সমর্থন করে context.textBaseline = 'middle':

var wrapText = function (context, text, x, y, maxWidth, lineHeight) {
    var paragraphs = text.split("\n");
    var textLines = [];

    // Loop through paragraphs
    for (var p = 0; p < paragraphs.length; p++) {
        var line = "";
        var words = paragraphs[p].split(" ");
        // Loop through words
        for (var w = 0; w < words.length; w++) {
            var testLine = line + words[w] + " ";
            var metrics = context.measureText(testLine);
            var testWidth = metrics.width;
            // Make a line break if line is too long
            if (testWidth > maxWidth) {
                textLines.push(line.trim());
                line = words[w] + " ";
            }
            else {
                line = testLine;
            }
        }
        textLines.push(line.trim());
    }

    // Move text up if centered vertically
    if (context.textBaseline === 'middle')
        y = y - ((textLines.length-1) * lineHeight) / 2;

    // Render text on canvas
    for (var tl = 0; tl < textLines.length; tl++) {
        context.fillText(textLines[tl], x, y);
        y += lineHeight;
    }
};

5

আপনার যদি কেবল দুটি লাইনের পাঠ্যের প্রয়োজন হয় তবে আপনি এগুলিকে দুটি পৃথক ফিলটেক্সট কলগুলিতে বিভক্ত করতে পারেন এবং প্রত্যেককে একটি আলাদা বেসলাইন দিতে পারেন।

ctx.textBaseline="bottom";
ctx.fillText("First line", x-position, y-position);
ctx.textBaseline="top";
ctx.fillText("Second line", x-position, y-position);

4

এই প্রশ্নটি ক্যানভাস কীভাবে কাজ করে তা বিবেচনা করে না। আপনি যদি একটি লাইন বিরতি চান কেবল আপনার পরবর্তীগুলির স্থানাঙ্কগুলি সামঞ্জস্য করুন ctx.fillText

ctx.fillText("line1", w,x,y,z)
ctx.fillText("line2", w,x,y,z+20)

3

আমি মনে করি আপনি এখনও সিএসএসের উপর নির্ভর করতে পারেন

ctx.measureText().height doesnt exist.

ভাগ্যক্রমে, সিএসএস হ্যাক-আরড্রি (সিএসএস পরিমাপ ব্যবহারের পুরানো বাস্তবায়ন স্থির করার আরও উপায়ের জন্য টাইপোগ্রাফিক মেট্রিক্স) এর মাধ্যমে, আমরা একই ফন্ট-বৈশিষ্ট্যযুক্ত একটির অফসেটহাইট পরিমাপের মাধ্যমে পাঠ্যের উচ্চতা খুঁজে পেতে পারি:

var d = document.createElement(”span”);
d.font = 20px arial
d.textContent = Hello world!”
var emHeight = d.offsetHeight;

থেকে: http://www.html5rocks.com/en/tutorials/canvas/texteffects/


এটি আপনার কাছে প্রতিবার পরিমাপ করার মতো একটি উপাদান তৈরি করার মেমরি থাকলে আপনার পক্ষে একটি ভাল সমাধান। আপনি ctx.save()তারপর, ctx.font = '12pt Arial' তারপর, করতে পারেন parseInt( ctx.font, 10 )। নোট করুন যে আমি এটি সেট করার সময় 'pt' ব্যবহার করি। এটি তখন পিএক্সে অনুবাদ করবে এবং ফন্টের উচ্চতা হিসাবে ব্যবহারের জন্য একটি অঙ্কে রূপান্তর করতে সক্ষম হবে।
এরিক হোডনস্কি

3

আমি এই দৃশ্যের জন্য এখানে একটি ছোট গ্রন্থাগার তৈরি করেছি: ক্যানভাস-টেক্সট

এটি বহু-লাইনে পাঠ্যকে উপস্থাপন করে এবং এটি শালীন প্রান্তিককরণ মোড সরবরাহ করে।

এটি ব্যবহার করার জন্য, আপনাকে এটি ইনস্টল করতে হবে বা একটি সিডিএন ব্যবহার করতে হবে।

স্থাপন

npm install canvas-txt --save

জাভাস্ক্রিপ্ট

import canvasTxt from 'canvas-txt'

var c = document.getElementById('myCanvas')
var ctx = c.getContext('2d')

var txt = 'Lorem ipsum dolor sit amet'

canvasTxt.fontSize = 24

canvasTxt.drawText(ctx, txt, 100, 200, 200, 200)

এটি অবস্থান / মাত্রার সাথে একটি অদৃশ্য বাক্সে পাঠ্য রেন্ডার করবে:

{ x: 100, y: 200, height: 200, width: 200 }

উদাহরণ ফিডল

/* https://github.com/geongeorge/Canvas-Txt  */

const canvasTxt = window.canvasTxt.default;
const ctx = document.getElementById('myCanvas').getContext('2d');

const txt = "Lorem ipsum dolor sit amet";
const bounds = { width: 240, height: 80 };

let origin = { x: ctx.canvas.width / 2, y: ctx.canvas.height / 2, };
let offset = { x: origin.x - (bounds.width / 2), y: origin.y - (bounds.height / 2) };

canvasTxt.fontSize = 20;

ctx.fillStyle = '#C1A700';
ctx.fillRect(offset.x, offset.y, bounds.width, bounds.height);

ctx.fillStyle = '#FFFFFF';
canvasTxt.drawText(ctx, txt, offset.x, offset.y, bounds.width, bounds.height);
body {
  background: #111;
}

canvas {
  border: 1px solid #333;
  background: #222; /* Could alternatively be painted on the canvas */
}
<script src="https://unpkg.com/canvas-txt@2.0.6/build/index.js"></script>

<canvas id="myCanvas" width="300" height="160"></canvas>


আমি এগিয়ে গিয়েছিলাম এবং উদাহরণটিকে "স্ব-দস্তাবেজ" সহায়তা করতে কিছু পরিবর্তনশীল সংজ্ঞায়িত করেছি। এটি ক্যানভাসের মধ্যে বাউন্ডিং বক্সকে কেন্দ্র করে পরিচালনা করে। আমি পিছনে একটি আয়তক্ষেত্রও যুক্ত করেছি, সুতরাং আপনি আসলে এটি সম্পর্ককে কেন্দ্র করে দেখতে পারেন। মহান কাজ! +1 একটি ছোট জিনিস আমি লক্ষ্য করেছি যে, যে রেখাগুলি মোড়লে তাদের অগ্রণী স্থানগুলি দমন করা যায় না। আপনি প্রতিটি লাইনটি ছাঁটাই করতে চাইতে পারেন যেমন ctx.fillText(txtline.trim(), textanchor, txtY)আমি কেবল এটি আপনার ওয়েবসাইটে আপনার ইন্টারেক্টিভ ডেমোতে লক্ষ্য করেছি।
মিঃ পলিহর্ল

@ মিঃপল্লিহর্য়াল উত্তর সাফ করার জন্য আপনাকে ধন্যবাদ। আমি ট্রিম ইস্যুটি ঠিক করেছি এবং 2.0.9সংস্করণটি প্রকাশ করেছি । ডেমো সাইটটি প্যাকেজ সংস্করণ আপডেট করে স্থির করা হয়েছে। একাধিক স্পেস নিয়ে সমস্যা আছে। আমি জানি না একটি মতামত প্যাকেজ নিয়ে যেতে বা সমস্যাটিকে উপেক্ষা করা ভাল। একাধিক জায়গা থেকে এর জন্য অনুরোধ পেয়েছি। আমি এগিয়ে গিয়ে যাইহোক ট্রিম যোগ করেছি। Lorem ipsum dolor, sit <many spaces> amet এই কারণেই আমি এটি প্রথম স্থানে না করলাম। আপনি কি মনে করেন যে আমি একাধিক স্পেস বিবেচনা করব এবং কেবলমাত্র একটি থাকলে তা সরিয়ে ফেলব?
জিওন জর্জ

সম্পাদনা করুন: মনে হচ্ছে স্ট্যাকওভারফ্লো কোড ব্লকটিও বহু স্থানগুলিকে উপেক্ষা করে
জিয়ন জর্জ

2

আমি <p>এটিও সম্ভব বলে মনে করি না, তবে এটির জন্য একটি উপাদান হ'ল একটি উপাদান তৈরি করা এবং এটি জাভাস্ক্রিপ্টের সাথে স্থাপন করা।


হ্যাঁ, আমি এটিই করার কথা ভাবছি। এটি ঠিক এর সাথেই fillText()এবং strokeText()আপনি CSS যা করতে পারে তার বাইরেও কিছু করতে পারেন।
টাওয়ার

আমি এটি পরীক্ষা করে দেখিনি, তবে আমি মনে করি এটি একটি আরও ভাল সমাধান হতে পারে - এখানে অন্য সমাধানগুলি ফিলটেক্সট () ব্যবহার করে এটি তৈরি করে যাতে পাঠ্যটি নির্বাচন করা যায় না (বা সম্ভবত আটকানো যায়)।
জেরি আশের

2

একই সমস্যা হওয়ার কারণে আমি এটি পেরিয়ে এসেছি। আমি ভেরিয়েবল ফন্টের আকারের সাথে কাজ করছি, সুতরাং এটি এটি বিবেচনায় নেয়:

var texts=($(this).find('.noteContent').html()).split("<br>");
for (var k in texts) {
    ctx.fillText(texts[k], left, (top+((parseInt(ctx.font)+2)*k)));
}

যেখানে .noteContent কনটেনটেটেবল ডিভ যা ব্যবহারকারী সম্পাদনা করেছেন (এটি প্রতিটি ফাংশন jQuery এ বাসা বেঁধেছে), এবং ctx.font "14px আরিয়াল" (লক্ষ্য করুন যে পিক্সেল আকারটি প্রথম আসে)


0

ক্যানভাস উপাদান নিউলাইন '\ n', ট্যাব '\ t' বা <বিআর /> ট্যাগের মতো অক্ষরগুলিকে সমর্থন করে না।

এটি চেষ্টা করুন:

var newrow = mheight + 30;
ctx.fillStyle = "rgb(0, 0, 0)";
ctx.font = "bold 24px 'Verdana'";
ctx.textAlign = "center";
ctx.fillText("Game Over", mwidth, mheight); //first line
ctx.fillText("play again", mwidth, newrow); //second line 

অথবা সম্ভবত একাধিক লাইন:

var textArray = new Array('line2', 'line3', 'line4', 'line5');
var rows = 98;
ctx.fillStyle = "rgb(0, 0, 0)";
ctx.font = "bold 24px 'Verdana'";
ctx.textAlign = "center";
ctx.fillText("Game Over", mwidth, mheight); //first line

for(var i=0; i < textArray.length; ++i) {
rows += 30;
ctx.fillText(textArray[i], mwidth, rows); 
}  

0

সমস্যার জন্য আমার ইএস 5 সমাধান:

var wrap_text = (ctx, text, x, y, lineHeight, maxWidth, textAlign) => {
  if(!textAlign) textAlign = 'center'
  ctx.textAlign = textAlign
  var words = text.split(' ')
  var lines = []
  var sliceFrom = 0
  for(var i = 0; i < words.length; i++) {
    var chunk = words.slice(sliceFrom, i).join(' ')
    var last = i === words.length - 1
    var bigger = ctx.measureText(chunk).width > maxWidth
    if(bigger) {
      lines.push(words.slice(sliceFrom, i).join(' '))
      sliceFrom = i
    }
    if(last) {
      lines.push(words.slice(sliceFrom, words.length).join(' '))
      sliceFrom = i
    }
  }
  var offsetY = 0
  var offsetX = 0
  if(textAlign === 'center') offsetX = maxWidth / 2
  for(var i = 0; i < lines.length; i++) {
    ctx.fillText(lines[i], x + offsetX, y + offsetY)
    offsetY = offsetY + lineHeight
  }
}

এ বিষয়ে আরো তথ্য আমার ব্লগে

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.