【问题标题】:Animate drawing of path on HTML5 canvas在 HTML5 画布上动画绘制路径
【发布时间】:2019-04-12 08:14:59
【问题描述】:

我的问题是如何为两点之间的路径绘制动画。

考虑两点 A 和 B 之间的曲线或路径。我可以使用 Konvajs 中的线条绘制功能在画布上轻松绘制它。

但是,我真正想要的是对线的显示进行动画处理,使其从 A 点开始并逐渐绘制到 B 点。显示应该是动画的,这样我就可以应用令人愉悦的缓动。

作为一个可比较的示例,请参阅本网站 https://coggle.it/ 上的简短视频,该视频显示了新盒子的创建以及将其与旧盒子连接起来的线条。

【问题讨论】:

  • 欢迎 - 我可以看到您已尝试解释您需要帮助的内容,我很抱歉,但我不太明白您想要什么。 StackOverflow 是一个问题解决网站,因此您需要编写一个您需要解决的精确问题。如果您需要一般知识,请启动 Google。你能解释一下你需要什么吗?
  • @VanquiishedWombat 我需要像本站coggle.it这样的动画制作线条,然后你按下添加按钮,线条会出现动画
  • 嗨 - 我编辑了你的问题,以便在 Konvajs 的上下文中更容易理解。另外,请从这种风格中学习如何在 SO 上提出问题。如果您包含少量代码来显示您尝试过的内容,您可以进一步改进问题并寻求更快的答案。更好的是,添加一个工作的 sn-p,它是一些 JS,可以在 SO 页面中工作 - 请参阅 Konvajs 的其他问题,其中包括 sn-ps 作为示例,您可以剪切和粘贴。
  • @VanquiishedWombat 好的!非常感谢!

标签: javascript canvas html5-canvas konvajs


【解决方案1】:

这是一个潜在的答案(特别感谢 @markov00 重新使用 SVG 中的相同技术)。它通过操作路径 dashOffset 和 dash 属性来工作。对here in a post by Jake Archibald 技术有一个很好的解释,其中还包括一个我发现非常有用的滑块交互式实验。

我已尝试使演示尽可能轻量级并仅展示技术 - 尽管我添加了一个滑块和一些 UI 以帮助理解该过程。 jquery 的使用仅用于该技术不需要的 UI 部分。

几点:

  • 这里的演示使用 3 条直线段的路径。但我尝试了曲线和组合路径,并且该技术在这些情况下也适用 - 所以任何路径都应该有效。
  • 我发现在路径上使用近距离路径命令 (z) 会导致路径长度函数在真实距离上变短。这显示为在任一端保持描边或间隙的路径量,其大小取决于关闭路径的第一个和最后一个之间的跳跃。
  • 路径长度实际上总是十进制的,所以不要尝试将所有内容都作为整数,因为您最终会发现您的笔划稍微过长或过短。

要将其用于动画和缓动等,请从滑块更改事件中获取几行并将它们粘贴到帧回调中,根据您的情况操作数学。

// Set up the canvas / stage
var stage = new Konva.Stage({container: 'container1', width: 320, height: 180});

// Add a layer
var layer = new Konva.Layer({draggable: false});
stage.add(layer);

// show where the start of the path is.
var circle = new Konva.Circle({
  x: 66,
  y: 15,
  radius: 5,
  stroke: 'red'
 })
 layer.add(circle);

// draw a path.
    var path = new Konva.Path({
      x: 0,
      y: 0,
      data: 'M66 15 L75 100 L225 120 L100 17 L66 15',
      stroke: 'green'
    });

// get the path length and set this as the dash and dashOffset. 
var pathLen = path.getLength();
path.dashOffset(pathLen);
path.dash([pathLen]);

layer.add(path)
stage.draw();

// Some UI bits
$('#dist').attr('max', parseInt(pathLen)); // set slider max to length of path
$('#pathLen').html('Path : ' + pathLen); // display path length

