init
This commit is contained in:
133
uni_modules/nutui-uni/components/marquee/index.scss
Normal file
133
uni_modules/nutui-uni/components/marquee/index.scss
Normal file
@@ -0,0 +1,133 @@
|
||||
.nut-marquee {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
margin: 0 auto;
|
||||
border-radius: 8px;
|
||||
|
||||
// stylelint-disable selector-class-pattern
|
||||
|
||||
|
||||
.bgContent {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.marqueeBg {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: url("https://img10.360buyimg.com/imagetools/jfs/t1/189406/15/21216/26045/61309346E9aa7922b/5dc34e22d3a7bb0e.png")no-repeat center;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.start {
|
||||
position: relative;
|
||||
top: -5px;
|
||||
left: -2px;
|
||||
width: 75px;
|
||||
height: 75px;
|
||||
background: url("https://img13.360buyimg.com/imagetools/jfs/t1/205479/17/4245/32041/61309346E02bd3b6b/b41be60bedbb1e69.png") no-repeat center;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.disabledDraw {
|
||||
background: url("https://img10.360buyimg.com/imagetools/jfs/t1/193040/14/21217/16320/61309346E6569e270/36e45126a5f1fc9c.png") no-repeat center;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.gift-list {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
.gift-item {
|
||||
position: absolute;
|
||||
width: 75px;
|
||||
height: 75px;
|
||||
list-style: none;
|
||||
background: url("https://img10.360buyimg.com/imagetools/jfs/t1/187454/31/21425/27854/61309346E7c791c2c/a12649fbffb63a34.png") no-repeat center;
|
||||
background-size: 100% 100%;
|
||||
|
||||
.gift-img {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
margin: 8px auto;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.desc {
|
||||
display: block;
|
||||
max-width: 70px;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color:#fff;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
// 上面3个奖品
|
||||
.gift-1,.gift-2,.gift-3 {
|
||||
top: 25px;
|
||||
}
|
||||
|
||||
.gift-1 {
|
||||
left: 15px;
|
||||
}
|
||||
|
||||
.gift-2 {
|
||||
left: 110px;
|
||||
}
|
||||
|
||||
.gift-3 {
|
||||
left: 205px;
|
||||
}
|
||||
|
||||
// 中间2个奖品
|
||||
.gift-4,.gift-8 {
|
||||
top: 110px;
|
||||
}
|
||||
|
||||
.gift-4 {
|
||||
left: 205px;
|
||||
}
|
||||
|
||||
.gift-8 {
|
||||
left: 15px;
|
||||
}
|
||||
|
||||
// 下面3个奖品
|
||||
.gift-5,.gift-6,.gift-7 {
|
||||
top: 190px;
|
||||
}
|
||||
|
||||
.gift-5 {
|
||||
left: 205px;
|
||||
}
|
||||
|
||||
.gift-6 {
|
||||
left: 110px;
|
||||
}
|
||||
|
||||
.gift-7 {
|
||||
left: 15px;
|
||||
}
|
||||
|
||||
// 中奖
|
||||
.active {
|
||||
background: url("https://img10.360buyimg.com/imagetools/jfs/t1/189406/15/21216/26045/61309346E9aa7922b/5dc34e22d3a7bb0e.png") no-repeat center;
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
uni_modules/nutui-uni/components/marquee/index.ts
Normal file
1
uni_modules/nutui-uni/components/marquee/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export type * from './marquee'
|
||||
61
uni_modules/nutui-uni/components/marquee/marquee.ts
Normal file
61
uni_modules/nutui-uni/components/marquee/marquee.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import type { ExtractPropTypes } from 'vue'
|
||||
import { commonProps, makeNumericProp } from '../_utils'
|
||||
|
||||
export const marqueeProps = {
|
||||
...commonProps,
|
||||
/**
|
||||
* @description 抽奖样式
|
||||
*/
|
||||
styleOpt: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
itemStyle: {},
|
||||
startStyle: {},
|
||||
bgStyle: {
|
||||
background: 'rgb(255, 231, 149)',
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
/**
|
||||
* @description 奖品列表
|
||||
*/
|
||||
prizeList: {
|
||||
type: Array<any>,
|
||||
required: true,
|
||||
},
|
||||
/**
|
||||
* @description 是否禁用开始抽奖点击
|
||||
*/
|
||||
disabled: Boolean,
|
||||
/**
|
||||
* @description 中奖奖品的index
|
||||
*/
|
||||
prizeIndex: makeNumericProp(-1),
|
||||
/**
|
||||
* @description 初始转动速度
|
||||
*/
|
||||
speed: makeNumericProp(150),
|
||||
/**
|
||||
* @description 预抽奖,转动多少次进入抽奖环节
|
||||
*/
|
||||
circle: makeNumericProp(30),
|
||||
}
|
||||
|
||||
export type MarqueeProps = ExtractPropTypes<typeof marqueeProps>
|
||||
|
||||
export const marqueeEmits = {
|
||||
click: () => true,
|
||||
/**
|
||||
* @description 开始跑动的回调函数,此时将接口中的中奖索引,赋值到 prize-index
|
||||
*/
|
||||
startTurns: () => true,
|
||||
/**
|
||||
* @description 停止跑动后的回调函数
|
||||
*/
|
||||
endTurns: () => true,
|
||||
|
||||
}
|
||||
|
||||
export type MarqueeEmits = typeof marqueeEmits
|
||||
138
uni_modules/nutui-uni/components/marquee/marquee.vue
Normal file
138
uni_modules/nutui-uni/components/marquee/marquee.vue
Normal file
@@ -0,0 +1,138 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, defineComponent, onMounted, reactive, ref, watch } from 'vue'
|
||||
import { PREFIX } from '../_constants'
|
||||
import { getMainClass } from '../_utils'
|
||||
import { marqueeEmits, marqueeProps } from './marquee'
|
||||
|
||||
const props = defineProps(marqueeProps)
|
||||
|
||||
const emit = defineEmits(marqueeEmits)
|
||||
let { prizeList, styleOpt } = reactive(props)
|
||||
|
||||
const classes = computed(() => {
|
||||
return getMainClass(props, componentName)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
// init();
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.prizeList,
|
||||
(list, prevList) => {
|
||||
prizeList = list
|
||||
},
|
||||
)
|
||||
|
||||
const marqueeDom: any = ref(null)
|
||||
// 上锁
|
||||
const lock = ref(false)
|
||||
// 转动到的商品的index
|
||||
const index = ref(0)
|
||||
// 转动跑格子次数
|
||||
const cellNumber = ref(0)
|
||||
// 初始速度
|
||||
const velocity = ref(+props.speed)
|
||||
// 至少需要转动多少次再进入抽奖环节
|
||||
const cycle = ref(props.circle)
|
||||
// 转动定时器
|
||||
const timer = ref<any>(null)
|
||||
|
||||
const bgContentStyle = styleOpt.bgStyle
|
||||
const bgItemStyle = styleOpt.itemStyle
|
||||
const cursorStyle = styleOpt.startStyle
|
||||
|
||||
// 每次转动
|
||||
function rollMarquee() {
|
||||
cellNumber.value += 1
|
||||
let idx = index.value // 当前转动到哪个位置
|
||||
const count = 8 // 总共有多少个位置
|
||||
idx += 1
|
||||
if (idx > count - 1)
|
||||
idx = 0
|
||||
|
||||
index.value = idx
|
||||
getPrize()
|
||||
}
|
||||
|
||||
function getPrize() {
|
||||
// 当前转动次数符合条件 && 转动到中奖位置
|
||||
if (cellNumber.value > +cycle.value && props.prizeIndex === index.value) {
|
||||
clearTimeout(timer.value) // 清除转动定时器
|
||||
// 恢复默认值和初始值
|
||||
timer.value = 0
|
||||
cellNumber.value = 0
|
||||
velocity.value = +props.speed
|
||||
cycle.value = props.circle
|
||||
setTimeout(() => {
|
||||
index.value = +props.prizeIndex
|
||||
emit('endTurns')
|
||||
lock.value = false
|
||||
}, 500)
|
||||
}
|
||||
else {
|
||||
if (cellNumber.value < +cycle.value)
|
||||
velocity.value -= 4
|
||||
else
|
||||
velocity.value += 20
|
||||
|
||||
// 开始转动抽奖
|
||||
timer.value = setTimeout(rollMarquee, velocity.value)
|
||||
}
|
||||
}
|
||||
|
||||
function startDraw() {
|
||||
emit('click')
|
||||
if (props.disabled)
|
||||
return
|
||||
if (!lock.value) {
|
||||
lock.value = true
|
||||
emit('startTurns')
|
||||
rollMarquee()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
const componentName = `${PREFIX}-marquee`
|
||||
|
||||
export default defineComponent({
|
||||
name: componentName,
|
||||
options: {
|
||||
virtualHost: true,
|
||||
addGlobalClass: true,
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<view ref="marqueeDom" :class="classes" :style="customStyle">
|
||||
<view class="bgContent" />
|
||||
<view class="marqueeBg" :style="bgContentStyle" />
|
||||
<view
|
||||
class="start"
|
||||
:class="[{ disabledDraw: lock || props.disabled }]"
|
||||
:style="cursorStyle"
|
||||
@click="startDraw"
|
||||
/>
|
||||
<ul class="gift-list">
|
||||
<li
|
||||
v-for="(item, i) in prizeList"
|
||||
:key="`luckmarquee${i}`"
|
||||
class="gift-item"
|
||||
:class="[`gift-${i + 1}`, { active: index === i }]"
|
||||
:style="bgItemStyle"
|
||||
>
|
||||
<div class="gift-img">
|
||||
<image :src="item.prizeImg" />
|
||||
</div>
|
||||
<span class="desc" v-html="item.prizeName" />
|
||||
</li>
|
||||
</ul>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import './index';
|
||||
</style>
|
||||
Reference in New Issue
Block a user