【uniapp封装div盒子实现div内元素拖动效果+父组件引用子组件里面的canvas无法显示问题】

该代码示例展示了如何在Vue.js应用中结合Canvas和touch事件创建一个可移动的元素。通过监听touchstart和touchmove事件,动态计算元素的移动位置,并限制其在设备视窗内的移动范围。同时,利用Canvas绘制线条作为交互元素的一部分。
摘要由CSDN通过智能技术生成

时间问题把两个内容集合到一块了来个总结

  • 先来个动图效果,如果觉得有用再继续看代码
    在这里插入图片描述

注:图上的绿色方块内的线条即为canvas绘制

代码如下

<template>
	<view>
		<view :class="[box,width,height]" :style="{translate:`${translateX} ${translateY}`}"
			@touchstart="handleTouchStart" @touchmove="handleTouchMove">
			<view class="sky">
			</view>
			<view class="water">
			</view>
			<span class="fold" @click="show" v-show="floatingShow">
				<img src="/rightArrows.svg" alt="" style="width: 100%;height: 100%;">
			</span>
			<span class="close" @click='hiden' v-show="floatingHiden">
				<img src="/leftArrows.svg" alt="" style="width: 100%;height: 100%;">
			</span>
			<span class="rope">
				<canvas canvas-id="myCanvas"
					style="width:100%;height:100%;background-color: aquamarine;z-index: 2;"></canvas>
			</span>
		</view>

	</view>

</template>

<script>
	export default {
		data() {
			return {
				startX: 0,
				startY: 0,
				deltaX: 0,
				deltaY: 230,
				maxX: 0, // 可视窗口的最大X值
				maxY: 0, // 可视窗口的最大Y值
				width: "150px",
				height: "200px",
			};
		},
		computed: {
			translateX() {
				return this.deltaX + 'px'
			},
			translateY() {
				return this.deltaY + 'px'
			},

		},
		watch: {
			boxHidenAndShow(newValue, oldValue) {
				console.log(newValue, "这个是监听的值")
				if (!newValue) {
					this.deltaX = 0
					this.deltaY = 230
				}
			}
		},
		mounted() {
			const {
				windowWidth,
				windowHeight
			} = uni.getSystemInfoSync()
			this.maxX = windowWidth - 150; // 200是元素的宽度
			this.maxY = windowHeight - 200; // 200是元素的高度
			console.log(this.maxX, this.maxY, "初始化获取设备视窗信息")
		},
		methods: {
			handleTouchStart(event) {
				// console.log(event, "这个是刚开始触发的")
				const {
					clientX,
					clientY
				} = event.touches[0];
				this.startX = clientX;
				this.startY = clientY;
			},
			handleTouchMove(event) {
				if (this.boxHidenAndShow) {
					const {
						clientX,
						clientY
					} = event.touches[0];
					if (this.translateX.slice(0, -2) < 0) {
						return
					}
					let newDeltaX = this.deltaX + clientX - this.startX;
					let newDeltaY = this.deltaY + clientY - this.startY;
					if (newDeltaX < 0) {
						newDeltaX = 0;
					} else if (newDeltaX > this.maxX) {
						newDeltaX = this.maxX;
					}
					if (newDeltaY < 0) {
						newDeltaY = 0;
					} else if (newDeltaY > this.maxY) {
						newDeltaY = this.maxY;
					}
					this.deltaX = newDeltaX;
					this.deltaY = newDeltaY;
					this.startX = clientX;
					this.startY = clientY;
				}

			},
			show() {
				this.initCanvas()				
			},
		
			initCanvas() {
				console.log("实现canvas")
				const context = uni.createCanvasContext('myCanvas',this);//子组件创建实例时候记得在这里加上this哦
				console.log(context, "这个是创建的")
				context.setStrokeStyle('#000000'); // 设置线条颜色
				context.setLineWidth(2); // 设置线条宽度
				context.beginPath(); // 开始绘制路径
				context.moveTo(10, 0); // 起点坐标
				context.lineTo(10, 115); // 终点坐标
				context.stroke(); // 绘制线条
				context.draw()
			}

		},

	}
</script>

<style lang="scss">
	.box {
		width: 20px;
		height: 100px;
		// width:150px;
		// height: 200px;
		background-color: white;
		border-radius: 18rpx;
		// position: absolute;
		word-wrap: break-word;
		transition: width 1s linear 0s;
		transition: height 1s linear 0s;
	}

	// .boxHiden{
	// 	width:20px;
	// 	height: 200px;
	// }

	.sky {
		// width: 150px;
		height: 50%;
		overflow: hidden;
	}

	.water {
		width: 100%;
		height: 30%;
		margin-top: 26%;
		border-radius: 0 0 18rpx 18rpx;
		background-color: rgb(159, 206, 255);
	}

	.fold {
		// display: block;
		position: fixed;
		z-index: 999;
		top: 0px;
		height: 100px;
		width: 20px;
		border-radius: 0 18rpx 18rpx 0;
		background-color: rgb(153, 154, 154);
	}

	.hidenWidth {
		width: 20px;
	}

	.hidenHeight {
		height: 100px;
	}

	.showWidth {
		width: 150px;
	}

	.showHeight {
		height: 200px;
	}

	.close {
		position: fixed;
		top: 50px;
		left: 130px;
		width: 20px;
		height: 100px;
		background-color: black;
		// text-align: center;
		// line-height: 30px;
		width: 20;
		border-radius: 18rpx 0 0 18rpx;
		// overflow: hidden;
	}

	.rope {
		position: fixed;
		top: 50px;
		width: 20px;
		height: 120px;
		left: 66px;
		overflow: hidden;
		background-color: hotpink;
		text-align: center;
	}
</style>

如有疑问请私信以及评论区联系

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值