帆布正弦文本滚动条

时间:2015-09-11 18:26:36

标签: javascript html5 canvas

我正在尝试在HTML5画布中创建正弦文本滚动动画,但我无法弄清楚如何以不同方式为每个字母设置动画。

我知道我可以使用.split('')来获取包含字符串中所有字符的数组。我尝试使用for循环for (var i = 0; i < chars.length; i++),但这没有达到我期望的效果(数组中的所有字符都被一起吸尘)。我希望有经验的人可以帮我解决代码并在其中写评论,这样我就可以学到这一点。

我已经拥有的是下面的内容。如您所见,它不会为每个字母设置动画。请参阅this video了解我要做的事情。

// 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 个答案:

答案 0 :(得分:2)

最好将字母扭曲成正弦波,因为随着波的斜率增加,从一个字符到下一个字符的距离会增加。如果你避免变形并且只是在xy = 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