首页 > 其他分享 >uniapp 用view画抽奖转盘

uniapp 用view画抽奖转盘

时间:2023-01-30 11:46:23浏览次数:38  
标签:uniapp rotateDeg center title height width result 转盘 view

实现思路:

  因为是画转盘,而不是画扇形,所以可以绕过用view画扇形,直接画一个圆,然后画几条直径,把文字写入的时候旋转一下就可以了。

以6等分为例,实现步骤:

  1. 画转盘背景:
    • 画一个圆,填充背景颜色;
    • 用“子绝父相”布局,画一条直径,垂直居中;
    • 再画一条直径,旋转60度;
    • 画第三条直径,旋转120度;
  2. 在转盘背景上写文字:
    • 以圆的外接矩形为外层容器,设置绝对布局和flex布局水平居中;
    • 内层view设置绝对布局,写入数据;
    • 由于绝对布局和外层容器设置了水平居中,所有的内层view都堆在中心,水平居中;
    • 以中心为旋转点,内层view分别旋转 -60度、-120度;-180度、-240度、-300度;
    • 设置文字方向垂直,写入完成;
  3. 画转盘上指针:
    • 样式可以自定义。
  4. 增加旋转动画。

实现效果:

 

具体代码如下(添加了禁止连续点击多次):

<!-- 抽奖转盘 -->
<template>
    <view id="app">
        <view class="title">{{showTextList[result].title}}</view>
        <view class="container" @click="startLottery" :style="{ top: windowSize.height * 0.05 + 'px' }">
            <!-- 转盘 -->
            <view class="circle" :animation="animationData">
                <view class="lines">
                    <view v-for="(item, index) in lineList" :style="{ transform: 'rotate(' + item.rotateDeg + 'deg)' }">
                    </view>
                </view>

                <view class="texts">
                    <view v-for="(item, index) in showTextList"
                        :style="{ transform: 'rotate(' + item.rotateDeg + 'deg)' }">
                        {{ item.title }}
                    </view>
                </view>
            </view>
            <!-- 指针 -->
            <view class="pointer">
                <view class="pointer-triangle" :style="{
            borderBottomWidth: windowSize.width / 14 + 'px',
            borderRightWidth: windowSize.width / 30 + 'px',
            borderLeftWidth: windowSize.width / 30 + 'px',
          }"></view>
                <view class="pointer-circle" :style="{
            width: windowSize.width / 12 + 'px',
            height: windowSize.width / 12 + 'px',
          }">GO</view>
            </view>
        </view>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                windowSize: {},
                lineList: [],
                showTextList: [],
                isClicked: false,
                animationData: {},
                lastResult: 0,
                result: 0,
                deg: 0,
            };
        },
        onl oad() {
            this.initData();
        },
        mounted() {
            this.windowSize = this.getWindowSize();
        },
        methods: {
            /* 获取屏幕可用尺寸 */
            getWindowSize() {
                const windowInfo = uni.getWindowInfo();
                let availableWindowSize = {
                    width: 0,
                    height: 0
                };
                availableWindowSize.width = windowInfo.windowWidth; //px
                availableWindowSize.height = windowInfo.windowHeight; //px
                // console.log("windowSize", this.windowSize);
                return availableWindowSize;
            },
            // 初始化数据
            initData() {
                this.lineList = [{
                    rotateDeg: 0,
                }, {
                    rotateDeg: 60,
                }, {
                    rotateDeg: 120,
                }];
                // 文字要逆时针旋转
                this.showTextList = [{
                        title: "1:跑步",
                        rotateDeg: 0
                    },
                    {
                        title: "2:游泳",
                        rotateDeg: -60
                    },
                    {
                        title: "3:666",
                        rotateDeg: -120
                    },
                    {
                        title: "4:打拳",
                        rotateDeg: -180
                    },
                    {
                        title: "5:剑道",
                        rotateDeg: -240
                    },
                    {
                        title: "6:play piano",
                        rotateDeg: -300
                    }
                ];
            },
            /* 开始旋转抽奖 */
            startLottery() {
                if (this.isClicked) {
                    //已经点击了
                    console.log("点击太频繁啦");
                    return;
                }
                this.isClicked = true;

                let animation = uni.createAnimation({
                    transformOrigin: "50% 50%",
                    duration:2000,
                    timingFunction: "ease-in-out",
                    delay: 0,
                });
                this.animationData = animation;
                this.animationData.rotate(this.randomNum()).step();
                this.animationData = this.animationData.export();

                setTimeout(() => {
                    this.isClicked = false;
                }, 2000);
            },
            /* 获取随机数 */
            randomNum() {
                this.result = Math.floor(Math.random() * 6); //数组索引:[0,5]
                if (this.result > this.lastResult) {
                    this.deg += 360 * 4 + (this.result - this.lastResult) * 60;
                } else {
                    this.deg += 360 * 4 + 360 - (this.lastResult - this.result) * 60;
                }
                // console.log(`result:${this.result},deg:${this.deg}`);
                this.lastResult = this.result;

                return this.deg;
            },
        },
    };
