如何在网页上设置文本绘图的动画?

str*_*gee 225 javascript css canvas html5-canvas css-shapes

我想要一个有一个居中单词的网页.

我想用动画绘制这个单词,这样页面就会以与我们相同的方式"写出"单词,即它从一个点开始,随着时间的推移绘制直线和曲线,使得最终结果是一个字形.

我不在乎这是用<canvas>DOM还是DOM 完成的,我不关心它是用JavaScript还是CSS完成的.没有jQuery会很好,但不是必需的.

我怎样才能做到这一点?我没有运气就进行了详尽的搜索.

小智 261

我希望用动画绘制这个单词,这样页面就会以与我们相同的方式"写出"单词

画布版

这将绘制单个字符更像是手工编写的字符.它使用长划线图案,其中每个字符随时间交换开/关顺序.它还有一个速度参数.

快照
示例动画(见下面的演示)

为了增加真实感和有机感,我添加了随机字母间距,y delta偏移,透明度,非常微妙的旋转,最后使用已经"手写"的字体.这些可以作为动态参数包装,以提供广泛的"书写风格".

为了更逼真的外观,将需要路径数据,而不是默认情况下.但这是一段简短而有效的代码,它近似于手写行为,并且易于实现.

这个怎么运作

通过定义破折号模式,我们可以创建行进蚂蚁,虚线等.利用这一点,通过为"关闭"点定义一个非常长的点并逐渐增加"开"点,它将给出在绘制点长度时描边时画线的错觉.

由于关闭点太长,重复图案将不可见(长度将随着所使用的字体的大小和特性而变化).字母的路径将有一个长度,所以我们需要确保我们每个点至少覆盖这个长度.

对于由多个路径(f.ex.O,R,P等)组成的字母,其中一个用于轮廓,一个用于空心部分,这些线条似乎是同时绘制的.我们不能用这种技术做很多事情,因为它需要访问每个路径段来分别进行描述.

兼容性

对于不支持canvas元素的浏览器,可以在标记之间放置显示文本的替代方法,例如样式化文本:

<canvas ...>
    <div class="txtStyle">STROKE-ON CANVAS</div>
</canvas>
Run Code Online (Sandbox Code Playgroud)

演示

这会产生实时动画描边(无依赖关系) -

var ctx = document.querySelector("canvas").getContext("2d"),
    dashLen = 220, dashOffset = dashLen, speed = 5,
    txt = "STROKE-ON CANVAS", x = 30, i = 0;

ctx.font = "50px Comic Sans MS, cursive, TSCu_Comic, sans-serif"; 
ctx.lineWidth = 5; ctx.lineJoin = "round"; ctx.globalAlpha = 2/3;
ctx.strokeStyle = ctx.fillStyle = "#1f2f90";

