gpt4 book ai didi

javascript - 在 Angular 中旋转伪 3d 旋转木马

转载 作者:行者123 更新时间:2023-12-01 23:07:46 25 4
gpt4 key购买 nike

我正在尝试创建一个包含 5 个元素的伪 3d 旋转木马,如下所示(并让它们循环):

enter image description here

我发现这个很棒 stackblitz作为起点,我已经玩了几个小时,试图让它有 5 个元素而不是 3 个,但我真的很难理解它是如何工作的。

如果比我聪明的人可以帮助我了解如何制作这 5 件元素,那就太好了。特别是,我不明白应该如何配置这个 movements 变量,这可能就是这里的全部秘诀。

movements = [
{ pos: 0, right: [1, 2], left: [8, 7] },
{ pos: 2, right: [3, 4, 5, 6, 7], left: [1, 0] },
{ pos: 7, right: [8, 0], left: [6, 5, 4, 3, 2] }
];

最佳答案

对不起,我想我是作者。我对代码的解释非常糟糕。看到你在轮播中一次看到 5 个元素,所以画一个圆周并将其分成 8 部分。编号所以最底部为 0,左边为 1、2,...有些像

    4
3 5
2 6
1 7
0

动画(你看到的脸)是 0,1,2,6 和 7

animates = [0, 1,2,6,7];

位置是

movements = [
{ pos: 0, right: [1], left: [7] },
{ pos: 1, right: [2], left: [0] },
{ pos: 2, right: [3,4,5,6], left: [1] },
{ pos: 6, right: [7], left: [5,4,3,2] },
{ pos: 7, right: [0], left: [6] },
];

那个,例如脸在位置 0,向右转到位置 1,向左转到位置 7脸在位置 1,向右转到位置 1,向左转到位置 0脸在位置 2,向右转到位置 3、4、5 和 6,向左转到位置 1。

嗯,你需要小心,当我们计算 Angular 时,你除以 8(而不是 9)

const animations = mov[direction].map(m => {
const angle = (m * 2 * Math.PI) / 8; //<--see the "8"
....
}

您可以选择除以 8 而不是除以 16,以使运动更逼真。在这种情况下,您会看到面孔

          8
7 9
6 10
5 11
4 12
3 13
2 14
1 15
0

看到在这种情况下可见的面是 0,2,4,12 y 14

animates=[0,2,4,12,14]

位置是

movements = [
{ pos: 0, right: [1,2], left: [15,14] },
{ pos: 2, right: [3,4], left: [1,0] },
{ pos: 4, right: [5,6,7,8,9,10,11,12], left: [3,2] },
{ pos: 12, right: [13,14], left: [11,10,9,8,7,6,5,4] },
{ pos: 14, right: [15,0], left: [13,12] },
];

你需要除以 16

const animations = mov[direction].map(m => {
const angle = (m * 2 * Math.PI) / 16; //<--see the "16"
....
}

我 fork 了 stackblitz here

更新轮播只向左、向右移动一步。如果我们定义其他 Action ,允许左右移动两步,我们可以改进它

movementsTwo=[
{ pos: 0, right: [1,2,3,4], left: [15,14,13,12] },
{ pos: 2, right: [3,4,5,6,7,8,9,10,11,12], left: [1,0,15,14] },
{ pos: 4, right: [5,6,7,8,9,10,11,12,13,14], left: [3,2,1,0] },
{ pos: 12, right: [13,14,15,0], left: [11,10,9,8,7,6,5,4,3,2] },
{ pos: 14, right: [15,0,1,2], left: [13,12,11,10,9,8,7,6,5,4] },

]

并更改函数 animateViews 以允许移动一两步

  animateViews(direction: string,steps:number=1) {
this.animates.forEach((x: number, index: number) => {
//here use one or another array
const movements=steps==1?this.movements:this.movementsTwo;
const mov = movements.find(m => m.pos == x);
...
}

这允许我们编写一个函数来“移动到前面”一个元素

  indexToFront(index: any) {
index = +index;
const pos = this.animates[+index];
if (pos) {
const mov = this.movements.find((x) => x.pos == pos);
const mov2 = this.movementsTwo.find((x) => x.pos == pos);
const anim = { direction: 'right', steps: 1 };
if (
mov.left[mov.left.length - 1] == 0 ||
mov2.left[mov2.left.length - 1] == 0
)
anim.direction = 'left';
if (
mov2.left[mov2.left.length - 1] == 0 ||
mov2.right[mov2.right.length - 1] == 0
)
anim.steps = 2;

this.animateViews(anim.direction, anim.steps);
}
}

嗯,唯一的就是写一个select

<select #select (change)="indexToFront(select.value)">
<option *ngFor="let i of [0,1,2,3,4]">{{i}}</option>
</select>

或者在我们的“轮播”中添加一个(click)事件

<div style="position:relative;margin-top:150px">
<div class="carousel" >
<div #element *ngFor="let i of [0,2,4,12,14];let index=index"
(click)="animates[index]!=0 && indexToFront(index)"
class="carousel__cell">{{index}}
</div>
</div>

我创建 another stackblitz

注意:真正“硬编码”的 movemnet 不太喜欢。如果我有一点时间,我会尝试创建一个组件,但我不能保证什么时候:(

更新 2 我为 5 张图片制作了一个组件 speudo-carousel。主要的变化是,在这一个中,我使用 transfom 来移动“卡片”。所以函数 animateView 变成了这样

animateViews(direction: string, steps: number = 1) {
this.animates.forEach((x: number, index: number) => {
const movements = steps == 1 ? this.movements : this.movementsTwo;
const mov = movements.find((m) => m.pos == x);
const item = this.itemsView.find((_x, i) => i == index);
const animations = mov[direction].map((m) => {
const angle = (m * 2 * Math.PI) / 16;
const scale =
(1 + this.minScale) / 2 + ((1 - this.minScale) / 2) * Math.cos(angle);
const applystyle = {
transform:'translate('+
(this.radius * Math.sin(angle)) + 'px,'+
(Math.floor(this.top * scale)-this.top)+'px)
scale('+scale+')',
'z-index': Math.floor(100 * scale),
};
return animate(
this.timer / mov[direction].length + 'ms',
style(applystyle)
);
});
....
});
}

这使得 .css 更简单

.carousel{
display:flex;
margin-left:auto;
margin-right:auto;
margin-top:20px;

}
.carousel::after{
content:' ';
display: block;
clear: both;
}

.carousel>div{
float:left;
margin-right:-100%;
cursor:pointer;
transform-origin: top left;
}

.carousel>div img {
border-radius: 1rem;
box-shadow: 0 .5rem 1rem rgba(0,0,0,.35);
}

因此组件对图像的大小没有太大的依赖性。另请参阅我添加了一个 transnformY 以产生“从上方查看”的感觉

new stackblitz 中的变化

注意:目前,如果我们想更改 .css,我们可以使用 styles.css 并编写,例如

.custom .carousel>div img {
border-radius: 50%!important;
border:2px solid white;

}

关于javascript - 在 Angular 中旋转伪 3d 旋转木马,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70496066/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com