找茬小游戏,uniapp小程序端+pc端操作静态页

5 篇文章 0 订阅
3 篇文章 0 订阅

在这里插入图片描述

需求:

做一个类似找茬的答题小程序;
提交后根据坐标返回值在图中标识出点对、点错、未点的茬;
pc端页面也要写一个,用于用户设置点位。

难点:

pc端和小程序端宽高比例的问题;
如何判定是否选对;

干扰项:

选择区域不一定从页面0,0的起始位置,需要根据实际情况减去这部分宽高,例如小程序端减了时间所占的高度。
pc端放了2个div,也减了

后端:

后端需要判定圆与圆之间偏移量多大视为选中,如图所示,xy偏移量为25,这里前端不去做判断,只需要后端给type就行

在这里插入图片描述

<template>
	<view>
		<view class="time">
			03:12
		</view>
		<view class="edit" @tap="xy" :style="{'width':trans(pcW)+'px','height':trans(pcH)+'px'}">
			<view class="editMask" :style="{'width':trans(pcW)+'px','height':trans(pcH)+'px'}">
				<view :class="item.type===1?'green':item.type==2?'red':'yellow'" v-for="(item,idx) in xyArr[index]" :key="idx" 
				:style="{
					'left': (item.x - trans(pcRoundMargin))+'px',
					'top':(item.y - trans(pcRoundMargin))+'px',
					'width':trans(pcRoundW)+'px',
					'height':trans(pcRoundW)+'px',
					'border-color':trans(pcBorder)+'px'}">
				</view>
			</view>
			<image :src="imgs[index]" :style="{'height':trans(pcH)+'px'}"></image>
		</view>
		<view class="operat">
			<u-button type="primary" text="上一题" @tap="tapIndex(0)" :disabled="index?false:true" plain
				custom-style="width:180rpx"></u-button>
			<u-button type="primary" text="下一题" @tap="tapIndex(1)" :disabled="index === total?true:false" plain
				custom-style="width:180rpx"></u-button>
			<u-button type="primary" text="提交" @tap="submit" custom-style="width:150rpx"></u-button>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				timeH: 0, //时间的高度
				xyArr: [],//xy的坐标数组
				imgs: ['你的图片', '你的图片'],
				index: 0, //当前下标
				total: 1 ,//总题数
				count:0,//(pc可操作窗口宽  -  手机屏宽) / pc可操作窗口宽 = pc每个像素要减的宽度
				countApp:0,//(pc可操作窗口宽  -  手机屏宽) / 手机屏宽 = 手机每个像素要减的宽度
				time:'',
				// type 1【选对】 2【选错】 3【未选】
				arr:[[{"x":"176.000","y":"158.000",'type':1},{"x":"649.000","y":"152.000",'type':2},{"x":"153.000","y":"382.000",'type':3}],[{"x":"153.000","y":"382.000",'type':3},{"x":"657.000","y":"377.000",'type':2}]],
				pcW:750,//pc端配置项,宽高一致
				pcH:450,
				pcBorder:4,//线粗
				pcRoundW:76,//圆的大小
				pcRoundMargin:40//这里xy减30是因为点击起始点为左上角,要减去圆形半径,向上移动
			}
		},
		created() {
			
		},
		mounted() {
			this.count = (this.pcW - uni.getSystemInfoSync().windowWidth) / this.pcW;//计算pc端和移动端比例
			this.countApp = (this.pcW - uni.getSystemInfoSync().windowWidth) / uni.getSystemInfoSync().windowWidth;//计算pc端和移动端比例
			
			this.getXY();
			// 距离顶部的高度,用于去除不计算的部分
			const query = uni.createSelectorQuery().in(this)
			query.select('.time').boundingClientRect(data => {
				this.timeH = data.height.toFixed(3);
			}).exec();
			
			for(let i = 0;i<=this.total;i++){//给xyArr塞空数组
				this.xyArr.push([])
			}
		},
		methods: {
			xy(e) {
				this.x = e.detail.x.toFixed(3);
				this.y = (e.detail.y - this.timeH).toFixed(3);
				let x = e.detail.x.toFixed(3);
				let y = (e.detail.y - this.timeH).toFixed(3);
				this.radius(x, y);
			},
			radius(x, y) {
				this.xyArr[this.index].push({x,y});
			},
			tapIndex(e) {
				if (e) { //下一题
					this.index = this.index + 1
				} else { //上一题
					this.index = this.index - 1
				}
			},
			getXY(){//pc返回值比对
				let arr = [];
				this.arr.forEach((ele,index)=>{
					arr.push([]);
					ele.forEach(e=>{
						arr[index].push({
							x:this.trans(e.x),
							y:this.trans(e.y),
							type:e.type
						})
					})
				})
				this.xyArr = arr; 
			},
			trans(e){//pc转移动的长度
				return parseFloat(e - (e * this.count));
			},
			transApp(e){//将移动端的转成pc端接收的点
				return parseFloat(e + (e * this.countApp));
			},
			submit(){
				let arr = [];
				this.xyArr.forEach((ele,index)=>{
					arr.push([]);
					ele.forEach(e=>{
						arr[index].push({
							x:this.transApp(e.x),
							y:this.transApp(e.y)
						})
					})
				})
				console.log(JSON.stringify(this.xyArr))
				console.log(JSON.stringify(arr))
			}
		}
	}
