如何通过JavaScript动态创建动画路径?

如何通过JavaScript动态创建动画路径?,javascript,animation,dynamic,Javascript,Animation,Dynamic,我在作品中有一个动画背景 我的目标是让“泡泡”以随机速度沿随机轨迹运动。当到达屏幕边缘时,它会传送回屏幕的另一侧继续前进 我会通过CSS制作动画,但我希望每个“气泡”所遵循的路径是随机的 每个元素都是这样的 如何通过JavaScript实现这种效果 这是处于当前状态的项目 代码笔: 当前JavaScript const orderedNumber = document.querySelectorAll('.backgroundBubble'); var colors = [ '#ff5b0

我在作品中有一个动画背景

我的目标是让“泡泡”以随机速度沿随机轨迹运动。当到达屏幕边缘时,它会传送回屏幕的另一侧继续前进

我会通过CSS制作动画,但我希望每个“气泡”所遵循的路径是随机的

每个元素都是这样的

如何通过JavaScript实现这种效果

这是处于当前状态的项目

代码笔:

当前JavaScript

const orderedNumber = document.querySelectorAll('.backgroundBubble');
var colors = [
  '#ff5b00', '#b8d500', '#795ced', 
  '#ab004a', '#21aec0', '#fe9300' 
];
for (li of orderedNumber) {
  var random_color = colors[Math.floor(Math.random() * colors.length)];
  li.style['background'] = random_color;
  var random_dimensions = Math.floor(Math.random() * 20 + 5);
  li.style['width'] = random_dimensions + "px";
  li.style['height'] = random_dimensions + "px";
  var random_left = Math.floor(Math.random() * 99 + 1);
  li.style['left'] = random_left + "%";
  var random_top = Math.floor(Math.random() * 99 + 1);
  li.style['top'] = random_top + "%";
}
“气泡”HTML


你好

以下是一个可能适合您的解决方案:

  • 每个元素(圆)使用
    transform:translate(x,y)
    CSS属性在随机路径上移动

  • 每个元素都会得到一个随机的x,y偏移量,通过该偏移量,元素会以稍微不同的轨迹移动

  • 当每个元素到达视口的限制时(window.innerWidth=最右侧,window.innerHeight=底部,0=顶部和左侧),它通过对初始偏移值
    offsetX
    offsetY

  • 当前正在使用
    setInterval
    实现动画,但更好的候选者可能是
    requestAnimationFrame

(看看我在新插入的代码中添加的注释。)

const orderedNumber=document.querySelectorAll('.backgroundBubble');
变量颜色=[
"ff5b00","b8d500","795ced",,
#ab004a'、#21aec0'、#fe9300'
];
常数liData=[];
orderedNumber.forEach((li,索引)=>{
var random_color=colors[Math.floor(Math.random()*colors.length)];
li.style['background']=随机颜色;
var random_dimensions=Math.floor(Math.random()*20+5);
li.style['width']=随机尺寸+px;
li.style['height']=随机尺寸+px;
var random_left=Math.floor(Math.random()*99+1);
li.style['left']=random_left+“%”;
var random_top=Math.floor(Math.random()*99+1);
li.style['top']=random_top+“%”;
//添加移动值:在此处添加每个元素
//获取将用于定义其移动的一些附加数据。
liData[索引]={
hasFlipped:false,//元素是否触及视口边界?如果是,此属性将被翻转:false->true->false
targetX:0,//当前x位置。从0开始。
targetY:0,//当前y位置。从0开始。
offsetX:Math.floor(Math.random()*10),//元素将沿x轴移动的随机x偏移量
offsetY:Math.floor(Math.random()*10)//元素将沿y轴移动的随机y偏移量
}
});
setInterval(函数(){
orderedNumber.forEach((li,索引)=>{
//下一行将给出元素的顶部、左侧、右侧和底部位置:
const{top,left,right,bottom}=li.getBoundingClientRect();
//获取offsetX和offsetY,以便我们可以移动元素
设{offsetX,offsetY}=liData[index];
如果(liData[index].hasFlipped){
//元素是否刚好到达顶部或左侧视口边界?
如果(顶部=窗内宽度){
liData[index].hasFlipped=true;
}
liData[index].targetX+=offsetX;
liData[index].targetY+=offsetY;
}
li.style.transform=`translate(${liData[index].targetX}px,${liData[index].targetY}px)`;
});
},50)
@导入url('https://fonts.googleapis.com/css?family=Exo:400,700');
*{
边际:0px;
填充:0px;
}
.背景{
宽度:100%;
位置:绝对位置;
顶部:50vh;
}
.上下文h1{
文本对齐:居中;
颜色:#fff;
字体大小:50px;
字体系列:“Exo”,无衬线;
}
.区域{
背景:#2a2e31;
背景:-webkit线性渐变(向左,#8f94fb,#4e54c8);/#026e9f#03a9f4
宽度:100%;
高度:100vh;
}
.圆圈{
位置:绝对位置;
排名:0;
左:0;
宽度:100%;
身高:100%;
溢出:隐藏;
}
李先生{
位置:绝对位置;
显示:块;
列表样式:无;
底部:-150px;
边界半径:50%;
}

你好

这可能会起作用,但它不会传送到屏幕的另一端,而是反弹回来,创建一个更有趣的动画

 const orderedNumber = document.querySelectorAll('.backgroundBubble');
var colors = [
  '#ff5b00', '#b8d500', '#795ced', 
  '#ab004a', '#21aec0', '#fe9300' 
];
const liData = [];

orderedNumber.forEach((li,index)=>{
  
  var random_color = colors[Math.floor(Math.random() * colors.length)];
  li.style['background'] = random_color;
  var random_dimensions = Math.floor(Math.random() * 20 + 5);
  li.style['width'] = random_dimensions + "px";
  li.style['height'] = random_dimensions + "px";
  var random_left = Math.floor(Math.random() * 99 + 1);
  li.style['left'] = random_left + "%";
  var random_top = Math.floor(Math.random() * 99 + 1);
  li.style['top'] = random_top + "%";
  // ADDING MOVEMENT VALUES:
  liData[index] = {
    hasFlipped: false,
    targetX: 0,
    targetY: 0,
    offsetX: Math.floor( Math.random() * 10 ),
    offsetY: Math.floor( Math.random() * 10 )
  }

});

setInterval(function(){
  orderedNumber.forEach((li,index)=>{
    const { top, left, right, bottom } = li.getBoundingClientRect();
    let { offsetX, offsetY } = liData[index];
    if ( liData[index].hasFlipped ){
      if ( top <= 0 || left <= 0 ){
        liData[index].hasFlipped = false;
      }
      liData[index].targetX -= offsetX;
      liData[index].targetY -= offsetY;

    } else {
      if ( bottom >= window.innerHeight || right >= window.innerWidth ){
        liData[index].hasFlipped = true;
      }
      liData[index].targetX += offsetX;
      liData[index].targetY += offsetY;
    }
      li.style.transform = `translate( ${liData[index].targetX}px,  ${liData[index].targetY}px )`;

  });

}, 50 )
常量
 const orderedNumber = document.querySelectorAll('.backgroundBubble');
var colors = [
  '#ff5b00', '#b8d500', '#795ced', 
  '#ab004a', '#21aec0', '#fe9300' 
];
const liData = [];

orderedNumber.forEach((li,index)=>{
  
  var random_color = colors[Math.floor(Math.random() * colors.length)];
  li.style['background'] = random_color;
  var random_dimensions = Math.floor(Math.random() * 20 + 5);
  li.style['width'] = random_dimensions + "px";
  li.style['height'] = random_dimensions + "px";
  var random_left = Math.floor(Math.random() * 99 + 1);
  li.style['left'] = random_left + "%";
  var random_top = Math.floor(Math.random() * 99 + 1);
  li.style['top'] = random_top + "%";
  // ADDING MOVEMENT VALUES:
  liData[index] = {
    hasFlipped: false,
    targetX: 0,
    targetY: 0,
    offsetX: Math.floor( Math.random() * 10 ),
    offsetY: Math.floor( Math.random() * 10 )
  }

});

setInterval(function(){
  orderedNumber.forEach((li,index)=>{
    const { top, left, right, bottom } = li.getBoundingClientRect();
    let { offsetX, offsetY } = liData[index];
    if ( liData[index].hasFlipped ){
      if ( top <= 0 || left <= 0 ){
        liData[index].hasFlipped = false;
      }
      liData[index].targetX -= offsetX;
      liData[index].targetY -= offsetY;

    } else {
      if ( bottom >= window.innerHeight || right >= window.innerWidth ){
        liData[index].hasFlipped = true;
      }
      liData[index].targetX += offsetX;
      liData[index].targetY += offsetY;
    }
      li.style.transform = `translate( ${liData[index].targetX}px,  ${liData[index].targetY}px )`;

  });

}, 50 )