Javascript 动态更改CSS关键帧值以创建时钟

Javascript 动态更改CSS关键帧值以创建时钟,javascript,css,css-animations,keyframe,Javascript,Css,Css Animations,Keyframe,这是我“第一次”尝试关键帧动画。之前,我被指控无法通过JavaScript动态更改硬编码CSS值,这让我很扫兴 我在谷歌上搜索了一下,发现它是“可以”完成的,但要找到、删除和替换部分或整个样式表需要做大量的工作 无论如何,这是我的努力。这个特定脚本的最终目标是时钟指针的反弹。我已经可以用transition和cubic bezier来实现这一点,但只能得到一次反弹。我在使用各种js库等时看到过这种效果,但你知道它是怎样的——你喜欢自己动手 我的问题是——我下面的方法有什么明显的错误吗。忽略这些琐

这是我“第一次”尝试关键帧动画。之前,我被指控无法通过JavaScript动态更改硬编码CSS值,这让我很扫兴

我在谷歌上搜索了一下,发现它是“可以”完成的,但要找到、删除和替换部分或整个样式表需要做大量的工作

无论如何,这是我的努力。这个特定脚本的最终目标是时钟指针的反弹。我已经可以用transition和cubic bezier来实现这一点,但只能得到一次反弹。我在使用各种js库等时看到过这种效果,但你知道它是怎样的——你喜欢自己动手

我的问题是——我下面的方法有什么明显的错误吗。忽略这些琐事,这只是一个测试。我想看的是我的GenerateKeyFrames()函数和调用它的两种方法

谢谢你提供的任何信息

var d=文档;
var incr=1;
var阶跃=-6//初始启动位置。
var coreCss='显示:块;位置:绝对;'
+'左:100像素;顶部:10px;高度:95px;'
+'宽度:4px;背景色:#000;'
+'变换原点:中心-底部;';
var initialAniCss='animation:reGen'+incr+'1s1forwards;';
coreCss+=初始值;
var elementToAnimate=d.createElement('div');
elementToAnimate.setAttribute('style',coreCss);
d、 身体。附属物子体(elementToAnimate);
函数GenerateKeyFrames(){
/*删除以前的“tmpSheet”样式表*/
var currSheet=(d.getElementById('tmpSheet');
如果(货币表){
//currSheet.parentNode.removeChild(currSheet);//看起来不像下面的其他2个一样平滑!
//currSheet.remove();-不,不好意思。
currSheet.outerHTML='';
}
/*以度为单位的运动*/
var p1=阶跃;
var p2=步骤+6;
var p3=步骤+4;
var p4=步骤+6;
var p5=步骤+5;
var p6=步骤+6;
/*创建新的关键帧。必须有新的名称!向名称添加递增变量可以*/
var frames='@keyframes reGen'+incr+'{'
+'0%{变换:旋转('+p1+'deg)translateZ(0);动画计时功能:轻松;}'
+'25%{变换:旋转('+p2+'deg)translateZ(0);动画计时功能:放松;}'
+'45%{transform:rotate('+p3+'deg)translateZ(0);动画计时功能:轻松;}'
+'65%{transform:rotate('+p4+'deg)translateZ(0);动画计时函数:ease out;}'
+'75%{transform:rotate('+p5+'deg)translateZ(0);动画计时功能:轻松;}'
+'85%,100%{transform:rotate('+p6+'deg)translateZ(0);动画计时函数:ease out;}}}';
/*创建新的tmpSheet样式表到页眉*/
var s=document.createElement('style');
s、 setAttribute(“id”、“tmpSheet”);
s、 innerHTML=帧;
document.getElementsByTagName('head')[0]。appendChild;
/*把它们放在一起,就可以开始了*/
var newAni='动画:重新生成'+incr+'1s1forwards;';
coreCss+=newAni;
elementToAnimate.setAttribute('style',coreCss);
d、 身体。附属物子体(elementToAnimate);
}
GenerateKeyFrames();
/*可以在动画结束或计时函数rep()上调用。
elementToAnimate.addEventListener(“animationend”,函数(e){
incr++;
步骤+=6;
元素为animate。删除属性(“样式”);
GenerateKeyFrames();
},假);
*/
函数rep(){
incr++;
步骤+=6;
元素为animate。删除属性(“样式”);
GenerateKeyFrames();
设置超时(rep,2000);
}

rep()这似乎太复杂了。每当我处理复杂的动画时,我都会使用GSAP。它使用基本JQuery和GSAP动画引擎TweenMax

您可以通过他们的


我真的不喜欢用唯一的名称动态插入所有这些关键帧。如果我这样做并尝试使用CSS关键帧动画,我会创建两个动画,一个提供“双反弹”效果,另一个围绕中心旋转包装

仅使用HTML和CSS,您几乎可以创建一个完整的工作时钟,尽管没有JavaScript您无法在正确的时间启动它

不过这是一个有趣的练习,我能够通过使用一点点JavaScript的关键帧动画来重新创建整个时钟效果,以确定动画的开始时间,并提供负片以将动画偏移到适当的时间范围

时间可能有点飘忽不定,但实际上没有你想象的那么多。我让动画在Chrome、FF和IE上运行了一夜,让我的电脑进入睡眠状态,9小时后,时钟仍然保持完美的时间。然而,当我一夜之间让它在手机的后台标签上运行时,时钟在早上就完全坏了。尽管如此,考虑到整个目的是在网页上显示一个时钟,网页不太可能停留足够长的时间,以至于时钟明显关闭

不管怎样,下面是一个片段:

window.addEventListener(“加载”,函数(){
var now=新日期();
var secondsDelay=now.getSeconds();
var minutesDelay=now.getMinutes()*60+秒播放;
var hoursDelay=(now.getHours()%12)*3600+分钟延迟;
var minuteHand=document.querySelector(“.minute.hand”);
var minuteWrapper=document.querySelector(“.minute”);
var secondWrapper=document.querySelector(“.second”);
var hourWrapper=document.querySelector(“.hour”);
//设置具有负延迟的动画偏移
minuteHand.style.animation=“minuteTick 60s-”+secondsdlay+“s infinite”;
secondWrapper.style.animation=“rotateHolder步骤(60)60s-”+secondsDelay+“s无限”;
minuteWrapper.style.animation=“rotateHolder步骤(60)3600s-”+分钟延迟+“s无限”;
hourWrapper.style.animation=“rotateHolder步骤(43200)43200s-”+hoursDelay+“s无限”;
//开始跑步
document.querySelector(“。
$(document).ready(function() {
  var clock = $('.clock'); // clock container
  var arm = $('.arm'); // seconds arm
  var log = $('.log'); // log beneath clock
  var position =  90; // starting position at 0 seconds
  var time = 0; 

setInterval(function(){
  position += 6; // 360 / 60 = +6 deg per second
  time ++; 
  TweenLite.to(arm, 0.3, {rotation:position, transformOrigin:"right bottom", ease: Back.easeOut.config(2), y: 0 });
  log.text(time + " seconds and " + position +  " degs");
 }, 1000);

});
/* Put it all together and it's ready to go */ 
var newAni = 'animation: reGen'+incr+' 1s 1 forwards;';
coreCss += newAni;