</script>

<style scoped>
    .title{
        text-align: center;
    }
    .container {
        position: relative;
        width: 100%;
        /* background: rgba(87, 189, 106, 0.5); */
        border: 1rpx solid skyblue;
    }

    .circle {
        position: relative;
        margin: auto;
        width: 400rpx;
        height: 400rpx;
        border-radius: 50%;
        border: 20rpx solid goldenrod;
        background: rgba(0, 112, 46, 0.8);
    }

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

    .lines>view {
        display: inline-block;
        width: 100%;
        height: 1%;
        position: absolute;
        transform-origin: center center;
        background-color: #f5b362;
    }

    .texts {
        position: absolute;
        width: 100%;
        height: 100%;
        top: 0;
        left: 0;
        display: flex;
        justify-content: center;
    }

    .texts view {
        display: inline-block;
        height: 96%;
        color: white;
        position: absolute;
        writing-mode: vertical-lr;
        transform-origin: center center;
        /* background-color: #bd2d30; */
    }

    .pointer {
        position: absolute;
        margin: auto;
        width: 100%;
        height: 100%;
        top: 0;
        left: 0;
        /* border: 5rpx solid yellow; */
    }

    .pointer-triangle,
    .pointer-circle {
        position: absolute;
        z-index: 1;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        display: inline-block;
    }

    .pointer-triangle {
        width: 0;
        height: 0;
        border-style: solid;
        border-top-width: 0px;
        border-color: transparent transparent #bd2d30 transparent;
        transform: translate(-50%, -100%);
    }

    .pointer-circle {
        display: flex;
        justify-content: center;
        align-items: center;
        border-radius: 50%;
        color: white;
        font-weight: bold;
        background: #bd2d30;
    }
</style>

 

标签:uniapp,rotateDeg,center,title,height,width,result,转盘,view
From: https://www.cnblogs.com/sunshine233/p/17074990.html

相关文章

  • Android TextView 丰富多彩的字体样式代码
    importjava.io.IOException;importorg.xmlpull.v1.XmlPullParserException;importandroid.app.Activity;importandroid.content.res.ColorStateList;importandroid.con......
  • uniapp开发微信小程序当前页面不可转发
    创建一个mixins,我的文件路径为:common/share.jsexportdefault{onShareAppMessage(res){//发送给朋友return{}},onShareTimeline(res){/......
  • Android开发 自定义View_时钟
    前言自定义View实现时钟涉及到三角函数,如果你对三角函数不甚了解或者已经遗忘,请参考我的博客:圆与三角函数的公式与使用  这篇博客详细解释了三角函数公式与对应坐......
  • svg之viewbox缩放
    先看个示例代码如下:<!DOCTYPEhtml><html><head> <metacharset="utf-8"> <title>svg-viewbox</title> <style> body{ text-align:center; } svg{ margin......
  • XnView 1.96.5
    非常棒的图像查看程序。支持150种图片格式,除一般的查看、浏览、幻灯显示等功能外,还自带30多面滤镜,方便编辑修改;可以批量转换文件格式,创建缩略图并生成网页,还可自己制作GIF......
  • 远程控制软件 TeamViewer 4.0.5459 简体中文版
    优点:没什么说的。亮点:支持直接拖放文件或目录到被控机器屏幕(目录),这个好!缺点:被控制的目标机器被锁定后无法使用屏幕连接访问,郁闷。。。啊下载地址:​​​http://vbcoder.qupan......
  • flutter Listview physics常见子类
    ListView的physics是ScrollPhysics类:其常见子类有BouncingScrollPhysics :允许滚动超出边界,但之后内容会反弹回来。ClampingScrollPhysics :防止滚动超出边界,夹住 。......
  • uView2.0 对http进行封装
    request.js://此vm参数为页面的实例,可以通过它引用vuex中的变量import{$config}from'@/config/config';module.exports=(vm)=>{//初始化请求配置uni.$......
  • AnyViewer
    近年来,越来越多的人需要远程办公,远程为用户提供服务或支持等,导致人们对远程控制软件的需求不断增加。但现在市面上远程控制软件参差不齐,有的远程控制软件功能不齐全,有的操作......
  • 视频直播源码,uniapp checkbox 怎么判断是否选中
    视频直播源码,uniappcheckbox怎么判断是否选中<checkbox-group@change="selfChangde"name=""><label><checkbox:checked="selfChecked"color="#DC143C"style="trans......