RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 842194
Accepted
Natalya
Natalya
Asked:2020-06-15 02:49:53 +0000 UTC2020-06-15 02:49:53 +0000 UTC 2020-06-15 02:49:53 +0000 UTC

requestAnimationFrame,无法循环

  • 772

升级找到的代码。在原作中,一缕缕雾气在画布上上下移动并消失。我试图将已变为最大值的高度设置为 0(更准确地说,反之亦然,我们从下到上),并且动画循环。我还没有完全理解变量的本质。从var td = new Date().getTime() - p.start;数学上讲,这通常是(-延迟),但是变量是不断增长的(与实时相关?)

if (p.newTop < 0)

    {   
        newTop = 100;
    }

移动到坐标 100(100 纯粹是为了清楚起见)成功。但是“归零” td 以将其分配给 newTop 以获取新线圈是行不通的。

const TIMEOUT = 40;
var stTime = 0;
canvasWidth = 1600;
canvasHeight = 200;
pCount = 0;
pCollection = new Array();
var puffs = 1;
var particlesPerPuff = 50; //2000
var img = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/85280/smoke2.png';
var smokeImage = new Image();
smokeImage.src = img;

for (var i1 = 0; i1 < puffs; i1++) {
  var puffDelay = i1 * 1500;
  for (var i2 = 0; i2 < particlesPerPuff; i2++) {
    addNewParticle((i2 * 50) + puffDelay);
  }
}

draw(new Date().getTime(), 3000);

function addNewParticle(delay) {
  var p = {};
  p.top = canvasHeight;
  p.left = randBetween(-200, 800);
  p.start = new Date().getTime() + delay;
  p.life = 8000;
  p.speedUp = 30;
  p.speedRight = randBetween(0, 20);
  p.startOpacity = .3
  p.newTop = p.top;
  p.newLeft = p.left;
  p.size = 200;
  p.growth = 10;

  pCollection[pCount] = p;
  pCount++;
}

function draw(time) {
  var c = document.getElementById("myCanvas");
  var ctx = c.getContext("2d");
  ctx.clearRect(0, 0, c.width, c.height);

  for (let i = 0; i < pCount; i++) {
    var p = pCollection[i];
    var td = new Date().getTime() - p.start;
    console.log(td);
    var frac = td / p.life
    var newTop = p.top - (p.speedUp * (td / 1000));
    var newLeft = p.left + (p.speedRight * (td / 1000));
    var newOpacity = Math.max(p.startOpacity * (1), 0);
    //var newOpacity = Math.max(p.startOpacity * (1-frac),0);
    var newSize = p.size + (p.growth * (td / 1000));
    p.newTop = newTop;
    p.newLeft = newLeft;


    if (p.newTop < 0) {
      //td = new Date().getTime() - p.start;
      newTop = 100;
    }


    ctx.fillStyle = 'rgba(150,150,150,' + newOpacity + ')';
    ctx.globalAlpha = newOpacity;
    ctx.drawImage(smokeImage, newLeft, newTop, newSize, newSize);
  }

  requestAnimationFrame(draw);
}

function randBetween(n1, n2) {
  var r = (Math.random() * (n2 - n1)) + n1;
  return r;
}
body {
  background: black url(https://s.cdpn.io/16327/texture_bg.jpg) no-repeat 50% 0px;
}

#myCanvas {
  height: 300px;
  width: 2400px;
  max-width: 99%;
  min-width: 800px;
  position: absolute;
  bottom: 0;
  z-index: 2;
}

#house {
  position: absolute;
  top: 20%;
  left: 40%;
}
<canvas id="myCanvas" height="200" width="800"></canvas>

