Функция jQuery частично срабатывает при первом нажатии, работает при втором нажатии - PullRequest
0 голосов
/ 10 мая 2019

Я использую элемент canvas для создания изображения текста base64.Когда я нажимаю кнопку «Создать текст», холст заполняется изображением, но он не изменяется, пока вы не нажмете кнопку второй раз .(И странно, на моей машине мои шрифты не работают до второго щелчка)

Моя скрипка ниже, и вы можете видеть, что функция работает частично при первом нажатиии это то, что сбивает меня с толку.

Я проверил ответы здесь , здесь и здесь уже, но я не эксперт по jQueryи я не знаю, как применить некоторые из этих решений в моем конкретном случае.Я попробовал некоторые из предложенных решений в ответах выше, включая:

  • Оборачивая мой код в $(document).ready(function() {}

  • Используя вместо этого $("#addText").clickиз $("#addText").on("click"...

Редактировать: Как упомянуто @Barmar в комментариях, с первого раза размер изменяется примерно до половины.Это связано с тем, что функция lineCount() выдает неправильный номер при первом нажатии.

$(document).ready(function() {

  $("#addText").click(txtimg);

  $("#myDownload").click(function() {
    var canvas = document.getElementById("myCanvas");
    var fullQuality = canvas.toDataURL("image/png", 1.0);
    $('#imgURL').val(fullQuality);
  });

  $("input[type='radio'][name='fontRadios']").click(function() {
    console.log($("input[type='radio'][name='fontRadios']:checked").val());
  });

  $("#colorChooser > label").on("click", function() {
    $('#colorPreview').css("background-color", $(this).attr('data-color')),
      txtimg();
  });

  $("#CaptureURL").click(function() {
    $("#imgURL").select();
    document.execCommand('copy');
  });

});

function txtimg() {
  var fontSize = parseInt($('#fontSizeValue').html());
  var fontColor = $('#colorChooser > label > input:checked').attr('id');
  var fontFam = $("input[type='radio'][name='fontRadios']:checked").val();
  var canvas = document.getElementById("myCanvas");
  var myMessage = $("#myMessage").val();

  var maxWidth = 600;
  var lineHeight = parseInt($('#lineHeightValue').html());
  var ctx = canvas.getContext("2d");
  var canvHeight = lineHeight * lineCount(ctx, myMessage, maxWidth);
  canvas.height = lineHeight * lineCount(ctx, myMessage, maxWidth);

  var x = canvas.width / 2;
  var y = canvas.height;

  //ctx.clearRect(0, 0, canvas.width, canvas.height);


  //ctx.beginPath();
  //ctx.moveTo(x, 0);
  ctx.font = fontSize + "px " + fontFam;
  ctx.fillStyle = fontColor;
  ctx.textAlign = 'center';
  ctx.textBaseline = 'bottom';
  ctx.imageSmoothingEnabled = true;
  ctx.imageSmoothingQuality = 'high';
  //ctx.fillText(myMessage, x, y);
  wrapText(ctx, myMessage, x, 0 + lineHeight, maxWidth, lineHeight);
}

function lineCount(context, text, maxWidth) {
  var words = text.split(' ');
  var line = '';
  var lines = 1;



  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 && n > 0) {
      line = words[n] + ' ';
      lines++;

    } else {
      line = testLine;
    }
  }
  return lines;
}

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

  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 && n > 0) {
      context.fillText(line, x, y);
      line = words[n] + ' ';
      y += lineHeight;
    } else {
      line = testLine;
    }
  }
  context.fillText(line, x, y);
}

function fontVal(elem) {
  var fv = document.getElementById('fontSizeValue');
  if (fv.innerHTML != elem.value) {
    fv.innerHTML = elem.value;
    console.log(elem.value);
  }
}

