画布钟摆动画-画布平移
canvas pendulum animation - canvas translating
我试图在HTML5 Canvas中制作一个简单的钟摆,但我被卡住了。我想把它向左和向右摆动25度,所以我计算出我应该在y轴上平移大约-3.5像素的每一帧(向右摆动时平移3.5像素)。我正在使用以下代码
var rotation = Math.PI/180, //rotate about 1deg
translation = -3.5,
counter = 0; //count rotations
function draw() {
var element = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.clearRect(0,0,element.width,element.height);
ctx.translate(0, translation);
ctx.rotate(rotation);
//function draws all objects
objects(element,ctx);
if (counter == 25) {
rotation *= -1;
translation *= -1;
counter = -25;
}
counter += 1;
window.requestAnimationFrame(draw);
}
一切看起来都很好,但当钟摆改变方向时,一切都在x轴上平移,几秒钟后就从屏幕上消失了。。这个代码出了什么问题?或者我在计算中遗漏了什么?我的代码在这里https://jsfiddle.net/qskxjzv9/2/
提前感谢您的回答。
问题是,当涉及旋转,然后进行平移时,x和y将被平移到与看起来逻辑不同的方向。
为了解决这个问题,我们实际上不需要涉及平移,而只需要使用它来放置枢轴(旋转点),然后使用基于不同计算钟摆运动方式的绝对旋转。
例如,这将同时解决平移问题和平滑钟摆运动:
- 更改绘制方法以绘制原点为(0,0)的钟摆-只需更改初始坐标,使其围绕(0,0
- 平移到屏幕的轴心点-这是发生旋转的地方
- 使用sin()作为因子进行旋转-这将创建一个平滑的动画,看起来更像钟摆,并且它将限制移动到范围为[-1,1]的角度
- 使用counter来移动sin()-这是一个频率因子(你可以稍后将其转换为实际频率,比如说,让钟摆每分钟移动n次等等)。为了简单起见,我只使用了现有的
counter
变量并降低了它的步长值
主代码然后:
var maxRot = 25 / 180 * Math.PI, // max 25° in both directions
counter = 0,
// these are better off outside loop
element = document.getElementById('canvas');
ctx = element.getContext('2d');
function draw() {
// reset transform using absolute transformation. Include x translation:
ctx.setTransform(1,0,0,1,element.width*0.5,0);
// clear screen, compensate for initial translate
ctx.clearRect(-element.width*0.5,0,element.width,element.height);
// rotate using sin() with max angle
ctx.rotate(Math.sin(counter) * maxRot);
// draw at new orientation which now is pivot point
objects(element, ctx);
// move sin() using "frequency"-ish value
counter += 0.05;
window.requestAnimationFrame(draw);
}
Fiddle
附加
感谢@Blindman67提供的额外改进:
要控制振荡的频率,你可以做一些小的改变-首先定义频率:
var FREQUENCY = 3;
定义一个将进行转换的函数:
function sint(time) {
return Math.sin(FREQUENCY * time * Math.PI * 0.002); // 0.002 allow time in ms
}
如果您现在更改draw()
方法以采用时间参数而不是计数器:
function draw(time) {
...
}
然后你可以这样称呼轮换:
ctx.rotate(sint(time) * maxRot);
您需要将原点转换为要旋转的点:
ctx.translate(element.width / 2, 0);
然后,你建议的轮换:
ctx.rotate(rotation);
最后,翻译回来:
ctx.translate(- element.width / 2, 0);
看到这个评论你的小提琴叉子。
相关文章:
- CSS表格:从列平移到整个表格宽度
- 为什么在画布上画线;t出现
- 在地图上画一条路线
- 在D3.js中,有没有任何方法可以将x和y方向上的滚动事件绑定到平移svg
- d3.csv有很多数据,只画了一个月
- 将谷歌地图中的平移边界设置为图像覆盖
- 多点触摸平移缩放在javascript中同时旋转
- 在d3中应用缩放平移和轴重缩放
- 如何将Node.js与卡布奇诺一起使用
- "此网站似乎使用滚动链接定位效果.这可能不能很好地与异步平移一起工作;
- 为什么我的线没有随着时间的推移而画出来
- 无法删除逗号'在菲兹布兹
- Zingchart-平移键和鼠标移动
- HTML5画布线宽错误
- 在手动设置平移x和平移y时设置svg平移动画
- svg.js/svg平移缩放-双击交互
- 我的鼠标向下功能不是从最近的点画线,而是从左上角画线
- 在 gisMap 上画一个圆圈
- 锤击JS平移不移动图像
- 代码学院的石头剪刀布