Javascript 动画按时间顺序
Javascript animations in timed sequence
我正在操纵一对 CSS 类 和 Javascript。我的脚本在一个定时序列上,它们一起播放一个动画。我觉得我很接近,但我被卡住了,有什么见解吗?
基本上,我需要第 1 步和第 2 步同时进行一秒钟,第 3 步在第 1 步和第 2 步之后持续 1 秒,第 4 步和第 5 步一起进行在步骤 1、2、3 和 4 等之后的同一时间持续一秒钟。在第 6 步结束时,重置计时器并重复。
我有一个 SVG,它由一堆线条组成。其中一些行必须在序列中的特定时间 "turn on",一些必须变大,所以我正在切换它们的 类 但仅在那个特定时间,否则它们将关闭。
这就是我的代码的样子(简单的 SVG 只是用于演示的模型)。它会手动将 类 添加到元素,但不会重置其计时器并无限重复,因为我无法弄清楚如何在添加它们后清除 类:
<!DOCTYPE html>
<html>
<head>
<style>
#line1, #line2, #line3, #line4, #line5, #line6 {
visiblity: hidden;
}
.showElement {
visibility: visible !important;
}
.growElement {
transform: scale(1.5) perspective(1px);
}
</style>
</head>
<body>
<svg height="210" width="500">
<line id="line1" class="first" x1="0" y1="0" x2="200" y2="200" style="stroke:red;stroke-width:2" />
<line id="line2" class="first" x1="0" y1="0" x2="200" y2="300" style="stroke:orange;stroke-width:2" />
<line id="line3" class="second" x1="0" y1="0" x2="200" y2="400" style="stroke:yellow;stroke-width:2" />
<line id="line4" class="third" x1="0" y1="0" x2="200" y2="500" style="stroke:green;stroke-width:2" />
<line id="line5" class="fourth" x1="0" y1="0" x2="200" y2="600" style="stroke:blue;stroke-width:2" />
<line id="line6" class="fifth" x1="0" y1="0" x2="200" y2="700" style="stroke:purple;stroke-width:2" />
<line id="line7" class="sixth" x1="0" y1="0" x2="200" y2="800" style="stroke:pink;stroke-width:2" />
</svg>
<script>
document.addEventListener('DOMContentLoaded', function() {
setInterval(function() {
// create array of all the elements with the class 'first', loop over each one
// in this case, ['
var firstClass = document.getElementsByClassName("first");
console.log(firstClass[0]);
console.log(firstClass[1]);
setInterval(function(){
firstClass[0].classList.add("showElement");
firstClass[1].classList.add("showElement");
}, 1000);
var secondClass = document.getElementsByClassName("second");
console.log(secondClass[0]);
console.log(secondClass[1]);
setInterval(function(){
secondClass[0].classList.add("showElement");
secondClass[1].classList.add("showElement");
}, 2000);
var thirdClass = document.getElementsByClassName("third");
console.log(thirdClass[0]);
setInterval(function(){
thirdClass[0].classList.add("showElement");
}, 3000);
var fourthClass = document.getElementsByClassName("fourth");
console.log(fourthClass[0]);
setInterval(function(){
fourthClass[0].classList.add("showElement");
}, 4000);
}, 4000);
});
</script>
</body>
</html>
我还需要弄清楚如何一次添加多个 类,只需要几个步骤。例如,元素 .first、.second 和 .third 我想突然出现所以我给他们 .showElement,但是元素 .third 我也想添加 .growElement。我该怎么做?
这是我的 Javascript 代码,它不同时接受多项内容。它使用一个计数器,因此不像以前那样看起来粗糙。它查看列表中的每个项目并应用一种样式:
<script>
document.addEventListener('DOMContentLoaded', function() {
var connections = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth'];
var i = 0; // index of the first item to show
setInterval(function(){
console.log(connections[i]);
document.getElementsByClassName(connections[i]).classList.add("showElement");
var counter = connections[i++]; // get the current item index and increment
if ((i == connections.length)) {
i = 0; // reset to first element if reach the end
}
}, 1000);
});
注意:我不想使用 jQuery,只是纯粹的 JavaScript。此动画存在于单个页面网站上,没有其他 JavaScript 具有外部 SVG,因此它必须存在于 SVG 文件中,我认为安装大型库没有多大意义。
但我正在寻找可能更好的方法来解决这个问题。有人告诉我这是 'promises' 的作品。我现在正在研究 Snap.svg、Q、When、WinJS 和 RSVP.js 库,如果您认为它会更好(甚至 jQuery,如果它真的更容易的话,欢迎提出建议).
var connections = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth'];
function showElements(i,duration){
var elements = document.getElementsByClassName(connections[i]);
elements.map((e) => e.classList.add('showElement'))
setTimeout(()=>{
//remove the .showElement after duration to display has elapsed
elements.map((e)=> e.classList.remove('showElement'))
//recursively calls the next animation to be played, resets at 6
showElements((i+1)%6,duration)
},duration)
}
不确定这是否正是您想要的,但它会在持续时间内为每个添加 showElement,然后将其删除。
showElements(0,1000)
这是一个更简洁的版本,它以 1 秒的间隔执行动画,让您可以更明显地控制每一帧上发生的事情。
要添加多个 类,您可以一次添加任何您喜欢的内容,例如:classList.Add('showElement', 'growElement')
(删除也是如此。See examples)
动画将通过在最后一帧中将帧设置回 0 来循环重复(0 是因为帧计数器在 switch 语句后递增)。然后在第一帧中确保清除最后一帧的样式。
<html>
<head>
<style>
#line1, #line2, #line3, #line4, #line5, #line6, #line7 {
visibility: hidden;
transform: scale(1) perspective(1);
transition: .5s transform;
}
.showElement {
visibility: visible !important;
}
.growElement {
transform: scale(3.5) perspective(1px);
}
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.2/plugins/CSSPlugin.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.2/easing/EasePack.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.2/TweenLite.min.js"></script>
<svg height="210" width="500">
<line id="line1" class="first" x1="0" y1="0" x2="200" y2="200" style="stroke:red;stroke-width:2" />
<line id="line2" class="first" x1="0" y1="0" x2="200" y2="300" style="stroke:orange;stroke-width:2" />
<line id="line3" class="second" x1="0" y1="0" x2="200" y2="400" style="stroke:yellow;stroke-width:2" />
<line id="line4" class="third" x1="0" y1="0" x2="200" y2="500" style="stroke:green;stroke-width:2" />
<line id="line5" class="fourth" x1="0" y1="0" x2="200" y2="600" style="stroke:blue;stroke-width:2" />
<line id="line6" class="fifth" x1="0" y1="0" x2="200" y2="700" style="stroke:purple;stroke-width:2" />
<line id="line7" class="sixth" x1="0" y1="0" x2="200" y2="800" style="stroke:pink;stroke-width:2" />
</svg>
<script>
var frame = 1;
// create array of all the elements with the class 'first', loop over each one
// in this case, ['
var firstClass = document.getElementsByClassName("first");
var secondClass = document.getElementsByClassName("second");
var thirdClass = document.getElementsByClassName("third");
var fourthClass = document.getElementsByClassName("fourth");
var fifthClass = document.getElementsByClassName("fifth");
var sixthClass = document.getElementsByClassName("sixth");
var seventhClass = document.getElementsByClassName("seventh");
function hideUnusedClasses(p_classesArray) {
p_classesArray.forEach(function(array, index){
for(var i=0;i<array.length;++i) {
array[i].classList.remove('showElement', 'growElement');
}
});
}
var interval = setInterval(function(){
//console.log('Run every 1 second');
switch(frame) {
case 1:
//console.log('frame', frame);
hideUnusedClasses([sixthClass]);
for(var i=0;i<firstClass.length;++i) {
firstClass[i].classList.add('showElement');
}
break;
case 2:
//console.log('frame', frame);
//console.log('Delete 1 class');
hideUnusedClasses([firstClass]);
for(var i=0;i<secondClass.length;++i) {
secondClass[i].classList.add('showElement');
}
break;
case 3:
//console.log('frame', frame);
//console.log('Delete 2 class');
hideUnusedClasses([secondClass]);
for(var i=0;i<thirdClass.length;++i) {
thirdClass[i].classList.add('showElement', 'growElement');
}
break;
case 4:
//console.log('frame', frame);
hideUnusedClasses([thirdClass]);
//console.log('Delete 3 class');
for(var i=0;i<fourthClass.length;++i) {
fourthClass[i].classList.add('showElement');
}
break;
case 5:
//console.log('frame', frame);
hideUnusedClasses([fourthClass]);
for(var i=0;i<fifthClass.length;++i) {
fifthClass[i].classList.add('showElement');
}
break;
case 6:
//console.log('frame', frame);
hideUnusedClasses([fifthClass]);
for(var i=0;i<sixthClass.length;++i) {
sixthClass[i].classList.add('showElement');
}
frame = 0;
break;
default:
//console.log('all done');
//clearInterval(interval);
}
++frame;
}, 1000);
</script>
</body>
</html>
我正在操纵一对 CSS 类 和 Javascript。我的脚本在一个定时序列上,它们一起播放一个动画。我觉得我很接近,但我被卡住了,有什么见解吗?
基本上,我需要第 1 步和第 2 步同时进行一秒钟,第 3 步在第 1 步和第 2 步之后持续 1 秒,第 4 步和第 5 步一起进行在步骤 1、2、3 和 4 等之后的同一时间持续一秒钟。在第 6 步结束时,重置计时器并重复。
我有一个 SVG,它由一堆线条组成。其中一些行必须在序列中的特定时间 "turn on",一些必须变大,所以我正在切换它们的 类 但仅在那个特定时间,否则它们将关闭。
这就是我的代码的样子(简单的 SVG 只是用于演示的模型)。它会手动将 类 添加到元素,但不会重置其计时器并无限重复,因为我无法弄清楚如何在添加它们后清除 类:
<!DOCTYPE html>
<html>
<head>
<style>
#line1, #line2, #line3, #line4, #line5, #line6 {
visiblity: hidden;
}
.showElement {
visibility: visible !important;
}
.growElement {
transform: scale(1.5) perspective(1px);
}
</style>
</head>
<body>
<svg height="210" width="500">
<line id="line1" class="first" x1="0" y1="0" x2="200" y2="200" style="stroke:red;stroke-width:2" />
<line id="line2" class="first" x1="0" y1="0" x2="200" y2="300" style="stroke:orange;stroke-width:2" />
<line id="line3" class="second" x1="0" y1="0" x2="200" y2="400" style="stroke:yellow;stroke-width:2" />
<line id="line4" class="third" x1="0" y1="0" x2="200" y2="500" style="stroke:green;stroke-width:2" />
<line id="line5" class="fourth" x1="0" y1="0" x2="200" y2="600" style="stroke:blue;stroke-width:2" />
<line id="line6" class="fifth" x1="0" y1="0" x2="200" y2="700" style="stroke:purple;stroke-width:2" />
<line id="line7" class="sixth" x1="0" y1="0" x2="200" y2="800" style="stroke:pink;stroke-width:2" />
</svg>
<script>
document.addEventListener('DOMContentLoaded', function() {
setInterval(function() {
// create array of all the elements with the class 'first', loop over each one
// in this case, ['
var firstClass = document.getElementsByClassName("first");
console.log(firstClass[0]);
console.log(firstClass[1]);
setInterval(function(){
firstClass[0].classList.add("showElement");
firstClass[1].classList.add("showElement");
}, 1000);
var secondClass = document.getElementsByClassName("second");
console.log(secondClass[0]);
console.log(secondClass[1]);
setInterval(function(){
secondClass[0].classList.add("showElement");
secondClass[1].classList.add("showElement");
}, 2000);
var thirdClass = document.getElementsByClassName("third");
console.log(thirdClass[0]);
setInterval(function(){
thirdClass[0].classList.add("showElement");
}, 3000);
var fourthClass = document.getElementsByClassName("fourth");
console.log(fourthClass[0]);
setInterval(function(){
fourthClass[0].classList.add("showElement");
}, 4000);
}, 4000);
});
</script>
</body>
</html>
我还需要弄清楚如何一次添加多个 类,只需要几个步骤。例如,元素 .first、.second 和 .third 我想突然出现所以我给他们 .showElement,但是元素 .third 我也想添加 .growElement。我该怎么做?
这是我的 Javascript 代码,它不同时接受多项内容。它使用一个计数器,因此不像以前那样看起来粗糙。它查看列表中的每个项目并应用一种样式:
<script>
document.addEventListener('DOMContentLoaded', function() {
var connections = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth'];
var i = 0; // index of the first item to show
setInterval(function(){
console.log(connections[i]);
document.getElementsByClassName(connections[i]).classList.add("showElement");
var counter = connections[i++]; // get the current item index and increment
if ((i == connections.length)) {
i = 0; // reset to first element if reach the end
}
}, 1000);
});
注意:我不想使用 jQuery,只是纯粹的 JavaScript。此动画存在于单个页面网站上,没有其他 JavaScript 具有外部 SVG,因此它必须存在于 SVG 文件中,我认为安装大型库没有多大意义。
但我正在寻找可能更好的方法来解决这个问题。有人告诉我这是 'promises' 的作品。我现在正在研究 Snap.svg、Q、When、WinJS 和 RSVP.js 库,如果您认为它会更好(甚至 jQuery,如果它真的更容易的话,欢迎提出建议).
var connections = ['first', 'second', 'third', 'fourth', 'fifth', 'sixth'];
function showElements(i,duration){
var elements = document.getElementsByClassName(connections[i]);
elements.map((e) => e.classList.add('showElement'))
setTimeout(()=>{
//remove the .showElement after duration to display has elapsed
elements.map((e)=> e.classList.remove('showElement'))
//recursively calls the next animation to be played, resets at 6
showElements((i+1)%6,duration)
},duration)
}
不确定这是否正是您想要的,但它会在持续时间内为每个添加 showElement,然后将其删除。
showElements(0,1000)
这是一个更简洁的版本,它以 1 秒的间隔执行动画,让您可以更明显地控制每一帧上发生的事情。
要添加多个 类,您可以一次添加任何您喜欢的内容,例如:classList.Add('showElement', 'growElement')
(删除也是如此。See examples)
动画将通过在最后一帧中将帧设置回 0 来循环重复(0 是因为帧计数器在 switch 语句后递增)。然后在第一帧中确保清除最后一帧的样式。
<html>
<head>
<style>
#line1, #line2, #line3, #line4, #line5, #line6, #line7 {
visibility: hidden;
transform: scale(1) perspective(1);
transition: .5s transform;
}
.showElement {
visibility: visible !important;
}
.growElement {
transform: scale(3.5) perspective(1px);
}
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.2/plugins/CSSPlugin.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.2/easing/EasePack.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.2/TweenLite.min.js"></script>
<svg height="210" width="500">
<line id="line1" class="first" x1="0" y1="0" x2="200" y2="200" style="stroke:red;stroke-width:2" />
<line id="line2" class="first" x1="0" y1="0" x2="200" y2="300" style="stroke:orange;stroke-width:2" />
<line id="line3" class="second" x1="0" y1="0" x2="200" y2="400" style="stroke:yellow;stroke-width:2" />
<line id="line4" class="third" x1="0" y1="0" x2="200" y2="500" style="stroke:green;stroke-width:2" />
<line id="line5" class="fourth" x1="0" y1="0" x2="200" y2="600" style="stroke:blue;stroke-width:2" />
<line id="line6" class="fifth" x1="0" y1="0" x2="200" y2="700" style="stroke:purple;stroke-width:2" />
<line id="line7" class="sixth" x1="0" y1="0" x2="200" y2="800" style="stroke:pink;stroke-width:2" />
</svg>
<script>
var frame = 1;
// create array of all the elements with the class 'first', loop over each one
// in this case, ['
var firstClass = document.getElementsByClassName("first");
var secondClass = document.getElementsByClassName("second");
var thirdClass = document.getElementsByClassName("third");
var fourthClass = document.getElementsByClassName("fourth");
var fifthClass = document.getElementsByClassName("fifth");
var sixthClass = document.getElementsByClassName("sixth");
var seventhClass = document.getElementsByClassName("seventh");
function hideUnusedClasses(p_classesArray) {
p_classesArray.forEach(function(array, index){
for(var i=0;i<array.length;++i) {
array[i].classList.remove('showElement', 'growElement');
}
});
}
var interval = setInterval(function(){
//console.log('Run every 1 second');
switch(frame) {
case 1:
//console.log('frame', frame);
hideUnusedClasses([sixthClass]);
for(var i=0;i<firstClass.length;++i) {
firstClass[i].classList.add('showElement');
}
break;
case 2:
//console.log('frame', frame);
//console.log('Delete 1 class');
hideUnusedClasses([firstClass]);
for(var i=0;i<secondClass.length;++i) {
secondClass[i].classList.add('showElement');
}
break;
case 3:
//console.log('frame', frame);
//console.log('Delete 2 class');
hideUnusedClasses([secondClass]);
for(var i=0;i<thirdClass.length;++i) {
thirdClass[i].classList.add('showElement', 'growElement');
}
break;
case 4:
//console.log('frame', frame);
hideUnusedClasses([thirdClass]);
//console.log('Delete 3 class');
for(var i=0;i<fourthClass.length;++i) {
fourthClass[i].classList.add('showElement');
}
break;
case 5:
//console.log('frame', frame);
hideUnusedClasses([fourthClass]);
for(var i=0;i<fifthClass.length;++i) {
fifthClass[i].classList.add('showElement');
}
break;
case 6:
//console.log('frame', frame);
hideUnusedClasses([fifthClass]);
for(var i=0;i<sixthClass.length;++i) {
sixthClass[i].classList.add('showElement');
}
frame = 0;
break;
default:
//console.log('all done');
//clearInterval(interval);
}
++frame;
}, 1000);
</script>
</body>
</html>