小程序实现转盘控件

zhuanpan.gif

实现思路:

UI制作一个转盘图片,通过控制图片CSS旋转来实现控件,也可使用canvas来实现(本人小菜鸡,canvas实现太复杂!!!)。

代码如下

HTML:

<view class="weight-container">
		<view v-if="platform==='mp-jd'||platform==='mp-weixin'" @click="goBack" class="left-top-button">
			
		</view>
		<view class="title">选择您的体重</view>

		<view class="unit">kg</view>
		<view>
			<image src="https://qiniupillowcode.25youpin.com/project/icon-down@2x.png" class="icon-down"></image>
		</view>
		<view class="weight-comp" >
			<view class="card-item">{{weight}}</view>
			
			<view class="canvas-wrapper" @touchstart="startDragging" @touchmove="drag" @touchend="stopDragging" @touchleave="stopDragging">
				<view class="pointer"></view>
				<view  class="knob" :style="{transform: `rotate(${angle}deg)`,transition: isDragging ? 'none' : 'transform 0.2s ease'}">
					 <div class="indicator"></div>
				</view>
			</view>
		</view>
		<image @click="handlerNext" src="https://qiniupillowcode.25youpin.com/project/btn-step3@2x.png"
			class="step-btn-img"></image>
	</view>

scss:

	.flex_column {
		display: flex;
		flex-direction: column;
	}

	.flex_center {
		justify-content: center;
		align-items: center
	}

	.weight-container {
		box-sizing: border-box;
		width: 100%;
		height: 100vh;
		padding: 20rpx;
		display: flex;
		flex-direction: column;
		justify-content: flex-start;
		align-items: center;
		background-color: black;
		background: url(https://qiniupillowcode.25youpin.com/project/bg@2x.png) no-repeat center;
		overflow: hidden;

		.title {
			width: 100%;
			margin-top: 259rpx;
			text-align: center;
			font-size: 40rpx;
			line-height: 56rpx;
			color: #fff;
			font-weight: 400;
		}

		.unit {
			width: 152rpx;
			height: 53rpx;
			margin-top: 160rpx;
			line-height: 53rpx;
			background: rgba(193, 216, 255, 0.2);
			border-radius: 27rpx;
			border: 2px solid #C1D8FF;
			font-size: 26rpx;
			color: #C1D8FF;
			text-align: center;
		}

		.icon-down {
			margin-top: 56rpx;
			width: 60rpx;
			height: 60rpx;
		}

		.weight-comp {
			margin-top: 54rpx;
			display: flex;
			flex-direction: column;
			justify-content: center;
			align-items: center;
			width: 100%;

			.card-item {
				width: 180rpx;
				height: 221rpx;
				background: #44D4DE;
				box-shadow: 0px 2rpx 20rpx 0px rgba(193, 216, 255, 0.2), 0px -2rpx 20rpx 0px rgba(193, 216, 255, 0.2);
				border-radius: 16rpx;
				text-align: center;
				font-size: 80rpx;
				line-height: 221rpx;
				font-weight: bold;
				color: #FFFFFF;
				text-shadow: 0px 2rpx 0px rgba(0, 0, 0, 0.5);
			}

			.canvas-wrapper {
				position: relative;
				transform: translateX(-50%);
				left: 50%;
				margin: 0 auto;
				height: 300rpx;
				overflow: hidden;
				padding-top: 80rpx;

				.pointer {
					position: absolute;
					top: 80rpx;
					width: 6rpx;
					height: 80rpx;
					left: 50%;
					transform: translateX(-50%);
					box-shadow: 0px 2px 10rpx 0px rgb(68, 212, 222);
					opacity: 1;
					background: #44D4DE;
				}

				.knob {
					width: 1000rpx;
					height: 1000rpx;
					background: url('https://qiniupillowcode.25youpin.com/project/footage.png') no-repeat;
					background-size: cover;
					cursor: pointer;

					.indicator {
						position: absolute;
						top: 50%;
						left: 50%;
						width: 10rpx;
						height: 10rpx;
						border-radius: 50%;
						background-color: #333;
						transform: translate(-50%, -50%);
					}
				}
			}
		}
	}

js:

export default {	
  data() {
	return {
		weight: 60,
		sysinfo: {},
		platform: '',
		isDragging: false, //是否正在拖拽
		angle: 0, //旋转的角度 从0开始顺时针旋转,
		lastMouseX: 0 //鼠标上一次Y坐标,计算拖动距离
		}
  },
  mounted() {
	try {
		this.sysinfo = uni.getSystemInfoSync();
		this.platform = this.sysinfo.uniPlatform;
	} catch (e) {
		console.log('>>>>', e);
	}
  },
  methods:{
   //用户按下控件,记录移动开始位置
   startDragging(event) {
	  console.log("触发了", event)
	  this.isDragging = true;
	  this.lastMouseX = event.touches[0].clientX;
   },
   //开始移动了
   drag(event) {
		console.log("触发了", event)
		if (!this.isDragging) {
			return;
		}
/*共150隔 每隔就是2.4 (360/150) 最小值为20 最大为140 设置中间为60 向左
* 最小值为(60-20)*2.4=96  向右最大值为(140-60)*2.4=192
*/
		const deltaX = event.touches[0].clientX - this.lastMouseX;
		this.angle += deltaX * 0.5;
		this.lastMouseX = event.touches[0].clientX;
		if (this.angle > 96) {
			this.angle = 96
		} else if (this.angle < -192) {
			this.angle = -192
		}
		let ctemp = Math.round(this.angle / 2.4);
		if (ctemp > 0) {
			this.weight = 60 - ctemp
		} else if (ctemp < 0) {
			this.weight = 60 + Math.abs(ctemp)
		} else {
			this.weight = 60
		}
	},
   //结束移动
   stopDragging() {
		this.isDragging = false;
   },
  },
}

代码世界的构建师,现实生活的悠游者。