- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
首先,我是 GSAP 新手,所以请耐心等待。我尽力描述我所面临的困难。
为了制作 SVG 文件的动画,我开始深入研究 GSAP。我为 SVG 文件中的不同元素创建了多个补间。一切工作正常,并且动画效果符合预期。
由于我的 SVG 中有很多要制作动画的元素,因此我开始添加 TimelineLite 以更好地控制整个事物。
此时,我的脚本文件如下所示:
首先,我声明了我想要设置动画的所有元素:
this.phone = document.querySelector('#gsap-phone-svg');
this.body = document.querySelectorAll('.gsap-phone-body');
this.body.shadow = this.phone.querySelectorAll('.gsap-phone-body-shadow');
this.body.mask = this.phone.querySelectorAll('.gsap-phone-body-mask');
this.layer = this.phone.querySelectorAll('.gsap-phone-layer');
this.screen = this.phone.querySelectorAll('.gsap-phone-screen');
this.screen.clipPath = this.phone.querySelectorAll('.gsap-phone-screen-clipPath');
.
.
.
// many more following here
然后我创建了一个对象来保存我的补间:
const tweens = {};
// creating tweens
tweens.body = TweenMax.to(this.body, this.animDur/2,{
y: this.maxExpand/6*-1,
ease: this.ease
});
.
.
.
// many more following here
最后,我将所有补间添加到临时数组中,然后将其传递到新的 TimelineLite() 中,如下所示:
const tl = new TimelineLite();
tl.add(tweensArray, 0, "start", 0.05);
我想,到目前为止似乎很合乎逻辑……现在问题就在这里。您可能已经注意到,也可能没有注意到,我有大约 20 个左右的元素需要制作动画。这就是为什么为每个元素单独添加补间会变得非常困惑。我还希望整个主要时间线是重复的。这里的问题是,我希望所有补间在“动画内”和“动画外”上有不同的缓动,并且我希望在“动画外”上没有交错。
所有这些小难题让我思考一种替代解决方案来管理我的补间和时间线的创建。
我想到的最方便的解决方案是将有关动画元素和时间线的所有信息存储在一个对象中:
const animation = {
settings : {
duration: 1.5,
expansion: 1,
easeIn: Elastic.easeOut.config(1, 0.5),
easeOut: Power2.easeInOut
},
timelines : {
main : {
delay : 0,
paused : true,
align : 'start',
stagger : 0.05,
},
test : {
delay: 0,
paused : true,
align : 'start',
stagger : 0.5
}
},
items : {
phone : {
id : '#gsap-phone-svg',
start : { },
end : { },
timeline : 'test',
},
body : {
class : '.gsap-phone-body',
start : {
y : 0,
},
end : {
y : -21,
},
timeline : 'test',
},
layer : {
class : '.gsap-phone-layer',
start : {
y : 0,
},
end : {
y : -62.5,
},
timeline : 'main',
},
radar : {
class : '.gsap-phone-radar',
start : {
y : 0,
},
end : {
y : -25,
},
timeline : 'main',
},
radarBase : {
class : '.gsap-phone-radar-base',
start: {
y : 0,
},
end : {
y: -16,
},
timeline : 'test',
},
ringOne : {
class : '.gsap-phone-radar-ring-1',
start : {
y : 0,
},
end : {
y: -25,
},
timeline : 'test',
},
ringTwo : {
class : '.gsap-phone-radar-ring-2',
start : {
y : 0,
},
end : {
y: -41,
},
timeline : 'main',
},
ringThree : {
class : '.gsap-phone-radar-ring-3',
start : {
y : 0,
},
end : {
y: -62.5,
},
timeline : 'main',
},
cancel : {
class : '.gsap-phone-cancel',
start : {
y : 0,
},
end : {
y: -50,
},
timeline : 'main',
},
submit : {
class : '.gsap-phone-submit',
start : {
y : 0,
},
end : {
y: -100,
},
timeline : 'main',
}
}
};
我编写了这个“createTweens”方法来返回 GSAP Tweens
/* create tweens */
function createTweens(anim){
const el = anim.items;
const settings = anim.settings;
const duration = settings.duration;
const easeIn = settings.easeIn;
const easeOut = settings.easeOut;
const tweensIn = [];
const tweensOut = [];
let tempTween = null;
for (const key in el){
const curEl = el[key];
const selector = curEl.class || el[key].id;
const startPoint = curEl.start || '';
const endPoint = curEl.end || '';
const timeline = curEl.timeline || '';
const nodes = document.querySelectorAll(selector);
nodes.forEach(object => {
tweensIn.push(getTween(object, endPoint, duration, easeIn, `${timeline}-in`));
tweensOut.push(getTween(object, startPoint, duration, easeOut, `${timeline}-out`));
});
}
function getTween(tw, twValues, twDur, twEase, tl){
const vars = twValues;
vars.paused = false;
vars.ease = twEase;
tempTween = TweenMax.to(tw, twDur/2, vars);
tempTween.data = {
timelineName : tl
};
return tempTween;
}
return tweensIn.concat(tweensOut);
}
另一个返回时间线的函数:
/* create timelines */
function createTimelines(anim, tweens){
const el = anim.timelines;
const timelines = {};
// timelines.mainIn = new TimelineLite();
// timelines.mainOut = new TimelineLite();
const tweensForTimelines = {};
for(const key in el){
const delay = el[key].delay;
const paused = el[key].paused;
const align = el[key].align;
const stagger = el[key].stagger;
const vars = {};
vars.paused = paused;
timelines[`${key}-in`] = new TimelineLite(vars);
timelines[`${key}-in`].delay = delay;
timelines[`${key}-in`].align = align;
timelines[`${key}-in`].stagger = stagger;
timelines[`${key}-out`] = new TimelineLite(vars);
timelines[`${key}-out`].delay = delay;
timelines[`${key}-out`].align = align;
timelines[`${key}-out`].stagger = stagger;
tweensForTimelines[`${key}-in`] = [];
tweensForTimelines[`${key}-out`] = [];
}
if(Object.keys(tweensForTimelines).length !== 0){
for(let i = 0; i < tweens.length; i++){
const curTween = tweens[i];
const tlTarget = curTween.data.timelineName;
tweensForTimelines[tlTarget].push(curTween);
}
}
for(const key in timelines){
try{
timelines[key].add(tweensForTimelines[key], timelines[key].delay, timelines[key].align, timelines[key].stagger);
console.log(TweenMax.getTweensOf(timelines[key]));
timelines[key].data = tweensForTimelines[key];
} catch(e){
}
}
return timelines;
}
如果我执行以下代码,它将播放我的“main-in”时间线。
const tweens = createTweens(animation);
const timelines = createTimelines(animation, tweens);
timelines['main-in'].play();
到目前为止,这确实有效。但是,如果我尝试将“main-in”时间线添加到新时间线,它就不再工作了。
const anotherTimeline = new TimelineLite();
anotherTimeline.add(timelines['main-in']);
anotherTimeline.play();
为了调试这个,我尝试了
TweenMax.getTweensOf(anotherTimeline);
但是返回的只是一个空数组。然后我为我的“main-in”时间线记录了相同的内容:
console.log(TweenMax.getTweensOf(timelines['main-in']));
还返回一个空数组,这让我很困惑,因为即使这个时间线似乎是空的,它也会播放我的“动画中”:
timelines['main-in'].play()
我真的被困在这里,非常感谢更高级的用户或任何对此有想法的人的帮助。我希望你们能够关注我...如果没有,请查看提供的代码笔..
提前致谢!
最佳答案
我没有时间解析你的所有代码并制作一个完整的替代品,但它确实让我觉得有点过度设计,但我也意识到我的大脑可能只是工作方式不同,这是一种风格选择(没有好坏之分)。
我发现最直观、可读和灵活的方法是,您将动画分解成 block ,然后将其放入函数中,每个 block 都返回一个可以嵌套在主时间轴中的 TimelineLite/Max 或 TweenLite/Max(如果你就这么选择)。
有点像:
function phoneIntro() {
var tl = new TimelineLite();
tl.to(...)
.to(...);
return tl;
}
function flipPhone() {
var tl = new TimelineLite();
tl.to(...);
return tl;
}
var master = new TimelineMax({repeat:-1});
master.add(phoneIntro(), 0)
.add(flipPhone(), "-=1"); //overlap by 1 second
...
当然,如果您有很多元素要对其执行相同类型的动画,那么这种模块化方法也非常有用,因为您可以将所需的任何变量输入到执行该操作的函数中你和吐口动画。
function buildStep(element, duration, x, y) {
return TweenMax.to(element, duration, {x:x, y:y, rotation:30});
}
希望当您创建一些模块化函数并满足您的任何需要时,事情可以变得多么灵活。整个方法也可以使编辑动画(并尝试计时等)变得更快,因为在代码中找到您的位置非常简单。 “我想让介绍时间长 2 秒......”只需找到phoneIntro() 函数并调整其中的内容即可。完毕。由于您将事物与主 TimelineMax 中的相对时间串在一起,因此您对第一个模块化 block 所做的更改会自动推迟后续事物的时间,并且它会很好地流动。不用担心 20 种不同的延迟。
此外,TweenLite.getTweensOf(anotherTimeline) 返回空数组的原因是该方法找到该对象的补间。就像,从字面上看,如果您要补间时间线本身(可能是其进度),它会返回该补间。听起来您假设它获取了某个时间轴实例的补间内部(事实并非如此)。如果这就是您所追求的,那么它就像 anotherTimeline.getChildren() 一样简单。
我希望这至少有一点帮助。欢迎在论坛中提问 http://greensock.com/forums这里有一个很棒的 GSAP 专业人士社区。即使您从不发布问题,这也是一个极好的学习场所:)
补间快乐!
关于javascript - GSAP:同时管理多个补间和时间线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40462528/
尝试在 Gatsby 站点中创建动画时,出现以下错误: 12:57:12:665 (ScrollMagic.Scene) -> ERROR calling setTween() due to miss
我有个问题想问你,希望你能帮助我。我正在使用 为自己构建视差效果GSAP, -ScrollTrigger v3.5.1 并为自己构建了一个名为 parallax() 的函数。 我想在具有不同设置的区域
因此,我在 Three.js 中获取对象的 Y 位置(高度),然后用它更新 greensock 时间变量。它正在登录控制台,但不更新 greensock 中的变量。我究竟做错了什么?当我向时间变量添加
我正在尝试使用 gsap 制作时钟动画。问题是我的实际脚本并不精确。我需要的是: 按下按钮 开始动画(整小时旋转) 然后再次按下按钮停止等待 2 秒并继续这样做 只需开始 -> 旋转 -> 停止(2
所以我目前正在花一些空闲时间学习和探索 GSAP(Greensock 动画平台)。我想知道是否可以为一个特定的重复元素提供一组值。这就是我的 Tween 的样子; TweenMax.from(blin
首先,我是 GSAP 新手,所以请耐心等待。我尽力描述我所面临的困难。 为了制作 SVG 文件的动画,我开始深入研究 GSAP。我为 SVG 文件中的不同元素创建了多个补间。一切工作正常,并且动画效果
我有这段代码可以为不透明度为 1 到 0 的对象设置动画。 但我想知道如何才能让这个 Action 无限重复,每 1 秒? 有什么想法吗? var tl = new TimelineMax();
我正在尝试使用 GSAP 进行我的第一个补间,但没有任何反应,即使我尝试使用示例代码也是如此。 我有一个包含以下代码的 php 文件: #green { width: 100px;
我有以下 3 个 HTML 元素: Item 1 Item 2 Item 3 以及以下 JavaScript: var timeline = new TimelineMax({paused:true,
我开始学习和使用 GreenSock Animation Platform (GSAP) 我创建了一个使用 3D 变换来旋转元素的“旋转票”示例,但是我在背面可见性方面遇到了问题。 看看我的 demo
GSAP 声称使用 HTML5 来执行出色的网络动画,但在他们关于 Greensock.com 的文章中明确表示它不使用 html5 中的 Canvas 框架。很明显,他们正在使用提供的 script
我正在使用 ssr 渲染在 nuxt.js 中编写应用程序。我有 gsap 的问题。我正在使用 typescript ,当我尝试使用 timeline.staggerTo() 方法时,我收到错误,即
我试图理解这篇文章: https://codepen.io/GreenSock/pen/RwVgEgZ 对我来说最难的是理解 select属性(property)。 AFAIK,这是 的属性HTML
如果我在 html 文件中编写脚本代码,动画就会起作用。但如果动画代码在js文件中,那就不行了。这是我的动画代码 $(document).ready(function(){ $(window)
我想做的是这样的:我想在页面的Y或X轴(底部和左侧边框)上生成框并让它们移动彼此平行,直到它们离开屏幕,我想将它们删除。这是我到目前为止所做的: Codepen 。 function generat
Holla,当我关闭菜单并再次打开它时,我需要重置动画。我怎样才能做到这一点?动画仅在我第一次打开菜单时起作用。 CSSPlugin.defaultTransformPerspective = 600
我有描述环境的大 svg 图片,并尝试创建循环,从左到右移动图片: html: CSS: .animation-wrapper{ top: -0; left: -10000px;
大家好.. 我想知道是否可以在GSAP中使用循环,或者它可能对这种情况有一些特殊的东西。 在我的情况下,我有 ul 元素和 30 li 项。 我想给他们增加单独的动画。 例如这样 TweenMax.t
我在 React 应用程序中使用 GSAP,在路线之间快速来回切换时遇到了大量空目标错误。 问题是我的动画比在 Macbook 上向左/向右滑动来后退/前进所需的时间更长,因此,当下一页加载时,旧动画
动画在播放时有效,但在使用reverse()函数时无效 这是演示 https://codesandbox.io/s/gatsby-express-9uqi7导航栏组件 const [state, se
我是一名优秀的程序员,十分优秀!