https://jsfiddle.net/Nata_Hamster/ut42nb5e/2/
javascript
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Stepan Kasyanenko
    2020-06-15T15:38:13Z2020-06-15T15:38:13Z

    您示例中的动画逻辑如下:

    1. 元素被创建Particle。对他而言,除其他属性外,还设置了创建时间p.start = new Date().getTime() + delay,

      • new Date().getTime()- 当前时间(以毫秒为单位)

      • delay- 生成延迟

    2. 然后,在元素的渲染过程中,计算它的位置var newTop = p.top - (p.speedUp * (td / 1000));

      • p.top- 起始位置
      • p.speedUp- 上升速度
      • td 是当前时间和开始时间之间的时间差,以毫秒为单位var td = new Date().getTime() - p.start。

    结果,我们看到公式中元素的位置var newTop = p.top - (p.speedUp * (td / 1000));取决于初始位置(p.top)、速度(p.speedUp)和时间差(td)。初始位置(p.top)和速度(p.speedUp)变量不会改变 - 它们是元素的常数。

    因此,元素的位置取决于 time( td)。这意味着您需要更改时间的初始值才能设置元素的位置。所以你需要写代码p.start = new Date().getTime()。

    下面是一个例子。

    const TIMEOUT = 40;
    var stTime = 0;
    canvasWidth = 1600;
    canvasHeight = 200;
    pCount = 0;
    pCollection = new Array();
    var puffs = 1;
    var particlesPerPuff = 50; //2000
    var img = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/85280/smoke2.png';
    var smokeImage = new Image();
    smokeImage.src = img;
    
    for (var i1 = 0; i1 < puffs; i1++) {
      var puffDelay = i1 * 1500;
      for (var i2 = 0; i2 < particlesPerPuff; i2++) {
        addNewParticle((i2 * 50) + puffDelay);
      }
    }
    
    draw(new Date().getTime(), 3000);
    
    function addNewParticle(delay) {
      var p = {};
      p.top = canvasHeight;
      p.left = randBetween(-200, 800);
      p.start = new Date().getTime() + delay;
      p.life = 8000;
      p.speedUp = randBetween(10, 40); // делаем разную скорость, чтобы смотрелось красивее
      p.speedRight = randBetween(0, 20);
      p.startOpacity = .3
      p.newTop = p.top;
      p.newLeft = p.left;
      p.size = 200;
      p.growth = 10;
    
      pCollection[pCount] = p;
      pCount++;
    }
    
    function draw(time) {
      var c = document.getElementById("myCanvas");
      var ctx = c.getContext("2d");
      ctx.clearRect(0, 0, c.width, c.height);
    
      for (let i = 0; i < pCount; i++) {
        var p = pCollection[i];
        var td = new Date().getTime() - p.start;
        var frac = td / p.life
        var newTop = p.top - (p.speedUp * (td / 1000));
        var newLeft = p.left + (p.speedRight * (td / 1000));
        var newOpacity = Math.max(p.startOpacity * (1), 0);
        //var newOpacity = Math.max(p.startOpacity * (1-frac),0);
        var newSize = p.size + (p.growth * (td / 1000));
    
        if (newTop <= 0) {
          p.start = new Date().getTime(); // обнуляем начальное время анимации start
        }
    
    
        ctx.fillStyle = 'rgba(150,150,150,' + newOpacity + ')';
        ctx.globalAlpha = newOpacity;
        ctx.drawImage(smokeImage, newLeft, newTop, newSize, newSize);
      }
    
      requestAnimationFrame(draw);
    }
    
    function randBetween(n1, n2) {
      var r = (Math.random() * (n2 - n1)) + n1;
      return r;
    }
    body {
      background: black url(https://s.cdpn.io/16327/texture_bg.jpg) no-repeat 50% 0px;
    }
    
    #myCanvas {
      height: 300px;
      width: 2400px;
      max-width: 99%;
      min-width: 800px;
      position: absolute;
      bottom: 0;
      z-index: 2;
    }
    
    #house {
      position: absolute;
      top: 20%;
      left: 40%;
    }
    <canvas id="myCanvas" height="200" width="800"></canvas>

    • 2

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5