// jquery event listener on slider change
$('#dist').on('input', function(){

  // compute the new dash lenth as original path length - current slider value. 
  // Means that dashLen initially = path len and moves toward zero as slider val increases.
  var dashLen = pathLen - $(this).val();;
  path.dashOffset(dashLen);   // set new value
  layer.draw();               // refresh the layer to see effect

  // update the UI elements      
  $('#dashLen').html('Dash: ' + dashLen);
  $('#pathPC').html(parseInt(100-(100 * (dashLen/pathLen)), 10) + '%');

})
.info 
{
padding-left: 20px;

}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.5.1/konva.js"></script>
<div class="slidecontainer">
  <input class='slider' id='dist' type="range" min="0" max="100" value="0" class="slider" id="myRange"/>
  <span class='info' id='pathPC'></span>
  <span class='info' id='pathLen'></span>
  <span class='info' id='dashLen'></span>
</div>
<div id='container1' style="display: inline-block; width: 300px, height: 200px; background-color: silver; overflow: hidden; position: relative;"></div>
<div id='img'></div>

【讨论】:

    【解决方案2】:

    我的动画解决方案:

        var width = window.innerWidth;
        var height = window.innerHeight;
    
        // Set up the canvas / stage
        var stage = new Konva.Stage({
            container: 'container',
            width: width,
            height: height
        });
    
        // Add a layer
        var layer = new Konva.Layer({
            draggable: false
        });
        stage.add(layer);
    
        // show where the start of the path is.
        var circle = new Konva.Circle({
            x: 66,
            y: 15,
            radius: 5,
            stroke: 'red'
        })
        layer.add(circle);
    
        // draw a path.
        var path = new Konva.Path({
            x: 0,
            y: 0,
            data: 'M66 15 L75 100 L225 120 L100 17 L66 15',
            stroke: 'green'
        });
    
        // get the path length and set this as the dash and dashOffset. 
        var pathLen = path.getLength();
        path.dashOffset(pathLen);
        path.dash([pathLen]);
    
        // make some animation with stop
        var anim = new Konva.Animation(function (frame) {
            var dashLen = pathLen - frame.time / 5;
            path.dashOffset(dashLen);
            if (dashLen < 0) {
                anim.stop();
            }
        }, layer);
    
        anim.start();
    
        layer.add(path)
        stage.draw();
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.5.1/konva.js"></script>
    <div id='container' style="display: inline-block; width: 300px, height: 200px; background-color: silver; overflow: hidden; position: relative;"></div>
    <div id='img'></div>

    【讨论】:

    • 不错 - 我将您的代码转换为 sn-p。记下您的下一篇文章。
    【解决方案3】:

    这是@Roxane 动画版本的替代方案,但使用了补间。

    var width = window.innerWidth;
        var height = window.innerHeight;
    
        // Set up the canvas / stage
        var stage = new Konva.Stage({
            container: 'container',
            width: width,
            height: height
        });
    
        // Add a layer
        var layer = new Konva.Layer({
            draggable: false
        });
        stage.add(layer);
    
        // show where the start of the path is.
        var circle = new Konva.Circle({
            x: 66,
            y: 15,
            radius: 5,
            stroke: 'red'
        })
        layer.add(circle);
    
        // draw a path.
        var path = new Konva.Path({
            x: 0,
            y: 0,
            data: 'M66 15 L75 100 L225 120 L100 17 L66 15',
            stroke: 'green'
        });
    
        // get the path length and set this as the dash and dashOffset. 
        var pathLen = path.getLength();
        path.dashOffset(pathLen);
        path.dash([pathLen]);
    
        layer.add(path);  // have to add to layer for tweening.
        
        // create the tween
        var tween = new Konva.Tween({
            node: path,
            dashOffset: 0,
            easing: Konva.Easings['BounceEaseOut'],
            duration: 1.5
        });
         tween.play(); // execute the tween
    
        stage.draw();
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.5.1/konva.js"></script>
    <div id='container' style="display: inline-block; width: 300px, height: 200px; background-color: silver; overflow: hidden; position: relative;"></div>
    <div id='img'></div>

    【讨论】:

      猜你喜欢
      • 2013-05-18
      • 1970-01-01
      • 1970-01-01
      • 2021-06-25
      • 2014-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-02
      相关资源
      最近更新 更多