CSS的3D应用:立方体沿边翻滚动画

14 篇文章 0 订阅

实现效果:

代码实现:

<view class="page">
	<view class="m-30" style="margin-top: 90rpx;">翻滚吧!立方体!</view>
	<view class="board">
		<!-- start 参考线 -->
		<view style="position: absolute; font-size: 0; transform: translateZ(-72rpx);">
			<view v-for="(item, index) in [,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]" :key="index" style="width:144rpx; height: 144rpx; border: 1px solid #333333; box-sizing: border-box; display: inline-block;"></view>
		</view>
		<!-- end 参考线 -->
		<view class="cube transition-anim" :style="animStyle">
			<view class="bottom">下</view>
			<view class="top">上</view>
			<view class="left">左</view>
			<view class="front">前</view>
			<view class="back">后</view>
			<view class="right">右</view>
		</view>
	</view>
	<view class="flex-row m-30">
		<button @click="left">左翻</button>
		<button @click="right">右翻</button>
		<button @click="top">上翻</button>
		<button @click="bottom">下翻</button>
	</view>
</view>
const ANIM_DURATION = 300; // 动画持续时间
var SIZE = 144;
var animBeginning; // 现在是否在执行动画中,为true即在执行动画时将拦截下个动画执行,直到ANIM_DURATION结束(ANIM_DURATION=0可达到不拦截的效果)
var rotate; // 三维旋转,x、y、z角度值,单位deg
var translate; // 二维位移,x、y位移值,单位rpx
export default {
	data() {
		return {
			animStyle: 'transform: translate(0) rotate(0deg);',
		}
	},
	onLoad() {
		this.initData();
	},
	methods: {
		initData() {
			animBeginning = false;
			rotate = { x: 0, y: 0, z: 0 };
			translate = { x: 0, y: 0 };
		},
		left(e) {
			if(animBeginning) {
				return;
			}
			if(rotate.x % 180 == 0) {
				rotate.y += rotate.x % 360 != 0 ? 90 : -90;
			} else if(Math.abs(rotate.y % 360) == 180) {
				rotate.z += rotate.x % 360 == 90 || rotate.x % 360 == -270 ? -90 : 90;
			} else {
				rotate.z += rotate.x % 360 == 90 || rotate.x % 360 == -270 ? 90 : -90;
			}
			translate.x -= SIZE;
			this.startAnimation();
		},
		right(e) {
			if(animBeginning) {
				return;
			}
			if(rotate.x % 180 == 0) {
				rotate.y += rotate.x % 360 != 0 ? -90 : 90;
			} else if(Math.abs(rotate.y % 360) == 180) {
				rotate.z += rotate.x % 360 == 90 || rotate.x % 360 == -270 ? 90 : -90;
			} else {
				rotate.z += rotate.x % 360 == 90 || rotate.x % 360 == -270 ? -90 : 90;
			}
			translate.x += SIZE;
			this.startAnimation();
		},
		top(e) {
			if(animBeginning) {
				return;
			}
			if(rotate.y % 180 == 0) {
				rotate.x += 90;
			} else {
				rotate.z += rotate.y % 360 == -90 || rotate.y % 360 == 270 ? -90 : 90;
			}
			translate.y -= SIZE;
			this.startAnimation();
		},
		bottom(e) {
			if(animBeginning) {
				return;
			}
			if(rotate.y % 180 == 0) {
				rotate.x -= 90;
			} else {
				rotate.z += rotate.y % 360 == -90 || rotate.y % 360 == 270 ? 90 : -90;
			}
			translate.y += SIZE;
			this.startAnimation();
		},
		startAnimation() {
			animBeginning = true;
			this.animStyle = 'transform: translate(' + translate.x + 'rpx, ' + translate.y + 'rpx) rotateX(' + rotate.x + 'deg) rotateY(' + rotate.y + 'deg) rotateZ(' + rotate.z + 'deg);';
			setTimeout(() => {
				// console.log(translate, rotate);
				animBeginning = false;
			}, ANIM_DURATION);
		}
	}
}
.flex-row {
	flex-direction: row;
	display: flex;
	position: relative;
}
.m-30 {
	margin: 30rpx;
}
.page {
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	width: 100vw;
	height: 100vh;
}
.board {
	transform-style: preserve-3d;
	transform: rotateX(-30deg) rotateY(30deg) rotateZ(0deg);
	flex: 1;
}
.cube {
	transform-style: preserve-3d;
	animation-fill-mode : forwards;
	width: 144rpx;
	height: 144rpx;
}
.cube view {
	width: 144rpx;
	height: 144rpx;
	position: absolute;
	/* opacity: 0.5; */
	display: flex;
	justify-content: center;
	align-items: center;
}
.back {
	background-color: #9900FF;
	transform: rotateY(180deg) translateZ(72rpx);
	
}
.right {
	background-color: #99CCCC;
	transform: rotateY(90deg) translateZ(72rpx);
	
}
.left {
	background-color: #00CC00;
	transform: rotateY(-90deg) translateZ(72rpx);
}
.top {
	background-color: #0099FF;
	transform: rotateX(90deg) translateZ(72rpx);
}
.bottom {
	background-color: #FFCC00;
	transform: rotateX(-90deg) translateZ(72rpx);
}
.front {
	background-color: #FF5757;
	transform: rotateY(0deg) translateZ(72rpx);
}

/* 过渡动画 */
.transition-anim {
	transition: all 0.3s;
	/* Firefox 4 */
	-moz-transition: all 0.3s;
	/* Safari 和 Chrome */
	-webkit-transition: all 0.3s;
	/* Opera */
	-o-transition: all 0.3s;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Homilier

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值