如何在画布上绘制段落文本 [英] How to paragraph text drawn onto canvas

查看:29
本文介绍了如何在画布上绘制段落文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我根据教程做了一个在线小测验,这是我第一次使用画布功能.当我输入自己的问题时,它们显示为一行,我不知道如何拆分这些行,以便正确显示问题.有人可以帮忙吗?

这是我目前所拥有的:

<头><风格>身体{背景颜色:黑色;}#ccontainer{宽度:550px;边距:0 自动;边距顶部:110px;}#myCanvas{/*/背景:#FFF;/*/}</风格><脚本>window.onload = 函数(){var canvas = document.getElementById("myCanvas");var context = canvas.getContext("2d");var quizbg = new Image();var 问题 = 新字符串;var Option1 = 新字符串;var Option2 = 新字符串;var Option3 = 新字符串;var mx=0;无功我=0;var CorrectAnswer = 0;var qnumber = 0;var rightanswers=0;var wronganswers=0;var QuizFinished = false;无功锁=假;var textpos1=25;var textpos2=145;var textpos3=230;var textpos4=325;var Questions = ["哪位曼联球员以 31 个进球赢得了
 2008 年金靴奖?","博比·查尔顿的足球生涯是在哪家具乐部开始的?","韦恩·鲁尼是哪一年赢得 BBC 青年体育人物奖的?年奖?"];var 选项 = [["Cristiano Ronaldo","Wayne Rooney","Ryan Giggs"],["Manchester United","Manchester City","Chelsea"],["2002","2003","2004"]];quizbg.onload = 函数(){context.drawImage(quizbg, 0, 0);设置问题();}quizbg.src = "quizbg.png";设置问题 = 函数(){问题=问题[qnumber];CorrectAnswer=1+Math.floor(Math.random()*3);if(CorrectAnswer==1){Option1=Options[qnumber][0];Option2=Options[qnumber][1];Option3=Options[qnumber][2];}if(CorrectAnswer==2){Option1=Options[qnumber][2];Option2=Options[qnumber][0];Option3=Options[qnumber][1];}if(CorrectAnswer==3){Option1=Options[qnumber][1];Option2=Options[qnumber][2];Option3=Options[qnumber][0];}context.textBaseline = "中";context.font = "16pt sans-serif,Arial";context.fillText(问题,20,textpos1);context.font = "14pt sans-serif,Arial";context.fillText(Option1,20,textpos2);context.fillText(Option2,20,textpos3);context.fillText(Option3,20,textpos4);}//设置问题canvas.addEventListener('click',ProcessClick,false);函数 ProcessClick(ev) {我=ev.y-canvas.offsetTop;如果(ev.y == 未定义){我的 = ev.pageY - canvas.offsetTop;}如果(锁定){重置Q();}//如果锁定别的{if(my>110 && my<180){GetFeedback(1);}if(my>200 && my<270){GetFeedback(2);}if(my>290 && my<360){GetFeedback(3);}}//!锁}//处理点击获取反馈 = 函数(a){如果(a==正确答案){context.drawImage(quizbg, 0,400,75,70,480,110+(90*(a-1)),75,70);正确答案++;//drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)}别的{context.drawImage(quizbg, 75,400,75,70,480,110+(90*(a-1)),75,70);错误答案++;}锁=真;context.font = "14pt sans-serif,Arial";context.fillText("再次点击继续",20,380);}//得到反馈重置Q=函数(){锁=假;context.clearRect(0,0,550,400);qnumber++;if(qnumber==Questions.length){EndQuiz();}别的{context.drawImage(quizbg, 0, 0);设置问题();}}结束测验=函数(){canvas.removeEventListener('click',ProcessClick,false);context.drawImage(quizbg, 0,0,550,90,0,0,550,400);context.font = "20pt sans-serif,Arial";context.fillText("你已经完成了测验!",20,100);context.font = "16pt sans-serif,Arial";context.fillText("正确答案:"+String(rightanswers),20,200);context.fillText("错误答案:"+String(wronganswers),20,240);}};<身体><div id="ccontainer"><canvas id="myCanvas" width="550" height="400"></canvas>

谢谢!

解决方案

您可以使用 context.measureText 来获取给定文本的宽度.

这是一个使用 context.measureText 换行文本的函数,用于测量句子中的每个单词,并在当前行超过给定宽度时换行:

演示:http://jsfiddle.net/m1erickson/mQFDB/

function wrapText(context, text, x, y, maxWidth, fontSize, fontFace){var words = text.split(' ');var 行 = '';var lineHeight=fontSize;context.font = fontSize + "px" + fontFace;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);行 = 单词 [n] + ' ';y += 线高;}别的 {线 = 测试线;}}context.fillText(line, x, y);返回(y);}

您可以像这样在画布上绘制文本:

var lastY=wrapText(context,"Hello",20,40,100,14,"verdana");

lastY 变量保存最后一行换行文本的 y 坐标.因此,您可以在 lastY 开始新文本加上一些填充:

lastY=wrapText(context,"World",20,lastY+20,100,14,"verdana");

此模式可让您在画布上制作文本环绕的段落(或者在您的情况下,在画布上制作问题和多项选择题答案).

I have made a short quiz online following a tutorial, this is my first time using the canvas function. When I have typed my own questions, they appear as one line, and I am not sure how to break the lines up, in order for the question to display properly. Can anyone help?

