|
|
@@ -14,7 +14,7 @@ struct TossCoinView{
|
|
|
@State cellWidth: number = 50 // 单元格宽度
|
|
|
@State headsCount: number = 0 // 正面朝上的次数
|
|
|
@State tailsCount: number = 0 // 反面朝上的次数
|
|
|
- @State rotationAngle: number = 40 // 旋转角度
|
|
|
+ @State rotationAngle: number = 0 // 旋转角度
|
|
|
@State verticalOffset: number = 0 // 纵向位移
|
|
|
@State isAnimRun: boolean = false // 动画是否正在执行
|
|
|
|
|
|
@@ -22,71 +22,125 @@ struct TossCoinView{
|
|
|
// 判断当前是否显示正面
|
|
|
isHeadsFaceUp() {
|
|
|
let normalizedAngle = this.rotationAngle % 360; // 规范化角度
|
|
|
- // 判断角度范围,确定是否显示地鼠面
|
|
|
+ // 判断角度范围,确定是否显示正面
|
|
|
if (normalizedAngle >= 0 && normalizedAngle < 90 || normalizedAngle >= 270 && normalizedAngle <= 360) {
|
|
|
- return true; // 显示地鼠面
|
|
|
+ return true; // 显示正面
|
|
|
}
|
|
|
return false; // 显示反面
|
|
|
}
|
|
|
+ runAnimation(){
|
|
|
+
|
|
|
+ if (this.isAnimRun) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.isAnimRun = true
|
|
|
+
|
|
|
+ let maxAnimationSteps = 2 * (10 + Math.floor(Math.random() * 10)); // 计算最大动画次数
|
|
|
+ let totalAnimationDuration = 1500; // 动画总时长 2000
|
|
|
+
|
|
|
+ // 第一次动画,向上抛出
|
|
|
+ animateToImmediately({
|
|
|
+ duration: totalAnimationDuration / 2, // 动画时长为总时长的一半
|
|
|
+ onFinish: () => { // 动画完成后的回调
|
|
|
+ // 第二次动画,向下落
|
|
|
+ animateToImmediately({
|
|
|
+ duration: totalAnimationDuration / 2,
|
|
|
+ onFinish: () => {
|
|
|
+ this.rotationAngle = this.rotationAngle % 360; // 确保角度在0到360之间
|
|
|
+ // 判断当前显示的面
|
|
|
+ if (this.isHeadsFaceUp()) { // 如果是正面
|
|
|
+ this.tailsCount++; // 反面朝上的次数加1
|
|
|
+ } else { // 如果是反面
|
|
|
+ this.headsCount++; // 正面朝上的次数加1
|
|
|
+ }
|
|
|
+ this.isAnimRun = false
|
|
|
+ }
|
|
|
+ }, () => {
|
|
|
+ this.verticalOffset = 0; // 重置纵向位移
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }, () => {
|
|
|
+ // 设置纵向位移,模拟抛硬币的效果
|
|
|
+ this.verticalOffset = -100 * (1 + Math.floor(Math.random() * 2)); // 随机设置向上的位移
|
|
|
+ });
|
|
|
+
|
|
|
+ // 循环动画,增加旋转效果
|
|
|
+ for (let i = 0; i < maxAnimationSteps; i++) {
|
|
|
+ animateToImmediately({
|
|
|
+ delay: i * totalAnimationDuration / maxAnimationSteps, // 设置每次动画的延迟
|
|
|
+ duration: 100, // 每次动画的持续时间
|
|
|
+ onFinish: () => {
|
|
|
+ // 动画完成后的回调
|
|
|
+ }
|
|
|
+ }, () => {
|
|
|
+ this.rotationAngle += 90; // 每次增加90度旋转
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
build() {
|
|
|
Column() {
|
|
|
YTHeader({ title: '抛硬币' })
|
|
|
|
|
|
- // Column(){
|
|
|
- // // Text('xxx').onClick(()=>{
|
|
|
- // // router.back()
|
|
|
- // // })
|
|
|
- // }
|
|
|
- // 页面标题
|
|
|
- Text('抛硬币')
|
|
|
- .height(50)// 高度设置为50
|
|
|
- .width('100%')// 宽度设置为100%
|
|
|
- .textAlign(TextAlign.Center)// 文本居中对齐
|
|
|
- .fontColor("#fefefe")// 字体颜色
|
|
|
- .fontSize(20); // 字体大小
|
|
|
-
|
|
|
- // 显示地鼠和计数
|
|
|
- Row({ space: 20 }) {
|
|
|
- Stack() {
|
|
|
- Image($r('[basic].media.coinbefore')).width(20).height(20).borderRadius(10)
|
|
|
|
|
|
- }
|
|
|
- .borderRadius('50%') // 设置圆角
|
|
|
- .width(20) // 设置宽度
|
|
|
- .height(20) // 设置高度
|
|
|
- .linearGradient({
|
|
|
- // 设置线性渐变背景
|
|
|
- direction: GradientDirection.LeftBottom,
|
|
|
- colors: [['#ebcf2f', 0.0], ['#fef888', 0.5], ['#ebcf2f', 1.0]]
|
|
|
- });
|
|
|
+
|
|
|
+ Row({ space: 20 }) {
|
|
|
+ // Stack() {
|
|
|
+ Image($r('[basic].media.voicemuisc')).width(30).height(30).margin({left:20,right:50})
|
|
|
+ //
|
|
|
+ // }
|
|
|
+ // .borderRadius('50%') // 设置圆角
|
|
|
+ // .width(20) // 设置宽度
|
|
|
+ // .height(20) // 设置高度
|
|
|
+ // .linearGradient({
|
|
|
+ // // 设置线性渐变背景
|
|
|
+ // direction: GradientDirection.LeftBottom,
|
|
|
+ // colors: [['#ebcf2f', 0.0], ['#fef888', 0.5], ['#ebcf2f', 1.0]]
|
|
|
+ // });
|
|
|
+ Text('正')
|
|
|
|
|
|
// 显示反面朝上的次数
|
|
|
Text(`${this.tailsCount}`)
|
|
|
.fontSize(20)
|
|
|
.fontColor(Color.Black);
|
|
|
|
|
|
- Stack() {
|
|
|
- // 显示100
|
|
|
- Image($r('[basic].media.coinback')).width(20).height(20).borderRadius(10)
|
|
|
- }
|
|
|
- .borderRadius('50%') // 设置圆角
|
|
|
- .width(20) // 设置宽度
|
|
|
- .height(20) // 设置高度
|
|
|
- .linearGradient({
|
|
|
- // 设置线性渐变背景
|
|
|
- direction: GradientDirection.LeftBottom,
|
|
|
- colors: [['#ebcf2f', 0.0], ['#fef888', 0.5], ['#ebcf2f', 1.0]]
|
|
|
- });
|
|
|
+ // Stack() {
|
|
|
+ // // 显示100
|
|
|
+ // Image($r('[basic].media.coinback')).width(20).height(20).borderRadius(10)
|
|
|
+ // }
|
|
|
+ // .borderRadius('50%') // 设置圆角
|
|
|
+ // .width(20) // 设置宽度
|
|
|
+ // .height(20) // 设置高度
|
|
|
+ // .linearGradient({
|
|
|
+ // // 设置线性渐变背景
|
|
|
+ // direction: GradientDirection.LeftBottom,
|
|
|
+ // colors: [['#ebcf2f', 0.0], ['#fef888', 0.5], ['#ebcf2f', 1.0]]
|
|
|
+ // });
|
|
|
+ Text('反')
|
|
|
|
|
|
// 显示正面朝上的次数
|
|
|
Text(`${this.headsCount}`)
|
|
|
.fontSize(20)
|
|
|
.fontColor(Color.Black);
|
|
|
+ Image($r('[basic].media.repeat')).width(30).height(30).margin({left:50,right:20}).onClick(()=>{
|
|
|
+ this.runAnimation()
|
|
|
+ })
|
|
|
+
|
|
|
+ }.width('100%').margin({top:20}).justifyContent(FlexAlign.Center); // 设置宽度和内容居中对齐
|
|
|
+
|
|
|
+ Column() {
|
|
|
+ if(!this.isAnimRun){
|
|
|
+ Column(){
|
|
|
+ Text(this.isHeadsFaceUp()?'正':"反").fontSize(20)
|
|
|
+ }.width(80)
|
|
|
+ .height(70)
|
|
|
+ .justifyContent(FlexAlign.Center)
|
|
|
+ .backgroundImage($r('[basic].media.number'))
|
|
|
+ .backgroundImageSize({width:'100%',height:"100%"})
|
|
|
+ .margin({bottom:40})
|
|
|
+ }
|
|
|
|
|
|
- }.width('100%').justifyContent(FlexAlign.Center); // 设置宽度和内容居中对齐
|
|
|
|
|
|
- Stack() {
|
|
|
Stack() {
|
|
|
// 创建放大版地鼠组件
|
|
|
// Hamster({ cellWidth: this.cellWidth * 3 })
|
|
|
@@ -107,8 +161,8 @@ struct TossCoinView{
|
|
|
});
|
|
|
}
|
|
|
.borderRadius('50%') // 设置圆角
|
|
|
- .width(100) // 设置宽度
|
|
|
- .height(100) // 设置高度
|
|
|
+ .width(180) // 设置宽度
|
|
|
+ .height(180) // 设置高度
|
|
|
.shadow({
|
|
|
radius:5,
|
|
|
color:"#f8cd46",
|
|
|
@@ -129,55 +183,17 @@ struct TossCoinView{
|
|
|
})
|
|
|
.translate({ x: 0, y: this.verticalOffset }) // 设置纵向位移
|
|
|
.onClick(() => { // 点击事件处理
|
|
|
+ this.runAnimation()
|
|
|
|
|
|
- if (this.isAnimRun) {
|
|
|
- return;
|
|
|
- }
|
|
|
- this.isAnimRun = true
|
|
|
-
|
|
|
- let maxAnimationSteps = 2 * (10 + Math.floor(Math.random() * 10)); // 计算最大动画次数
|
|
|
- let totalAnimationDuration = 1500; // 动画总时长 2000
|
|
|
-
|
|
|
- // 第一次动画,向上抛出
|
|
|
- animateToImmediately({
|
|
|
- duration: totalAnimationDuration / 2, // 动画时长为总时长的一半
|
|
|
- onFinish: () => { // 动画完成后的回调
|
|
|
- // 第二次动画,向下落
|
|
|
- animateToImmediately({
|
|
|
- duration: totalAnimationDuration / 2,
|
|
|
- onFinish: () => {
|
|
|
- this.rotationAngle = this.rotationAngle % 360; // 确保角度在0到360之间
|
|
|
- // 判断当前显示的面
|
|
|
- if (this.isHeadsFaceUp()) { // 如果是地鼠面
|
|
|
- this.tailsCount++; // 反面朝上的次数加1
|
|
|
- } else { // 如果是反面
|
|
|
- this.headsCount++; // 正面朝上的次数加1
|
|
|
- }
|
|
|
- this.isAnimRun = false
|
|
|
- }
|
|
|
- }, () => {
|
|
|
- this.verticalOffset = 0; // 重置纵向位移
|
|
|
- });
|
|
|
- }
|
|
|
- }, () => {
|
|
|
- // 设置纵向位移,模拟抛硬币的效果
|
|
|
- this.verticalOffset = -100 * (1 + Math.floor(Math.random() * 5)); // 随机设置向上的位移
|
|
|
- });
|
|
|
-
|
|
|
- // 循环动画,增加旋转效果
|
|
|
- for (let i = 0; i < maxAnimationSteps; i++) {
|
|
|
- animateToImmediately({
|
|
|
- delay: i * totalAnimationDuration / maxAnimationSteps, // 设置每次动画的延迟
|
|
|
- duration: 100, // 每次动画的持续时间
|
|
|
- onFinish: () => {
|
|
|
- // 动画完成后的回调
|
|
|
- }
|
|
|
- }, () => {
|
|
|
- this.rotationAngle += 90; // 每次增加90度旋转
|
|
|
- });
|
|
|
- }
|
|
|
});
|
|
|
- }.width('100%').layoutWeight(1).align(Alignment.Bottom).padding({ bottom: 80 }); // 设置组件的宽度、权重、对齐方式和底部内边距
|
|
|
+ }.width('100%').height(500).justifyContent(FlexAlign.Center).margin({bottom:100}) // 设置组件的宽度、权重、对齐方式和底部内边距
|
|
|
+
|
|
|
+ Button('抛硬币').fontColor(Color.White)
|
|
|
+ .backgroundColor('#fd54e3').width('70%')
|
|
|
+ .height(44).borderRadius(20)
|
|
|
+ .onClick(()=>{
|
|
|
+ this.runAnimation()
|
|
|
+ })
|
|
|
|
|
|
|
|
|
}.padding({ bottom: this.safeBottom })
|