动画html元素的宽度

时间:2015-12-15 17:25:54

标签: javascript animation

如何创建一个增加(减少)给定html元素宽度的函数?以下是我尝试这样做,但我认为这非常糟糕。如何改进我的代码?



function foo(elem, num) {
  var i = 0;

  if (!elem.style.width) {
    setTimeout(function bar() {
      if (i < num) {
        elem.style.width = i++ + '%';
        elem.innerHTML = i++;
      }

      setTimeout(bar, 30);
    }, 30);
  } else {
    i = num;
    setTimeout(function baz() {
      if (i > 0) {
        elem.style.width = i-- + '%';
        elem.innerHTML = i--;
      }

      setTimeout(baz, 30);
    }, 30);
  }
}
&#13;
div {
  height: 25px;
  width: 25px;
  background: red;
  cursor: pointer;
}
&#13;
<div onclick="foo(this, 75)">0%</div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

有一些改进:

  • 首先,您正在跳过每一秒百分比,因为您在函数中执行了两次i++ / i--,一个接一个地执行(因此您将宽度设置为{{1}并显示0%,然后将其设置为1%并显示2%等)
  • 第二,您可以使用3%(对于旧版浏览器包含polyfill)以获得更好的性能
  • 第三,您可以通过计算方向(requestAnimationFrame1来重构您的代码,使其不那么重复,具体取决于您是否希望-1增加或减少并且只有一个i / bar函数

这是我的看法:

&#13;
&#13;
baz
&#13;
function foo(elem, num) {
  var initialWidth = elem.style.width;
  var i = initialWidth ? num : 0;
  var direction = initialWidth ? -1 : 1;

  function bar() {
    elem.style.width = i + '%';
    elem.innerHTML = '' + i;
    i += direction;

    if (i <= num && i >= 0)
      window.requestAnimationFrame(bar);
  }
  window.requestAnimationFrame(bar);

  return function reset() {
    elem.style.width = initialWidth;
    elem.innerHTML = '';
  }
}


var animated = false,
  reset1, reset2;
document.getElementsByClassName('grower-parent')[0].onclick = function() {
  if (!animated) {
    animated = true;
    reset1 = foo(document.getElementsByClassName('grower-1')[0], 50);
    reset2 = foo(document.getElementsByClassName('grower-2')[0], 50);
    return;
  }
  animated = false;
  reset1();
  reset2();
};
&#13;
.grower-1,
.grower-2 {
  display: block;
  background-color: blue;
  height: 1em;
  color: white;
  width: 0;
}
&#13;
&#13;
&#13;

编辑:现在首先点击开始动画,第二次点击重置动画。

编辑2:一个更复杂的程序,可以实际切换到目标动画或返回初始值(以及在<div class="grower-parent"> <div class="grower-1" style="width:50%"></div> <div class="grower-2"></div> </div>px单位之间切换)。您现在可以开始了解为什么我们有专用的动画库,我们可以插入到我们的项目中而不必重新发明轮子:)(试试GSAP,它真棒)

&#13;
&#13;
%
&#13;
function animateTo(element, to) {
  if (to === undefined) return function() {};

  var animating = true;
  var width, match;
  var unit = (to === Number(to)) ? (width = to, 'px') : (match = to.match(/(\d+)\s*(px|%)/), width = Number(match[1]), match[2]);
  var initialWidth = unit === 'px' ? element.offsetWidth : (match = element.style.width.match(/(\d+)\s*%/)) ? Number(match[1]) : Math.round(element.offsetWidth / ((element.offsetParent || element).offsetWidth) * 100);
  var currentWidth = initialWidth;
  var direction = initialWidth <= width ? 1 : -1;

  function animate() {
    element.style.width = currentWidth + unit;
    element.innerHTML = currentWidth + unit;
    currentWidth += direction;

    if (direction * currentWidth <= direction * width) {
      if (animating) window.requestAnimationFrame(animate);
    } else {
      animating = false;
    }
  }

  function stopAnimation() {
    animating = false;
  }

  window.requestAnimationFrame(animate);
  return stopAnimation;
}

function toggleWidth(element, to) {
  var initial = element.style.width ? element.style.width : element.offsetWidth + 'px';
  var toAnimation = true;
  var stopAnimation;
  return function toggle() {
    if (stopAnimation) stopAnimation();
    if (toAnimation) {
      stopAnimation = animateTo(element, to);
    } else {
      stopAnimation = animateTo(element, initial);
    }
    toAnimation = !toAnimation;
  }
}

var toggle = toggleWidth(document.getElementsByClassName('grower-1')[0], '10%');
var toggle2 = toggleWidth(document.getElementsByClassName('grower-2')[0], '200px');
document.getElementsByClassName('grower-parent')[0].onclick = function() {
  toggle();
  toggle2();
};
&#13;
.grower-1,
.grower-2 {
  display: block;
  background-color: blue;
  height: 1em;
  color: white;
  width: 0;
}
&#13;
&#13;
&#13;

答案 1 :(得分:0)

为什么不使用CSS Transitions

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!DOCTYPE html>
    <html>
    <head>
    <style> 
    div {
        width: 100px;
        height: 100px;
        background: red;
        -webkit-transition: width 2s; /* For Safari 3.1 to 6.0 */
        transition: width 2s;
    }
    
    div:hover {
        width: 300px;
    }
    .transition-class {
        width: 500px;
        height: 200px;
    }
    </style>
    </head>
    <body>
    
    <p><b>Note:</b> This example does not work in Internet Explorer 9 and earlier versions.</p>
    
    <div id="myDiv"></div>
    
    <p>Hover over the div element above, to see the transition effect.</p>
    
     <button id="myButton">click me</button>
    </body>
    </html>
row.names <- c('A2003','B2010','C2011','D2010','E2001','F2005','F2009','G2003','G2007','H2004','H2010')
sp1 <- c(4,83,1,2,4,3,1,5,7,2,4)
sp2 <- c(5,0,2,3,10,5,0,2,4,3,1)
sp3 <- c(7,2,4,8,7,2,4,83,1,5,7)
sp4 <- c(0,2,4,2,4,12,1,5,7,2,4)
Site <- c('A','B','C','D','E','F','F','G','G','H','H')
Year <- c('2003','2010','2011','2010','2001','2005','2009','2003','2007','2004','2010')
Obs <- c(1,1,1,4,9,6,8,2,5,2,3)
ID <- c('A2003','B2010','C2011','D2010','E2001','F2005','F2009','G2003','G2007','H2004','H2010')
df<- data.frame(row.names, sp1, sp2, sp3, sp4, Site, Year, Obs, ID)
rownames(df) <- df[,1]
df[,1] <- NULL
df
#fix(df)
df.1 <- subset(df, Obs == 1)
df.more <- subset(df, Obs >= 2)
df.1
df.more