支付宝 小程序 抽奖组件 大转盘

这篇具有很好参考价值的文章主要介绍了支付宝 小程序 抽奖组件 大转盘。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

介绍

使用支付宝原有的大转盘营销组件进行改造的,由于背景使用的图片,目前只支持 6 个奖品,一般情况下的大转盘都是这个规格。
转盘停止:之前使用的是计算角度来完成的,没有那种缓慢停止的动画。现在加了一个缓慢停止的动画,让抽奖变得更加顺滑
录出来的动图可能会看到转盘往相反方向转动,但是真机的视觉效果上是看不出来的。

转盘效果图

支付宝 小程序 抽奖组件 大转盘
支付宝 小程序 抽奖组件 大转盘文章来源地址https://www.toymoban.com/news/detail-469369.html

页面代码

index.axml
<view class="lucky-draw-wrapper">
  <view class="chance-logs-container">
    <view class="remaining-chance">
      您有
      <text class="chance">{{ chance }}</text>
      次抽奖机会
    </view>
  </view>
  <turntable
    prizeList="{{ prizeList }}"
    rotTimes="{{ chance }}"
    onStart="onStart"
    onFinish="onFinish"
    onTimesUp="onTimesUp"
  />
</view>
index.js
Page({
  data: {
    prizeList: [
      {
        prizeId: '646739d6dcca4d1f505cb0d3',
        name: 'H&M100元优惠券',
        type: 'COUPON',
        image: 'https://gw.alipayobjects.com/zos/rmsportal/nIQUKeYBbJWliGJVhVmx.png',
      },
      {
        prizeId: '646739d6dcca4d1f505cb0d4',
        name: '2元话费券',
        type: 'COUPON',
        image: 'https://gw.alipayobjects.com/zos/rmsportal/HkrVjjjuxZPUMCUbPazb.png',
      },
      {
        prizeId: '646739d6dcca4d1f505cb0d5',
        name: '45元飞猪出行券',
        type: 'COUPON',
        image: 'https://gw.alipayobjects.com/zos/rmsportal/cDctUxwBLPCszQHRapYV.png',
      },
      {
        prizeId: '646739d6dcca4d1f505cb0d6',
        name: 'H&M10元优惠券',
        type: 'COUPON',
        image: 'https://gw.alipayobjects.com/zos/rmsportal/FAmIWZAWpUwlRFKqQDLz.png',
      },
      {
        prizeId: '646739d6dcca4d1f505cb0d7',
        name: '2元流量券',
        type: 'COUPON',
        image: 'https://gw.alipayobjects.com/zos/rmsportal/cuGomeXzMyeeZMjvVjBj.png',
      },
      {
        prizeId: '646739d6dcca4d1f505cb0d8',
        name: '谢谢参与',
        type: 'NONE',
        image: 'https://zos.alipayobjects.com/rmsportal/dwhgPyWAcXuvJAWlSSgU.png',
      },
    ],
    chance: 3,
  },
  onLoad() {
  },
  async onStart() {
    return this.data.prizeList[Math.floor(Math.random() * 6)];
  },
  async onFinish(result) {
    if (!result) {
      return;
    }

    const { type, name } = result;
    my.showToast({
      type: 'none',
      content: type === 'NONE' ? '很遗憾,差点就中奖了' : `恭喜您,获得${name}`,
    });
    this.setData({
      chance: this.data.chance - 1,
    });
  },
  onTimesUp() {
    my.showToast({
      type: 'none',
      content: '您的抽奖次数已用完',
    });
  },
});
index.json
{
  "transparentTitle": "auto",
  "titlePenetrate":"YES",
  "barButtonTheme": "default",
  "usingComponents": {
    "turntable": "./components/Turntable/index"
  }
}

turntable 组件代码

index.axml

<view class="turntable-container" style="width:{{ width }}rpx; height:{{ width }}rpx;">
  <view
    class="turntable-list {{ animationStatus }}"
    style="background:url('{{ bgImg }}') 0% 0% / 100% 100% no-repeat; {{ transform }}"
  >
    <view a:for="{{ prizeList }}" a:for-index="i">
      <view class="turntable-item">
        <view
          class="turntable-img"
          style="width:{{ prizeWidth }}; padding-top:{{ prizePaddingTop }}; transform:rotate({{ (i + 0.5) / 6 }}turn);{{ itemTransformOrigin }}"
        >
          <view class="prize-name {{ item.type === 'NONE' ? 'none' : '' }}">{{ item.name }}</view>
          <view a:if="{{ item.coupon }}" class="desc">{{ item.coupon.shortDesc }}</view>
          <image src="{{ item.image }}" mode="widthFix" class="prize-img" />
        </view>
      </view>
    </view>
  </view>
  <view class="turntable-btn" >
    <image src="{{ btnImg }}" mode="widthFix" class="img" onTap="onDraw" />
  </view>
</view>

index.acss