(function loop() {
  ctx.clearRect(x, 0, 60, 150);
  ctx.setLineDash([dashLen - dashOffset, dashOffset - speed]); // create a long dash mask
  dashOffset -= speed;                                         // reduce dash length
  ctx.strokeText(txt[i], x, 90);                               // stroke letter

  if (dashOffset > 0) requestAnimationFrame(loop);             // animate
  else {
    ctx.fillText(txt[i], x, 90);                               // fill final letter
    dashOffset = dashLen;                                      // prep next char
    x += ctx.measureText(txt[i++]).width + ctx.lineWidth * Math.random();
    ctx.setTransform(1, 0, 0, 1, 0, 3 * Math.random());        // random y-delta
    ctx.rotate(Math.random() * 0.005);                         // random rotation
    if (i < txt.length) requestAnimationFrame(loop);
  }
})();
Run Code Online (Sandbox Code Playgroud)
canvas {background:url(http://i.imgur.com/5RIXWIE.png)}
Run Code Online (Sandbox Code Playgroud)
<canvas width=630></canvas>
Run Code Online (Sandbox Code Playgroud)

  • 我是唯一一个为此疯狂的人吗?看起来如此真实,至少比第一个答案更好,并且最接近提问者的问题. (19认同)
  • 我最后使用了另一个答案,因为我现在需要它作为我第二天使用的快速肮脏的黑客然后再也没有碰过,但我接受了这个,因为它更接近我的样子对于. (5认同)

Aks*_*hay 213

编辑2019


我创建了一个可以创建逼真动画的JavaScript库.它易于使用,需要一个充当字体的特殊JSON文件.

var vara = new Vara("#container", "https://rawcdn.githack.com/akzhy/Vara/ed6ab92fdf196596266ae76867c415fa659eb348/fonts/Satisfy/SatisfySL.json", [{
  text: "Hello World!!",
  fontSize: 48,
  y:10
}, {
  text: "Realistic Animations",
  fontSize: 34,
  color:"#f44336"
}], {
  strokeWidth: 2,
  textAlign:"center"
});
Run Code Online (Sandbox Code Playgroud)
#container {
  padding: 30px;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://rawcdn.githack.com/akzhy/Vara/16e30acca2872212e28735cfdbaba696a355c780/src/vara.min.js"></script>
<div id="container"></div>
Run Code Online (Sandbox Code Playgroud)

查看Github页面以获取文档和示例.和Codepen


上一个答案

下面的示例使用snap.js动态创建tspan元素,然后为每个元素设置动画stroke-dashoffset.

var s = Snap('svg');
var text = 'Some Long Text'
var len = text.length;
var array = [];
for (var x = 0; x < len; x++) {
  var t = text[x]
  array.push(t);
}
var txt = s.text(50, 50, array)
$('tspan').css({
  'font-size': 50,
  fill: 'none',
  stroke: 'red',
  "stroke-width":2,
  'stroke-dasharray': 300,
  'stroke-dashoffset': 300
})

$('tspan').each(function(index) {
  $(this).stop(true, true).delay(300 * index).animate({
    'stroke-dashoffset': 0,
  }, 300, function() {
    $(this).css('fill', 'red')
  })
})
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg width="500" height="500">
</svg>
Run Code Online (Sandbox Code Playgroud)

上一个答案


你可以使用svg做这样的事情 stroke-dasharray

text {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  -webkit-animation: draw 8s forwards;
}
@-webkit-keyframes draw {
  100% {
    stroke-dashoffset: 0;
  }
}
text {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  -webkit-animation: draw 8s forwards;
  -moz-animation: draw 8s forwards;
  -o-animation: draw 8s forwards;
  -ms-animation: draw 8s forwards;
  animation: draw 8s forwards;
}
@-webkit-keyframes draw {
  100% {
    stroke-dashoffset: 0;
  }
}
@-moz-keyframes draw {
  100% {
    stroke-dashoffset: 0;
  }
}
@-o-keyframes draw {
  100% {
    stroke-dashoffset: 0;
  }
}
@-ms-keyframes draw {
  100% {
    stroke-dashoffset: 0;
  }
}
@keyframes draw {
  100% {
    stroke-dashoffset: 0;
  }
}
Run Code Online (Sandbox Code Playgroud)
<svg width="500" height="500">
  <text x="100" y="80" fill="none" stroke="black" stroke-width="1" font-size="50">Some text</text>
</svg>
Run Code Online (Sandbox Code Playgroud)

没有keyframes动画你可以做这样的事情

<svg width="500" height="500">
  <text x="100" y="80" fill="none" stroke="black" stroke-width="5" font-size="50"  stroke-dasharray="1000"
  stroke-dashoffset="1000">Some text
  <animate attributeName="stroke-dashoffset"
    from="1000"
    to="0" 
    dur="8s"
      fill="freeze">
          
      </animate> </text>
</svg>
Run Code Online (Sandbox Code Playgroud)

对于IE支持,您可以使用jquery/javascript

$('text').animate({
    'stroke-dashoffset':'0'
},8000)
Run Code Online (Sandbox Code Playgroud)
text {
  stroke-dasharray: 1000;
  stroke-dashoffset: 1000;
  }
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg width="500" height="500">
  <text x="100" y="80" fill="none" stroke="black" stroke-width="1" font-size="50" 
 >Some text
  </text>
</svg>
Run Code Online (Sandbox Code Playgroud)

  • 哇,这真的很有趣.我已经采用了原始代码片段并通过删除重复的CSS属性,使用基于百分比的偏移量和dasharray值以及更改笔触宽度来使其更加明显,以使代码更加明显:http://jsfiddle.net/Ajedi32/gdc4azLn/1 /如果需要,可以随意编辑任何这些改进. (3认同)
  • @JefferyThaGintoki你也可以用canvas做到这一点,只需将文本放在canvas标签之间,如果不支持canvas,则会出现文本(或正文中另一个答案中显示的动画gif).如果浏览器不支持canvas,它可能也不支持svg. (3认同)
  • 对于这个问题,这是一个史诗般的解决方案,SVG优于canvas(+1),如果浏览器不支持它,它将显示文本. (2认同)