function lineVal(elem) {
  var lv = document.getElementById('lineHeightValue');
  if (lv.innerHTML != elem.value) {
    lv.innerHTML = elem.value;
    console.log(elem.value);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>Helloworld!</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.0/css/all.css">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
  <link href="https://fonts.googleapis.com/css?family=Oswald|Roboto|Sofia" rel="stylesheet">
</head>

<body>
  <div class="container">
    <div class="d-flex flex-row align-content-center mb-5">
      <div class="d-flex align-self-center mx-auto">
        <canvas id="myCanvas" width="600" height="100" style="border: 1px solid #cecece;"></canvas>
      </div>
    </div>

    <form id="myForm">
      <div class="form-group">
        <label for="myMessage">Message</label>
        <input type="text" name="myMessage" id="myMessage" class="form-control" value="Did you ever hear the tragedy of Darth Plagueis the Wise? I thought not. It's not a story the Jedi would tell you. It's a Sith legend. Darth Plagueis was a Dark Lord of the Sith, so powerful and so wise he could use the Force to influence the midichlorians to create life... He had such a knowledge of the dark side that he could even keep the ones he cared about from dying. The dark side of the Force is a pathway to many abilities some consider to be unnatural. He became so powerful... the only thing he was afraid of was losing his power, which eventually, of course, he did. Unfortunately, he taught his apprentice everything he knew, then his apprentice killed him in his sleep. It's ironic he could save others from death, but not himself."
        />
      </div>
      <hr/>
      <div class="row">
        <div class="col-lg-6">
          <div class="form-group">
            <label for="fontRange">Font Size:&nbsp;</label><span id="fontSizeValue">32</span><span>px</span>
            <input type="range" class="form-control-range" id="fontRange" min="8" max="128" value="32" onChange="fontVal(this)" onMouseMove="fontVal(this)">
          </div>
        </div>
        <div class="col-lg-6">
          <div class="form-group">
            <label for="lineRange">Line Height</label><span id="lineHeightValue">32</span><span>px</span>
            <input type="range" class="form-control-range" id="lineRange" min="0" max="128" value="32" onChange="lineVal(this)" onMouseMove="lineVal(this)">
          </div>
        </div>
      </div>
      <hr/>
      <div class="row">
        <div class="col-lg-6">
          <div class="form-group">
            <label for="fontSizeSelect">Typeface</label>
            <div class="form-check">
              <input class="form-check-input" type="radio" name="fontRadios" id="Oswald" value="Oswald" checked>
              <label class="form-check-label" for="WP">
									Oswald
								</label>
            </div>
            <div class="form-check">
              <input class="form-check-input" type="radio" name="fontRadios" id="Roboto" value="Roboto">
              <label class="form-check-label" for="TG">
									Roboto
								</label>
            </div>
            <div class="form-check">
              <input class="form-check-input" type="radio" name="fontRadios" id="Sofia" value="Sofia">
              <label class="form-check-label" for="TGB">
									Sofia
								</label>
            </div>
          </div>
        </div>
        <div class="col-lg-6">
          <div class="btn-group btn-group-toggle w-100" data-toggle="buttons" id="colorChooser">
            <label class="btn rush-red active" data-color="#ed1c24">
							<input type="radio" name="colorOptions" id="#ed1c24" autocomplete="off" checked>Red
							</label>
            <label class="btn rush-gold" data-color="#eeb111">
							<input type="radio" name="colorOptions" id="#eeb111" autocomplete="off">Gold
							</label>
            <label class="btn rush-grey" data-color="#505051">
							<input type="radio" name="colorOptions" id="#505051" autocomplete="off">Grey
							</label>
            <label class="btn rush-black" data-color="#111111">
							<input type="radio" name="colorOptions" id="#111111" autocomplete="off">Black
							</label>
          </div>
          <div class="card">
            <div id="colorPreview" class="card-body" style="background-color: #ed1c24;">

            </div>
          </div>
        </div>

      </div>

      <button id="addText" class="btn btn-primary" type="button">
					Add Text
				</button>
    </form>
    <hr/>
    <button class="btn btn-primary" type="button" id="myDownload">
				<i class="fa fa-code pr-2"></i>Generate Image URL
			</button>
    <button class="btn btn-primary" type="button" id="CaptureURL">
				<i class="fa fa-copy pr-2"></i>Copy
			</button>
    <!--a class="btn disabled float-right" id="linkURL" href="#" target="_blank">
				<i class="fa fa-external-link-alt pr-2"></i>Test in Browser
			</a-->

    <textarea id="imgURL" class="form-control"></textarea>
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
</body>

</html>

Ответы [ 2 ]

1 голос
/ 10 мая 2019

Установите свойства шрифта canvas до первого вызова lineCount(). Внутренний вызов measureText() использует все значения по умолчанию, прежде чем назначить их.

0 голосов
/ 10 мая 2019

Я нашел ответ здесь: Рисование текста в с @ font-face не работает в первый раз

Браузеры загружают шрифт в фоновом режиме, асинхронно, поэтомуЯ положил их в документ в другом месте для загрузки.это отбрасывало функцию measureText () и, следовательно, отбрасывало межстрочный интервал

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...