修改域名配置等文件

This commit is contained in:
2024-12-03 14:39:48 +08:00
parent f1f5b666b5
commit fb8c9f8431
20 changed files with 1174 additions and 14 deletions

View File

@@ -0,0 +1,130 @@
@mixin theme($property, $variable) {
$theme: (
'dialer_text_color': #ffb400,
'dialer_prize_font_size': 12px,
'dialer_prize_name_padding': 8px,
'dialer_prize_inner_padding': 8px,
'dialer_prize_image_size': 36px
);
$value: map-get($theme, $variable);
#{$property}: $value;
/* #ifndef APP-IOS || APP-ANDROID */
$css-variable: var(--#{$variable}, #{$value});
#{$property}: #{$css-variable};
/* #endif */
}
.l-dialer {
position: relative;
&__inner {
width: 100%;
height: 100%;
flex:1;
position: relative;
@include theme('color', 'dialer_text_color');
background-repeat: no-repeat;
background-size: cover;
box-sizing: border-box;
border-radius: 999px;
overflow: hidden;
// transition: transform 3s ease;
// transform-origin: 50% 50%;
transition-property: transform;
transition-timing-function: cubic-bezier(0.250, 0.460, 0.455, 0.995);
&-border {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
}
&-wrap {
position: relative;
z-index: 1;
width: 100%;
height: 100%;
border-radius: 999px;
overflow: hidden;
box-sizing: border-box;
// background: red;
/* #ifndef APP-ANDROID */
&::after {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
content: '';
border-radius: 50%;
box-shadow: 0 0 20rpx currentColor inset;
}
/* #endif */
}
&-item {
overflow: hidden;
position: absolute;
top: -50%;
left: 50%;
width: 100%;
height: 100%;
transform-origin: 0 100%;
}
&-content {
position: absolute;
@include theme('padding-top', 'dialer_prize_inner_padding');
box-sizing: border-box;
width: 100%;
height: 100%;
left: -50%;
bottom: -50%;
display: flex;
flex-direction: column;
align-items: center;
}
&-name {
@include theme('padding-top', 'dialer_prize_name_padding');
@include theme('padding-bottom', 'dialer_prize_name_padding');
@include theme('font-size', 'dialer_prize_font_size');
@include theme('color', 'dialer_text_color');
}
&-img {
@include theme('width', 'dialer_prize_image_size');
@include theme('height', 'dialer_prize_image_size');
}
}
&__pointer {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 1;
}
}
/* #ifndef APP-IOS || APP-ANDROID */
.heart {
animation: heart 1s infinite;
}
@keyframes heart {
0% {
transform: scale(1);
}
25% {
transform: scale(1.03);
}
to {
transform: scale(1);
}
}
/* #endif */

View File

@@ -0,0 +1,111 @@
replace2(val)
r = match('\$[^() ]+', val, 'gi')
re = val
for v, i in r
k = split(v, re)
j = s('%s', convert(v))
re = join(j, k)
unquote(re)
theme($property, $imp)
a = replace('(\$[^() ]+)', '$1', $imp)
// #ifndef APP-NVUE
b = replace('(\$)([^() ]+)', 'var(--$2, $1$2)', $imp)
// #endif
{$property} replace2(a)
// #ifndef APP-NVUE
{$property} replace2(b)
// #endif
$dialer_text_color ?= #ffb400
$dialer_prize_font_size ?= 12px
$dialer_prize_name_padding ?= 8px
$dialer_prize_inner_padding ?= 8px
$dialer_prize_image_size ?= 36px
.l-dialer
position relative
&__inner
width 100%
height 100%
position relative
// color $dialer_text_color
theme('color', '$dialer_text_color')
background-repeat no-repeat
background-size cover
box-sizing border-box
&-border
position absolute
left 0
top 0
bottom 0
right 0
&-wrap
position relative
z-index 1
// flex 1
width 100%
height 100%
border-radius 50%
overflow hidden
box-sizing border-box
&::after
position absolute
left 0
top 0
bottom 0
right 0
content ''
border-radius 50%
box-shadow 0 0 20rpx currentColor inset
&-item
overflow hidden
position absolute
top -50%
left 50%
width 100%
height 100%
transform-origin 0 100%
&-content
position absolute
theme('padding-top', '$dialer_prize_inner_padding')
// padding-top $dialer_prize_inner_padding
box-sizing border-box
width 100%
height 100%
left -50%
bottom -50%
display flex
flex-direction column
align-items center
&-name
theme('padding-top', '$dialer_prize_name_padding')
theme('padding-bottom', '$dialer_prize_name_padding')
theme('font-size', '$dialer_prize_font_size')
theme('color', '$dialer_text_color')
// padding-top $dialer_prize_name_padding
// padding-bottom $dialer_prize_name_padding
// font-size $dialer_prize_font_size
// color $dialer_text_color
&-img
// margin-top 24rpx
theme('width', '$dialer_prize_image_size')
theme('height', '$dialer_prize_image_size')
// width $dialer_prize_image_size
// height $dialer_prize_image_size
&__pointer
position absolute
left 50%
top 50%
transform translate(-50%, -50%)
z-index 1
.heart
animation heart 1s infinite
@keyframes heart
0%
transform scale(1)
25%
transform scale(1.03)
to
transform scale(1)

View File

@@ -0,0 +1,260 @@
<template>
<view class="l-dialer" :style="rootStyles">
<view class="l-dialer__inner" :style="innerStyle">
<view class="l-dialer__inner-border" v-if="$slots['border'] != null">
<slot name="border" />
</view>
<view class="l-dialer__inner-wrap" ref="drawbleRef" :style="wrapStyle">
<view class="l-dialer__inner-item" v-for="(item, index) in prizeList" :key="index"
:style="itemStyle(index)">
<view class="l-dialer__inner-content" :style="contentStyle(index)">
<slot v-if="$slots['prize'] != null" name="prize" :item="item" :even="index % 2"></slot>
<template v-else>
<text class="l-dialer__inner-name" :style="nameStyle">{{ item['name'] }}</text>
<image class="l-dialer__inner-img" :src="item['img']"></image>
</template>
</view>
</view>
</view>
</view>
<view class="l-dialer__pointer" :style="pointerStyle">
<slot v-if="$slots['pointer'] != null" name="pointer" />
<image v-else :class="!isTurnIng ? 'heart' : ''" src="/uni_modules/lime-dialer/static/turnable_btn.png"
style="width: 100%" mode="widthFix" @tap="$emit('click')" />
</view>
</view>
</template>
<script lang="uts" setup>
const emits = defineEmits(['click', 'done'])
const slots = defineSlots<{
prize : {
item : UTSJSONObject,
even : number
}
}>()
const props = defineProps({
size: {
// #ifdef APP-ANDROID
type: Object,
// #endif
// #ifndef APP-ANDROID
type: [String, Number],
// #endif
default: 300
},
prizeList: {
type: Array as PropType<UTSJSONObject[]>,
default: () : UTSJSONObject[] => []
},
turns: {
type: Number,
default: 10
},
duration: {
type: Number,
default: 3
},
styleOpt: {
type: Object as PropType<UTSJSONObject>,
default: () : UTSJSONObject => ({
// 每一块扇形的背景色,默认值,可通过父组件来改变
prizeBgColors: ['#fff0a3', '#fffce6'],
// 每一块扇形的外边框颜色,默认值,可通过父组件来改变
borderColor: '#ffd752',
} as UTSJSONObject)
},
customStyle: {
type: String,
},
dialStyle: {
type: String,
},
pointerStyle: {
type: String,
default: `width: 30%`
}
})
const drawbleRef = ref<UniElement | null>(null)
const startRotateDegree = ref(0)
const rotateAngle = ref('rotate(0deg)')
const rotateTransition = ref('')
const isTurnIng = ref(false)
const getStyleOpt = computed(() : UTSJSONObject => {
const style = {
// 每一块扇形的背景色,默认值,可通过父组件来改变
prizeBgColors: ['#fff0a3', '#fffce6'],
// 每一块扇形的外边框颜色,默认值,可通过父组件来改变
borderColor: '#ffd752',
}
return UTSJSONObject.assign(style, props.styleOpt)
})
const rootStyles = computed(() : string => {
const size = /\d$/.test(`${props.size}`) ? `${props.size}px` : props.size;
return `width: ${size}; height: ${size}; ${props.customStyle}`
})
const innerStyle = computed(() : string => {
// const style = new Map<string, string>()
let style = ''
const padding = getStyleOpt.value['padding'] ?? 0
style += `padding: ${padding};`
style += `transform: ${rotateAngle.value};`
style += `${rotateTransition.value};`//`transition: ${rotateTransition.value};`
style += `${props.dialStyle};`
return style
})
const wrapStyle = computed(() : string => {
const borderColor = getStyleOpt.value['borderColor']
if (borderColor != null) {
return `border: 1rpx solid ${borderColor}`
}
return ''
})
const itemStyle = computed(() : ((index : number) => Map<string, any>) => {
return (index : number) : Map<string, any> => {
const length = props.prizeList.length;
const prizeBgColors : string[] = (getStyleOpt.value['prizeBgColors'] ?? [] as string[]) as string[]
const prizeBgColorsLength = prizeBgColors.length;
const borderColor = getStyleOpt.value['borderColor']
const style = new Map<string, any>();
// #ifndef APP
if (length == 2) {
// style['transform'] = index == 0 ? 0 : `rotate(270deg)`
style.set('transform', index == 0 ? `rotate(0deg)` : `rotate(270deg)`)
style.set('top', 0)
} else {
style.set('transform', `rotate(${(360 / length) * index}deg) skewX(0deg) skewY(${360 / length - 90}deg)`);
}
if (prizeBgColorsLength > 0) {
style.set('backgroundColor', `${prizeBgColors[index % prizeBgColorsLength]}`)
}
if (borderColor != null) {
style.set('border', `1rpx solid ${borderColor}`)
}
// #endif
// #ifdef APP
if (length == 2) {
style.set('backgroundColor', `${prizeBgColors[index % prizeBgColorsLength]}`)
style.set('transform', index == 0 ? `rotate(0deg)` : `rotate(270deg)`);
style.set('top', 0)
if (borderColor != null) {
style.set('border', `1rpx solid ${borderColor}`)
}
} else {
style.set('transform', `rotate(${(360 / length) * index}deg)`);
}
// #endif
return style
}
})
const contentStyle = computed(() : ((index : number) => string) => {
return (index : number) : string => {
// #ifndef APP
if (props.prizeList.length != 2) {
return `transform: skewY(${90 - 360 / props.prizeList.length}deg) skewX(0deg) rotate(${180 / props.prizeList.length}deg)`
} else {
return index == 0
? `transform: rotate(90deg); bottom: 0`
: `transform: rotate(0deg); bottom: -50%; left: 0`
}
// #endif
// #ifdef APP
if (props.prizeList.length != 2) {
return `transform: rotate(${180 / props.prizeList.length}deg)`
} else {
return index == 0
? `transform: rotate(90deg); bottom: 0`
: `transform: rotate(0deg); bottom: -50%; left: 0`
}
// #endif
}
})
const nameStyle = computed(() : Map<string, any> => {
const fontSize = getStyleOpt.value['fontSize']
const color = getStyleOpt.value['color']
const style = new Map<string, any>()
if (fontSize != null) {
style.set('fontSize', fontSize)
}
if (color != null) {
style.set('color', color)
}
return style
})
const run = (index : number) => {
if (isTurnIng.value) return
const duration = props.duration;
const length = props.prizeList.length;
const _rotateAngle = startRotateDegree.value + props.turns * 360 + 360 - (180 / length + (360 / length) * index) - (startRotateDegree.value % 360);
startRotateDegree.value = _rotateAngle;
rotateAngle.value = `rotate(${_rotateAngle}deg)`;
rotateTransition.value = `transition-duration: ${duration}s`;
isTurnIng.value = true
setTimeout(() => {
emits('done', index);
isTurnIng.value = false
}, duration * 1000 + 500);
}
// #ifdef APP
onMounted(() => {
nextTick(() => {
if (drawbleRef.value == null) return;
const ctx = drawbleRef.value!.getDrawableContext()!;
const size = drawbleRef.value!.offsetWidth;
watch(props.prizeList, () => {
ctx.reset()
const length = props.prizeList.length;
if (length == 2) return
const prizeBgColors : string[] = (getStyleOpt.value['prizeBgColors'] ?? [] as string[]) as string[]
const prizeBgColorsLength = prizeBgColors.length;
const borderColor = getStyleOpt.value['borderColor'] as string | null
const centerX = size / 2;
const centerY = size / 2;
const radius = size / 2;
const angle = (2 * Math.PI) / length;
for (let i = 0; i < length; i++) {
ctx.beginPath();
ctx.moveTo(centerX, centerY);
ctx.arc(centerX, centerY, radius, i * angle, (i + 1) * angle);
ctx.lineTo(centerX, centerY);
ctx.closePath();
ctx.fillStyle = prizeBgColors[i % prizeBgColorsLength];
if (borderColor != null) {
ctx.lineWidth = 2
ctx.strokeStyle = borderColor;
ctx.stroke()
}
ctx.fill();
}
ctx.update()
}, { immediate: true })
})
})
// #endif
defineExpose({
run
})
</script>
<style lang="scss" scoped>
@import './index';
</style>

View File

@@ -0,0 +1,176 @@
<template>
<view class="l-dialer" :style="getStyle">
<view class="l-dialer__inner" :style="getDialStyle">
<view class="l-dialer__inner-border" v-if="$slots.border">
<slot name="border"/>
</view>
<view class="l-dialer__inner-wrap" :style="styleOpt.borderColor && (' border: 1rpx solid ' + styleOpt.borderColor)">
<view class="l-dialer__inner-item" v-for="(item, index) in prizeList" :key="index" :style="[getRotateAngle(index)]">
<view class="l-dialer__inner-content" :style="[getCorrectAngle(index)]">
<slot v-if="$slots.prize" name="prize" :item="item" :even="index % 2"></slot>
<block v-else>
<view class="l-dialer__inner-name" :style="[{fontSize: styleOpt.fontSize, color: styleOpt.color}]">{{ item.name }}</view>
<image class="l-dialer__inner-img" :src="item.img"></image>
</block>
</view>
</view>
</view>
</view>
<view class="l-dialer__pointer" :style="pointerStyle" >
<slot v-if="$slots && $slots.pointer" name="pointer"/>
<image
v-else
:class="!isTurnIng ? 'heart': ''"
src="/uni_modules/lime-dialer/static/turnable_btn.png"
style="width: 100%"
mode="widthFix"
@tap="$emit('click')"
/>
</view>
</view>
</template>
<script>
// import {addUnit} from '@/uni_modules/lime-shared/addUnit'
// import {sleep} from '@/uni_modules/lime-shared/sleep'
export default {
name: 'l-dialer',
emits: ['click', 'done'],
props: {
size: {
type: [String, Number],
default: 300
},
prizeList: {
type: Array
},
turns: {
type: Number,
default: 10
},
duration: {
type: Number,
default: 3
},
styleOpt: {
type: Object,
default: () => ({
// 每一块扇形的背景色,默认值,可通过父组件来改变
// $primary-1 $primary-2
prizeBgColors: ['#fff0a3', '#fffce6'],
// 每一块扇形的外边框颜色,默认值,可通过父组件来改变
// primary-4
borderColor: '#ffd752',
})
},
customStyle: {
type: String,
},
dialStyle: {
type: String,
},
pointerStyle: {
type: String,
default: `width: 30%`
}
},
data() {
return {
// 开始转动的角度
startRotateDegree: 0,
// 设置指针默认指向的位置,现在是默认指向2个扇形之间的边线上
rotateAngle: 0,
rotateTransition: '',
isTurnIng: false,
};
},
computed: {
getStyleOpt() {
const style = {
// 每一块扇形的背景色,默认值,可通过父组件来改变
prizeBgColors: ['#fff0a3', '#fffce6'],
// 每一块扇形的外边框颜色,默认值,可通过父组件来改变
borderColor: '#ffd752',
}
return Object.assign(style, this.styleOpt)
},
getRotateAngle() {
return index => {
const style = {
transform: `rotate(${(360 / this.prizeList.length) * index}deg) skewX(0deg) skewY(${360 / this.prizeList.length - 90}deg)`,
backgroundColor: `${this.getStyleOpt.prizeBgColors[index % this.getStyleOpt.prizeBgColors.length]}`,
border: `${this.getStyleOpt.borderColor && '1rpx solid ' + this.getStyleOpt.borderColor }`
}
if(this.prizeList.length == 2) {
style['transform'] = index == 0 ? 0 : `rotate(270deg)` //`rotate(${(360 / this.prizeList.length) * index}deg)`
style['top'] = 0
}
return style
// return {
// transform: `rotate(${(360 / this.prizeList.length) * index}deg) skewX(0deg) skewY(${360 / this.prizeList.length - 90}deg)`,
// backgroundColor: `${this.styleOpt.prizeBgColors[index % this.styleOpt.prizeBgColors.length]}`,
// border: `${this.styleOpt.borderColor && '1rpx solid ' + this.styleOpt.borderColor }`
// }
};
},
getCorrectAngle() {
return index => {
const style = {
transform: `skewY(${90 - 360 / this.prizeList.length}deg) skewX(0deg) rotate(${180 / this.prizeList.length}deg)`
}
if(this.prizeList.length == 2){
if(index == 0) {
style['transform'] = `rotate(90deg)`
style['bottom'] = 0
} else {
style['transform'] = `rotate(0deg)`
style['left'] = 0
style['bottom'] = '-50%'
}
}
return style
};
},
getStyle() {
let { size, customStyle } = this;
//addUnit(size)//
size = /\d$/.test(size) ? size + 'px' : size;
return `width: ${size}; height: ${size}; ${customStyle}`;
},
getDialStyle() {
return `
padding: ${this.getStyleOpt.padding};
transform: ${this.rotateAngle};
transition: ${this.rotateTransition};
${this.dialStyle}
`;
}
},
methods: {
// 转动起来
run(index) {
if(this.isTurnIng) return
const duration = this.duration;
const length = this.prizeList.length
const rotateAngle = this.startRotateDegree + this.turns * 360 + 360 - (180 / length + (360 / length) * index) - (this.startRotateDegree % 360);
this.startRotateDegree = rotateAngle;
this.rotateAngle = `rotate(${rotateAngle}deg)`;
this.rotateTransition = `transform ${duration}s cubic-bezier(0.250, 0.460, 0.455, 0.995)`;
this.isTurnIng = true
// sleep(duration * 1000 + 500).then(() => {
// this.$emit('done', index);
// this.isTurnIng = false
// })
setTimeout(() => {
this.$emit('done', index);
this.isTurnIng = false
}, duration * 1000 + 500);
}
}
};
</script>
<style lang="scss" scoped>
@import './index';
</style>