switch.wxml
<view class="main-container" style="background-color: {{value ? '#9aa6d6' : '#20114c'}}; transform: scale({{size}})" bindtap="onClick">
<view class="content" style="left: {{value ? '0' : '-80rpx'}}">
<!-- 云 -->
<view class="left">
<view
class="cloud"
wx:for="{{cloudList}}"
wx:key="id"
style="top: {{item.top}}rpx; left: {{value ? item.left : 0}}rpx; transform: scale({{item.scale}}); transition: {{item.transition}}s"
>
<view class="cloud-square"></view>
<view class="cloud-circle"></view>
<view class="cloud-circle small"></view>
</view>
</view>
<!-- 太阳 and 月亮 -->
<view class="middle" style="background-color: {{value ? '#ffe2a1' : '#fff'}}">
<view class="crater-box" style="transform: {{!value ? 'translate(0,0)' : 'translate(50rpx,-50rpx)'}}">
<view
class="crater crater{{item.id}}"
wx:for="{{craterList}}"
wx:key="id"
style="top: {{item.top}}rpx; left: {{item.left}}rpx; transform: scale({{item.scale}}); opacity: {{item.opacity}}"
></view>
</view>
</view>
<!-- 星星 -->
<view class="right">
<view class="star-box">
<view
class="star star{{item.id}} {{!value ? 'twinkle' : ''}}"
wx:for="{{starList}}"
wx:key="id"
style="top: {{item.top}}rpx; left: {{!value ? item.left : 50}}rpx; transition: {{item.transition}}s; animation-delay: {{item.delay}}s"
></view>
</view>
</view>
</view>
</view>
switch.wxss
.main-container {
position: relative;
width: 160rpx;
height: 80rpx;
background-color: #20114c;
border-radius: 40rpx;
transition: 1s all cubic-bezier(0.2, 0.1, 0.1, 0.8);
overflow: hidden;
}
.content {
position: absolute;
top: 0;
height: 100%;
width: 240rpx;
transition: 0.6s all cubic-bezier(0.2, 0.1, 0.1, 0.8);
overflow: hidden;
}
.left {
position: absolute;
top: 50%;
left: 0;
height: 100%;
width: 86rpx;
transform: translateY(-50%);
z-index: 1;
}
.cloud {
top: 50%;
left: 50%;
position: absolute;
width: 36rpx;
height: 26rpx;
}
.cloud-square {
position: absolute;
bottom: 0;
width: 36rpx;
height: 18rpx;
border-radius: 9rpx;
background-color: #fff;
}
.cloud-circle {
position: absolute;
top: 0;
right: 4rpx;
height: 18rpx;
width: 18rpx;
border-radius: 9rpx;
background-color: #fff;
}
.cloud-circle.small {
top: 4rpx;
left: 2rpx;
transform: scale(0.8);
}
.middle {
position: absolute;
top: 50%;
left: 50%;
width: 66rpx;
height: 66rpx;
border-radius: 33rpx;
transform: translate(-50%, -50%);
overflow: hidden;
transition: 0.6s all cubic-bezier(0.2, 0.1, 0.1, 0.8);
box-shadow: 0 0 10rpx rgba(255, 255, 255, 0.5);
}
.crater-box {
transition: 0.6s;
}
.crater {
position: absolute;
width: 28rpx;
height: 28rpx;
border-radius: 50%;
background: linear-gradient(to bottom, #efedf3, #fff);
}
.right {
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 0;
height: 100%;
width: 86rpx;
z-index: 1;
overflow: hidden;
}
.star-box {
height: 100%;
}
.star {
position: absolute;
width: 10rpx;
height: 10rpx;
border-radius: 50%;
background-color: #fff;
transition: 0.2s;
}
.star1 {
width: 2rpx;
height: 2rpx;
}
.star2 {
width: 4rpx;
height: 4rpx;
}
.star3 {
width: 3rpx;
height: 3rpx;
}
.star4 {
width: 5rpx;
height: 5rpx;
}
.star5 {
width: 3rpx;
height: 3rpx;
}
.star6 {
width: 3rpx;
height: 3rpx;
}
.twinkle {
animation: twinkle 2s infinite ease-in-out;
}
@keyframes dawn {
0%,
100% {
background-color: #fff;
}
80% {
background-color: #e2fdff;
}
90% {
background-color: #edffff;
}
}
@keyframes twinkle {
0%,
100% {
transform: scale(1);
}
20% {
transform: scale(1.2);
}
40% {
transform: scale(1.4);
}
60% {
transform: scale(1.2);
}
80% {
transform: scale(1.1);
}
}
switch.js
Component({
properties: {
// 开关缩放倍数 (0.5-2)
size: {
type: [Number, String],
value: 1
},
// 通过value双向绑定的值
value: {
type: Boolean,
value: false
},
// 打开选择器时的值
activeValue: {
type: [Number, String, Boolean],
value: true
},
// 关闭选择器时的值
inactiveValue: {
type: [Number, String, Boolean],
value: false
}
},
data: {
cloudList: [
{
id: 1,
top: 30,
left: 12,
scale: 0.8,
transition: 0.2
},
{
id: 2,
top: 8,
left: 40,
scale: 0.4,
transition: 0.4
},
{
id: 3,
top: 46,
left: 50,
scale: 0.6,
transition: 0.8
}
],
starList: [
{
id: 1,
top: 24,
left: 12,
delay: 0.2,
transition: 0.2
},
{
id: 2,
top: 26,
left: 24,
delay: 0.5,
transition: 0.4
},
{
id: 3,
top: 42,
left: 28,
delay: 0.3,
transition: 0.8
},
{
id: 4,
top: 54,
left: 38,
delay: 0.7,
transition: 0.8
},
{
id: 5,
top: 32,
left: 46,
delay: 0.8,
transition: 0.8
},
{
id: 6,
top: 46,
left: 50,
delay: 0.6,
transition: 0.8
}
],
craterList: [
{
id: 1,
top: 6,
left: 28,
scale: 0.3,
opacity: 0.6
},
{
id: 2,
top: 12,
left: 10,
scale: 0.4,
opacity: 0.8
},
{
id: 3,
top: 24,
left: 32,
scale: 0.6,
opacity: 1
},
{
id: 4,
top: 28,
left: 10,
scale: 0.2,
opacity: 0.4
}
]
},
methods: {
onClick() {
const newValue = !this.data.value;
this.setData({
value: newValue
});
this.triggerEvent('input', newValue);
this.triggerEvent('change', newValue ? this.data.activeValue : this.data.inactiveValue);
console.log(newValue)
}
}
});
switch.json
{
"component": true,
"usingComponents": {}
}
引入组件
"usingComponents": {
"v-switch": "/components/switch/switch"
},
使用组件
<v-switch value="{{switchValue}}" size="0.7" active-value="1" inactive-value="0" bind:change="onChangeChecked" bind:input="onChangeCheckedInput"></v-switch>
uniapp版参考原作者:https://ext.dcloud.net.cn/plugin?id=3469