- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的目标是将缓动纳入我的项目中基于时间的移动中,并且可能需要一些帮助。
目前我正在使用每秒 x 像素的简单公式。
...
speed: 100,
now: undefined,
delta: undefined,
then: undefined,
setDelta: function() {
this.now = Date.now();
this.delta = (this.now - this.then) / 1000;
this.then = this.now;
},
...
var slice = this.speed * this.delta;
this.x += Math.cos(rad) * slice;
this.y += Math.sin(rad) * slice;
通过这样做,我的对象以每秒 100 像素的速度移动。然而,动画非常无聊,因此有一个想法,让它变得更有趣,让它开始缓慢,加速到一半距离,然后再次开始减速,直到到达目的地。
我找到了 javascript 缓动函数列表 click .
我认为看起来准确的应该是一些平滑的正弦,就像这样:
easeInOutSin: function (t) {
return (1 + Math.sin(Math.PI * t - Math.PI / 2)) / 2;
}
问题是我无法弄清楚如何将此公式“连接”到我的代码(如上所述)。
在链接上,人们声称 t
是从 0
到 1
的参数,我认为可能需要改变的是速度
。也许有人可以帮忙。
这是一个用于实验的演示片段:
let distance = (p) => Math.sqrt((p.x - p.dx) * (p.x - p.dx) + (p.y - p.dy) * (p.y - p.dy)),
rftv = (p) => Math.atan2(p.dy - p.y, p.dx - p.x);
let cvs = document.createElement('canvas'),
ctx = cvs.getContext('2d'),
w = cvs.width = 700,
h = cvs.height = 200,
cx = w / 2,
cy = h / 2;
let obj = {
x: 100,
y: cy,
speed: 100,
dx: 600,
dy: cy,
run: function() {
if(!this.moving) { return; }
let d = distance(this);
if(d < 1) {
this.end();
}
this.setDelta();
var slice = this.speed * this.delta;
let rad = rftv(this);
this.x += Math.cos(rad) * slice;
this.y += Math.sin(rad) * slice;
},
now: undefined,
delta: undefined,
then: undefined,
setDelta: function() {
this.now = Date.now();
this.delta = (this.now - this.then) / 1000;
this.then = this.now;
},
moving: false,
start: function() {
this._started_ = Date.now();
this.then = Date.now();
this.moving = true;
},
end: function() {
this.moving = false;
console.log( Date.now() - this._started_, 'should be close to 5000' );
}
};
let render = () => {
ctx.fillStyle = '#ccc';
ctx.fillRect(0, 0, w, h);
ctx.beginPath();
ctx.arc(obj.x, obj.y, 10, 0, Math.PI * 2);
ctx.closePath();
ctx.strokeStyle = 'red';
ctx.stroke();
obj.run();
requestAnimationFrame(render);
};
document.body.appendChild(cvs);
render();
obj.start();
最佳答案
您选择的缓动函数只是时间的函数。这意味着它返回一个从 0 到 1 的比率,具体取决于时间,该时间也在 0 到 1 的范围内。这意味着您必须计算耗时与所需的总动画时间的比率。然后,要计算位置,您需要将返回的比率应用到您想要行驶的总距离 (this.dx - this.startX
) 并将其添加到起始位置。
请注意,在下面的示例中,我忽略了您的 rad
和 this.then
计算,我并没有真正明白您对 rad
的含义>,正如您所看到的,缓动必须是总移动距离和总动画时间的函数。因此,也没有速度的概念,或者您必须将其应用于总距离/动画时间。
let distance = (p) => Math.sqrt((p.x - p.dx) * (p.x - p.dx) + (p.y - p.dy) * (p.y - p.dy)),
rftv = (p) => Math.atan2(p.dy - p.y, p.dx - p.x),
easeInOutSin = function (t) {
return (1 + Math.sin(Math.PI * t - Math.PI / 2)) / 2;
};
let cvs = document.createElement('canvas'),
ctx = cvs.getContext('2d'),
w = cvs.width = 700,
h = cvs.height = 200,
cx = w / 2,
cy = h / 2;
let obj = {
x: 100,
startX: 100,
y: cy,
//speed: 100,
dx: 600,
dy: cy,
run: function() {
if(!this.moving) { return; }
let d = distance(this);
if(d < 1) {
this.end();
}
this.setDelta();
/*var slice = this.speed * this.delta;
let rad = rftv(this);
this.x += Math.cos(rad) * slice;*/
this.x = this.startX + (this.delta * (this.dx - this.startX));
//this.y += Math.sin(rad) * slice;
},
now: undefined,
delta: undefined,
//then: undefined,
setDelta: function() {
this.now = Date.now();
this.delta = easeInOutSin( (this.now - this._started_) / 5000 ); //(this.now - this.then) / 1000;
//this.then = this.now;
},
moving: false,
start: function() {
this._started_ = Date.now();
this.then = Date.now();
this.moving = true;
},
end: function() {
this.moving = false;
console.log( Date.now() - this._started_, 'should be close to 5000' );
}
};
let render = () => {
ctx.fillStyle = '#ccc';
ctx.fillRect(0, 0, w, h);
ctx.beginPath();
ctx.arc(obj.x, obj.y, 10, 0, Math.PI * 2);
ctx.closePath();
ctx.strokeStyle = 'red';
ctx.stroke();
obj.run();
if(obj.moving){ requestAnimationFrame(render); }
};
document.body.appendChild(cvs);
obj.start();
render();
这是第二个示例,具有更高级的缓动函数,改编自 this answer它有 4 个参数:耗时、开始值和结束值以及动画总时间。返回值直接是您的 x
位置。编辑:固定应用参数,应为 0 和总距离,然后将其添加到起始位置。
let distance = (p) => Math.sqrt((p.x - p.dx) * (p.x - p.dx) + (p.y - p.dy) * (p.y - p.dy)),
rftv = (p) => Math.atan2(p.dy - p.y, p.dx - p.x),
easeInOutSine = (t, startVal, endVal, totalTime) => (-endVal/2 * (Math.cos(Math.PI*t/totalTime) - 1) + startVal);
let cvs = document.createElement('canvas'),
ctx = cvs.getContext('2d'),
w = cvs.width = 700,
h = cvs.height = 200,
cx = w / 2,
cy = h / 2;
let obj = {
x: 100,
startX: 100,
y: cy,
//speed: 100,
dx: 600,
dy: cy,
run: function() {
if(!this.moving) { return; }
let d = distance(this);
if(d < 1) {
this.end();
}
this.setDelta();
/*var slice = this.speed * this.delta;
let rad = rftv(this);
this.x += Math.cos(rad) * slice;*/
this.x = this.startX + this.delta;
//this.y += Math.sin(rad) * slice;
},
now: undefined,
delta: undefined,
//then: undefined,
setDelta: function() {
this.now = Date.now();
this.delta = easeInOutSine((this.now - this._started_), 0, (this.dx - this.startX), 5000);//(this.now - this.then) / 1000;
//this.then = this.now;
},
moving: false,
start: function() {
this._started_ = Date.now();
this.then = Date.now();
this.moving = true;
},
end: function() {
this.moving = false;
console.log( Date.now() - this._started_, 'should be close to 5000' );
}
};
let render = () => {
ctx.fillStyle = '#ccc';
ctx.fillRect(0, 0, w, h);
ctx.beginPath();
ctx.arc(obj.x, obj.y, 10, 0, Math.PI * 2);
ctx.closePath();
ctx.strokeStyle = 'red';
ctx.stroke();
obj.run();
if(obj.moving){ requestAnimationFrame(render); }
};
document.body.appendChild(cvs);
obj.start();
render();
希望您更好地理解它是如何工作的,祝你好运!
补充说明:我还颠倒了 obj.start();
和 render();
并向 requestAnimationFrame 添加了一个条件
以避免无限循环。
关于javascript - 将缓动纳入基于时间的移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55097986/
我有一个 RelativeLayout,我从 drawable 设置了背景。我能够将 RelativeLayout 的背景更改为另一个RadioButton 被选中。但是当它发生变化时我该如何给它一个
我正在尝试在 Google 的 Play 报亭应用中复制此动画: http://i.imgur.com/UuX1PRO.webm 我的布局看起来像这样: ... more
我一直在评估 Airflow 。我有一个用例,我有一个每小时运行一次的工作流,以获得每小时的数据聚合。另一个每天运行以获得相同的每日聚合。是否可以创建一个组合工作流,其中仅当所有小时聚合在过去一天都成
我有下一个结构: Activity 1: Activity 2: Form to add new item to the recycler View. RecyclerView
我只是想知道 JavaFx 中是否有任何简单的动 Canvas 局方法,例如 VBox 和 HBox。我希望我的应用程序在指定时间后更改 VBox 的背景颜色。但我意识到没有任何类似于 FillTra
我正在使用 Angular 4 动画在按钮上测试一个简单的淡入/淡出动画。我遇到的问题是,因为我使用的是 bool 值,所以没有任何东西被触发。从开发工具来看,它看起来像一个 .ng-animatin
有没有人在 SublimeREPL 中使用 irb 交换 pry 有任何运气?我很接近,我想。我没有收到错误,但是当我输入命令时也没有收到响应。每次我点击返回时,它的行为就像缓冲区被重置一样。 我正在
今天要向小伙伴们介绍的是一个能够快速地把数据制作成可视化、交互页面的 Python 框架:Streamlit,分分钟让你的数据动起来! 犹记得我在做机器学习和数据分析方面的毕设时,
简而言之,我想缩放 View - 就像 Android Market 一样,当您单击“更多”按钮时,例如在“描述”上。 我发现,Android Market 具有以下结构的布局: > 64d
我似乎无法让它工作。 我正在尝试每天发送一个给定的文件,其名称类似于“file_{{ds_nodash}}.csv”。 问题是我似乎无法将此名称添加为文件名,因为它似乎无法使用。在电子邮件的正文或主题
当您调整窗口大小时, float 的 div 将按预期换行到下一行。但我真的很希望这种布局变化是动画化的。 编辑:顺便说一句,找到一个不依赖于 JQuery 的解决方案会很好。如果需要,我不介意编写自
我有一个复杂的数据处理管道,目前在单台机器上用 Python 实现。 管道是围绕处理属于一系列实现文档、页面、单词等的自定义类的对象而构建的。该管道中的大多数操作都是令人尴尬地并行的——它们处理单个文
我是一名优秀的程序员,十分优秀!