Холст синусоидальный текстовый скроллер

Я пытаюсь создать синусоидальную анимацию прокрутки текста на холсте HTML5, но не могу понять, как анимировать каждую букву по-разному.

Я знаю, что могу использовать .split('') чтобы получить массив, который содержит все символы в строке. Я пытался с помощью for петля for (var i = 0; i < chars.length; i++) но это не сделало то, что я ожидал (все символы в массиве были смешаны вместе). Я надеялся, что кто-то с таким опытом сможет помочь мне с кодом и написать в нем комментарии, чтобы я мог изучить это.

То, что у меня уже есть, ниже. Как видите, это не оживляет каждую букву. Посмотрите это видео о том, что я пытаюсь сделать.

// Canvas
var c = document.getElementById('c');
var ctx = c.getContext('2d');
var seconds = Date.now();
var offsetY = 220;
var offsetX = 490;
var chars = 'abc';
var amplitude = 50;
var textcolor ='#fff';
var backgroundcolor = '#000';

// Options
c.height = 500;  // Canvas HEIGHT
c.width = 500;   // Canvas WIDTH


function animate() {

    var y = Math.floor((Date.now() - seconds) / 10) / 30;
    var yPos = Math.sin((y)) * amplitude;

    ctx.fillStyle = backgroundcolor;
    ctx.fillRect(0, 0, c.width, c.height);
    ctx.fillStyle = textcolor;

    ctx.fillText(chars, offsetX--, offsetY + yPos);

    if (offsetX == 0) {
        offsetX = 490;
    }

    // Loop it
    requestAnimationFrame(animate);

}

// Start animation
requestAnimationFrame(animate);
<!doctype html>

<html>

    <head>
        <title>Sinus Scroller</title>
    </head>

    <body>

        <canvas id="c">
        </canvas>

    </body>

</html>

1 ответ

Решение

Желательно деформировать буквы в синусоидальную волну, потому что расстояние от одного символа до следующего увеличивается с увеличением наклона волны. Если вы избегаете деформации и просто реализуете волну с постоянной скоростью в x и с y = sin(x) для каждой буквы вы увидите межсимвольные промежутки, растущие на крутых участках синусоидальной волны и сужающиеся около оптимума.

В любом случае, вот простая реализация:

var text = 'Savor  the  delightful  flavor  of  Bubba-Cola',
    canvasWidth = 620,
    canvasHeight = 200,
    rightEdgeBuffer = 50;

WebFont.load({  // Web Font Loader: https://github.com/typekit/webfontloader
  google: {
    families: ['Source Sans Pro']
  },
  active: function () {  // Gets called when font loading is done.
    var canvas = document.getElementsByTagName('canvas')[0],
        context = canvas.getContext('2d'),
        yZero = canvasHeight / 2,      // Set axis position and amplitude
        amplitude = canvasHeight / 4,  // according to canvas dimensions.
        textColor ='#fff',
        backgroundColor = '#000';
    canvas.width = canvasWidth;
    canvas.height = canvasHeight;
    context.font = "32px 'Source Sans Pro', monospace";

    var pos = canvasWidth;  // Split the text into characters.
    var units = text.split('').map(function (char) {
      var width = context.measureText(char).width,
          unit = { char: char, width: width, pos: pos };
      pos += width;  // Calculate the pixel offset of each character.
      return unit;
    });

    var running = true,
        lapTime;  // Set this before the first animation call.

    function animate() {
      var currentTime = Date.now(),
          dp = (currentTime - lapTime) / 15;  // Displacement in pixels.
      lapTime = currentTime;
      context.fillStyle = backgroundColor;
      context.fillRect(0, 0, canvasWidth, canvasHeight);
      units.forEach(function (unit) {
        unit.pos -= dp;  // Update char position.
        if (unit.pos < -unit.width) {  // Wrap around from left to right.
          unit.pos += canvasWidth + rightEdgeBuffer;
        }
        var y = Math.sin(unit.pos / 45) * amplitude;
        context.fillStyle = textColor;
        context.fillText(unit.char, unit.pos, yZero + y);
      });
      if (running) {
        requestAnimationFrame(animate);
      }
    }

    document.getElementById('stopButton').onclick = function () {
      running = false;
    };

    lapTime = Date.now();
    requestAnimationFrame(animate);
  }
});
<script
 src="https://ajax.googleapis.com/ajax/libs/webfont/1.5.18/webfont.js"
></script>

<canvas></canvas>

<button id="stopButton"> stop </button>

Вот более полная реализация с прямолинейно искривленными символами:

https://github.com/michaellaszlo/wavy-text

Другие вопросы по тегам