.turntable-container {
  position: relative;
  margin: auto;
  border-radius: 50%;
  overflow: hidden;
}

.turntable-list {
  position: absolute;
  border-radius: 50%;
  width: inherit;
  height: inherit;
  transition: all 6s ease;
  -webkit-transition: all 6s ease;
}

.turntable-list.scrolling {
  animation: scroll-start 0.4s linear infinite;
}

@keyframes scroll-start {
  from {
    transform: rotate(0);
  }

  to {
    transform: rotate(360deg);
  }
}

.turntable-list.stop {
  animation: scroll-slow-down 0.7s ease-out;
}

@keyframes scroll-slow-down {
  from {
    transform: rotate(0);
  }

  to {
    transform: rotate(360deg);
  }
}

.turntable-list.stop-win {
  animation: scroll-slow-down-win 0.7s ease-out;
}

@keyframes scroll-slow-down-win {
  from {
    transform: rotate(0);
  }

  to {
    transform: rotate(330deg);
  }
}

.turntable-item {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}

.turntable-img {
  position: relative;
  display: block;
  margin: 0 auto;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.turntable-img .prize-name {
  width: 200rpx;
  padding: 30rpx 0 20rpx;
  color: #000;
  font-weight: 600;
  font-size: 32rpx;
  line-height: 30rpx;
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.turntable-img .prize-name.none {
  color: rgba(17, 17, 17, 0.55);
}

.turntable-img .desc {
  margin-top: -10rpx;
  font-size: 20rpx;
  line-height: 28rpx;
  color: rgba(0, 0, 0, 0.65);
}

.turntable-img .prize-img {
  display: block;
  max-width: 120rpx;
  height: 85rpx;
}

.turntable-btn {
  position: absolute;
  top: -12rpx;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.turntable-btn .img {
  width: 20%;
}

index.js

Component({
  data: {
    degValue: 0, // 旋转角度
    prizeWidth: 0, // 奖项背景图宽度计算值
    prizePaddingTop: 0, // 奖项上边距计算值
    itemTransformOrigin: '', // 奖项旋转原点计算值
    animationStatus: '',
    transform: '',
  },
  props: {
    width: 690, // 画布大小,默认单位 rpx
    initDeg: 0, // 初始旋转角度
    rotTimes: 0, // 抽奖机会次数
    prizeList: [], // 奖品列表
    prizeWidth: NaN, // 奖项宽度
    prizePaddingTop: NaN, // 奖项距离圆弧的内边距
    bgImg: 'https://gw.alipayobjects.com/zos/rmsportal/YIunNQVWkFRxUTaUNhOZ.png', // 背景图
    btnImg: 'https://gw.alipayobjects.com/zos/rmsportal/JHenAywYHZTLbbrnkIFN.png', // 按钮图
    onStart() {}, // 开始回调
    onFinish() {}, // 结束回调
    onTimesUp() {}, // 次数用尽的回调
  },
  didMount() {
    const widthNum = this._getNum(this.props.width);
    const widthUnit = this._getUnit(this.props.width);
    const { prizeWidth } = this.props;
    const paddingTop = this.props.prizePaddingTop;
    this.setData({
      degValue: this.props.initDeg,
      itemTransformOrigin: `transform-origin: 50% ${0.5 * widthNum}${widthUnit};`,
      prizeWidth: isNaN(prizeWidth) ? this._calculatePrizeWidth() : prizeWidth,
      prizePaddingTop: isNaN(paddingTop) ? this._calculatePrizePaddingTop() : paddingTop,
    });
    this.count = 6; // 奖品个数
    this.rotNum = 0; // 当前是第几次抽奖
    this.onRunning = false; // 是否正在抽奖
  },
  methods: {
    async onDraw() {
      if (this.onRunning) {
        return;
      }

      if (this.props.rotTimes < 1) {
        this.props.onTimesUp();
        return;
      }

      this.onRunning = true;
      this.setData({ animationStatus: 'scrolling' });
      const result = await this.props.onStart();
      // 延迟2秒钟展示奖品
      setTimeout(() => {
        this.done(result);
      }, 2000);
    },
    done(result) {
      if (!result) {
        this.onRunning = false;
        this.props.onFinish(null);
        this.setData({ animationStatus: 'stop', transform: '' });
        return;
      }

      this.setData({ animationStatus: 'stop-win', transform: 'transform: rotate(-30deg);' });
      let tempData = this.props.prizeList;
      for (let index = 0; index < tempData.length; index++) {
        if (tempData[index].prizeId === result.prizeId) {
          const itemAfterIndex = tempData.slice(index, this.props.prizeList.length);
          const itemBeforeIndex = tempData.slice(0, index);
          tempData = itemAfterIndex.concat(...itemBeforeIndex);
        }
      }
      this.setData({
        prizeList: tempData,
      });
      // 转盘停止1秒钟后展示弹框
      setTimeout(() => {
        this.onRunning = false;
        this.props.onFinish(result);
      }, 1000);
    },
    _getNum(str) {
      // 获取像素选项数值
      return parseFloat(str);
    },
    _getUnit(str) {
      // 获取像素选项单位
      // eslint-disable-next-line no-param-reassign
      str += '';
      return (str.match(/[a-z]+$/) || [])[0] || 'rpx';
    },
    _calculatePrizeWidth() {
      // 等边三角形内接正方形边长: (4 - 2 * 根号3) * 边长
      const widthNum = this._getNum(this.props.width);
      const widthUnit = this._getUnit(this.props.width);
      return (4 - 2 * Math.sqrt(3)) * 0.5 * widthNum + widthUnit;
    },
    _calculatePrizePaddingTop() {
      // 等边三角形一边的中点离过该边两点的圆弧的距离: 边长 - 边长 * (根号3 / 2)
      const widthNum = this._getNum(this.props.width);
      const widthUnit = this._getUnit(this.props.width);
      return 0.5 * widthNum - 0.25 * widthNum * Math.sqrt(3) + widthUnit;
    },
  },
});

index.json

{
  "component": true
}

到了这里,关于支付宝 小程序 抽奖组件 大转盘的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • html+css+js实现转盘抽奖

     

    2024年01月25日
    浏览(37)
  • JavaScript实践:用Canvas开发一个可配置的大转盘抽奖功能

    🏆作者简介,黑夜开发者,全栈领域新星创作者✌,阿里云社区专家博主,2023年6月csdn上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 🏆本文已收录于专栏:100个JavaScript的小应用。 🎉欢迎 👍点赞✍评论⭐收藏 大转盘抽奖是一种常见的

    2024年02月14日
    浏览(42)
  • 【支付宝小程序】支付宝小程序自定义组件技术教程

    🦖我是Sam9029,一个前端 Sam9029的CSDN博客主页:Sam9029的博客_CSDN博客-JS学习,CSS学习,Vue-2领域博主 **🐱‍🐉🐱‍🐉恭喜你,若此文你认为写的不错,不要吝啬你的赞扬,求收藏,求评论,求一个大大的赞!👍** 在前端开发中,自定义组件是非常重要的一部分。在支付宝的开发

    2024年02月12日
    浏览(39)
  • 小程序父子组件间传值(微信/支付宝/钉钉)

    以传递一个简单的count值为例,实现父子组件的双向绑定,无论是点击父组件按钮还是子组件按钮,count值都自增 父传子 简单的将父组件在data中定义的属性,赋给子组件定义在properties中的属性即可 通过在父组件中设置一个按钮,使count自增,子组件的count属性也会随之自增

    2024年02月10日
    浏览(80)
  • 支付宝原生小程序组件与父级传递数据(微信小程序基本一样)

    1. 声明组件 在对应的目录下,右击点击 新建小程序 ,之后会生成对应的文件 2. 子组件

    2024年02月16日
    浏览(74)
  • 【微信小程序 | 实战开发】常用的视图容器类组件介绍和使用(1)

    个人名片: 🐼 作者简介:一名大二在校生,喜欢编程🎋 🐻‍❄️ 个人主页🥇: 小新爱学习. 🐼 个人WeChat:hmmwx53 🕊️ 系列专栏:🖼️ 零基础学Java——小白入门必备 重识C语言——复习回顾

    2024年02月02日
    浏览(57)
  • 支付宝小程序 组件 web-view h5交互

    目录结构 支付宝小程序 /pages/index/index.axml /pages/index/index.js /pages/index/index.json 组件  /component/index-page/index.axml  /component/index-page/index.js   /component/index-page/index.json web-view /pages/web/web.axml /pages/web/web.js h5

    2024年02月13日
    浏览(45)
  • 小程序webview组件,小程序和webview交互,小程序内联h5页面,小程序webview内网页实现微信支付

    小程序支持webview以后,我们开发的好多h5页面,就可以直接在小程序里使用了,比如我们开发的微信商城,文章详情页,商品详情页,就可以开发一套,多处使用了。我们今天来讲一讲。在小程序的webview里实现微信支付功能。因为微信不允许在小程序的webview里直接调起微信

    2024年02月09日
    浏览(63)
  • 微信小程序大转盘完整代码

    微信小程序大转盘完整代码 谢谢,代码简洁明了,生活不易忘多多支持,祝你前程似锦。 咨询问题,回复,“笔者”获取联系方式

    2024年02月11日
    浏览(97)
  • 前端 vite+vue3——写一个随机抽奖组件

    大家好,我是yma16,本文分享关于前端 vite+vue3——写一个抽奖随机组件。 vue3系列相关文章: 前端vue2、vue3去掉url路由“ # ”号——nginx配置 csdn新星计划vue3+ts+antd赛道——利用inscode搭建vue3(ts)+antd前端模板 认识vite_vue3 初始化项目到打包 python_selenuim获取csdn新星赛道选手所在城

    2024年02月08日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包