</script>

<style lang="scss" scoped>
	.edit {
		// width: 750rpx;
		// height: 750rpx;

		image {
			width: 100%;
			height: 100%;
		}

		.editMask {
			// width: 750rpx;
			// height: 750rpx;
			position: absolute;
			z-index: 1;

			view {
				border-radius: 50%;
				// width: 92rpx;
				// height: 92rpx;
				position: absolute;
			}

			.red {
				border: solid #e54031;
			}

			.yellow {
				border: solid #fbc21a;
			}

			.green {
				border: solid #229241;
			}
		}
	}

	.time {
		text-align: center;
		padding: 20rpx;
	}

	.operat {
		padding: 20rpx;
		justify-content: space-between;
		display: flex;
	}
</style>

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="这里是vue.js"></script>
	</head>

	<body>
		<div class="app">
			<div style="width: 55px;height: 55px;"></div>
			<div style="display: flex;">
				<div style="width: 55px;height: 55px;"></div>
				<div class="edit" @click="xy($event)" ref="edit">
					<div class="editMask">
						<!--这里xy减30是因为点击起始点为左上角,要减去圆形半径,向上移动-->
						<div class="yellow" v-for="(item,idx) in xyArr[index]" :key="idx" :style="{'left':(item.x - 40)+'px','top':(item.y - 40)+'px'}"> </div>
					</div>
					<image :src="imgs[index]" mode="widthFix"></image>
				</div>
			</div>
			
			<div class="operat">
				<button class="primary" @click="tapIndex(0)" :disabled="index?false:true">
					上一题
				</button>
				<button class="primary" @click="tapIndex(1)" :disabled="index === total?true:false">
					下一题
				</button>
				<button class="primary" @click="submit">
					保存
				</button>
			</div>
		</div>
	</body>
	<script>
		new Vue({
			el: '.app',
			data: {
				topH: 0, //距离顶部的高度
				leftH: 0, //距离左侧的高度
				xyArr: [],
				imgs: ['你的图片', '你的图片'],
				index: 0, //当前下标
				total: 1, //总题数
				arr:[[{"x":"176.000","y":"158.000",'type':1},{"x":"136.000","y":"118.000",'type':2},{"x":"649.000","y":"152.000",'type':2},{"x":"153.000","y":"382.000",'type':3}],[{"x":"153.000","y":"382.000",'type':3},{"x":"657.000","y":"377.000",'type':2}]]
			},
			mounted() {
				this.topH = this.$refs.edit.getBoundingClientRect().top - 8;
				this.leftH = this.$refs.edit.getBoundingClientRect().left - 8;
				for(let i = 0; i <= this.total; i++) { //给xyArr塞空数组
					this.xyArr.push([])
				}
//this.xyArr = this.arr; 
			},
			methods: {
				xy(e) {
					let x = (e.x - this.leftH).toFixed(3);
					let y = (e.y - this.topH).toFixed(3);
					console.log(x)
					console.log(y)
					this.radius(x, y);
				},
				radius(x, y) {
					this.xyArr[this.index].push({ x, y });
				},
				tapIndex(e) {
					if(e) { //下一题
						this.index = this.index + 1
					} else { //上一题
						this.index = this.index - 1
					}
				},
				submit(){
					console.log(this.xyArr)
					console.log(JSON.stringify(this.xyArr))
					
				}
			}
		})
	</script>
	<style type="text/css">
		body{margin: 0;}
		.edit {
			width: 750px;
			height: 450px;
		}

		.edit img {
			width: 100%;
			height: 100%;
		}
		
		.edit .editMask {
			overflow: hidden;
			width: 750px;
			height: 450px;
			position: absolute;
			z-index: 1;
		}
		
		.edit .editMask div {
			border-radius: 50%;
			width: 76px;
			height: 76px;
			position: absolute;
		}
		
		.edit .editMask .red {
			border: 4px solid #e54031;
		}
		
		.edit .editMask .yellow {
			border: 4px solid #fbc21a;
		}
		
		.edit .editMask .green {
			border: 4px solid #229241;
		}
		
		.time {
			text-align: center;
			padding: 20px;
		}
		
		.operat {
			padding: 20px;
			justify-content: space-between;
			display: flex;
		}
		.operat .primary{
			width: 80px;
		}
	</style>

</html>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值