Here is what I have so far:

<!DOCTYPE HTML>
<html>
<head>
<style>
    body{
        background-color: black;
    }

    #ccontainer{

        width: 550px;
        margin: 0 auto;
        margin-top: 110px;
    }

    #myCanvas{
        /*/ background: #FFF; /*/
    }
    </style>

    <script>
        window.onload = function(){

            var canvas = document.getElementById("myCanvas");
            var context = canvas.getContext("2d");
            var quizbg = new Image();
            var Question = new String;
            var Option1 = new String;
            var Option2 = new String;
            var Option3 = new String;
            var mx=0;                                   
            var my=0;
            var CorrectAnswer = 0;
            var qnumber = 0;
            var rightanswers=0;
            var wronganswers=0;
            var QuizFinished = false;
            var lock = false;
            var textpos1=25;
            var textpos2=145;
            var textpos3=230;
            var textpos4=325;
            var Questions = ["Which Manchester United Player won 
 the 2008 Golden Boot with 31 Goals?","At which club did Bobby Charlton start his football career?","Which year did Wayne Rooney win the BBC Young Sports Personality of the year award?"];
            var Options = [["Cristiano Ronaldo","Wayne Rooney","Ryan Giggs"],["Manchester United","Manchester City","Chelsea"],["2002","2003","2004"]];


            quizbg.onload = function(){
              context.drawImage(quizbg, 0, 0);
              SetQuestions();
            }
            quizbg.src = "quizbg.png";



            SetQuestions = function(){

                Question=Questions[qnumber];
                CorrectAnswer=1+Math.floor(Math.random()*3);

                if(CorrectAnswer==1){Option1=Options[qnumber][0];Option2=Options[qnumber][1];Option3=Options[qnumber][2];}
                if(CorrectAnswer==2){Option1=Options[qnumber][2];Option2=Options[qnumber][0];Option3=Options[qnumber][1];}
                if(CorrectAnswer==3){Option1=Options[qnumber][1];Option2=Options[qnumber][2];Option3=Options[qnumber][0];}

                context.textBaseline = "middle";
                context.font = "16pt sans-serif,Arial";
                context.fillText(Question,20,textpos1);
                context.font = "14pt sans-serif,Arial";
                context.fillText(Option1,20,textpos2);
                context.fillText(Option2,20,textpos3);
                context.fillText(Option3,20,textpos4);


            }//SetQuestions

                canvas.addEventListener('click',ProcessClick,false);

                function ProcessClick(ev) {
                    my=ev.y-canvas.offsetTop;
                    if(ev.y == undefined){
                        my = ev.pageY - canvas.offsetTop;
                }

                if(lock){
            ResetQ();
        }//if lock

        else{

        if(my>110 && my<180){GetFeedback(1);}
        if(my>200 && my<270){GetFeedback(2);}
        if(my>290 && my<360){GetFeedback(3);}

        }//!lock

            }//process click

            GetFeedback = function(a){

              if(a==CorrectAnswer){
                context.drawImage(quizbg, 0,400,75,70,480,110+(90*(a-1)),75,70);
                rightanswers++;
                //drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
              }
              else{
                context.drawImage(quizbg, 75,400,75,70,480,110+(90*(a-1)),75,70);
                wronganswers++;
              }
              lock=true;
              context.font = "14pt sans-serif,Arial";
              context.fillText("Click again to continue",20,380);
            }//get feedback



        ResetQ= function(){
        lock=false;
        context.clearRect(0,0,550,400);
        qnumber++;
        if(qnumber==Questions.length){EndQuiz();}
        else{
        context.drawImage(quizbg, 0, 0);
        SetQuestions();}
        }


        EndQuiz=function(){
        canvas.removeEventListener('click',ProcessClick,false);
        context.drawImage(quizbg, 0,0,550,90,0,0,550,400);
        context.font = "20pt sans-serif,Arial";
        context.fillText("You have finished the quiz!",20,100);
        context.font = "16pt sans-serif,Arial";
        context.fillText("Correct answers: "+String(rightanswers),20,200);
        context.fillText("Wrong answers: "+String(wronganswers),20,240);
        }






        };
    </script>

</head>
 <body>

<div id="ccontainer">
    <canvas id="myCanvas" width="550" height="400"></canvas>
</div>

</body>
 </html>

Thanks!

解决方案

You can use context.measureText to get the width of given text.

Here's a function that wraps text using context.measureText to measure each word in a sentence and wrap to a new line when the current line exceeds a given width:

A Demo: http://jsfiddle.net/m1erickson/mQFDB/

function wrapText(context, text, x, y, maxWidth, fontSize, fontFace){
  var words = text.split(' ');
  var line = '';
  var lineHeight=fontSize;

  context.font = fontSize + "px " + fontFace;

  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);
  return(y);
}

You can draw your text on the canvas like this:

var lastY=wrapText(context,"Hello",20,40,100,14,"verdana");

The lastY variable holds the y-coordinate of the last line of wrapped text. Therefore you can begin new text at lastY plus some padding:

lastY=wrapText(context,"World",20,lastY+20,100,14,"verdana");

This pattern lets you make text-wrapped paragraphs down the canvas (or in your case questions and multiple choice answers down the canvas).

这篇关于如何在画布上绘制段落文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