9***@qq.com
9***@qq.com
  • 发布:2022-07-12 12:34
  • 更新:2023-04-21 08:22
  • 阅读:447

【报Bug】@touchend 获取坐标点位置后 使用uni.canvasGetImageData 获取坐标点颜色和坐标点颜色不一致

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: Windows 10 21H2

HBuilderX类型: 正式

HBuilderX版本号: 3.4.15

手机系统: Android

手机系统版本号: Android 10

手机厂商: 华为

手机机型: oppo R15

页面类型: vue

vue版本: vue2

打包方式: 离线

项目创建方式: HBuilderX

示例代码:
<template>  
	<view class="body" v-show="isShow">  
		<view class="top-panel">  
			<view class="cancal-btn" @click="close()">cancal</view>  
			<view class="top-title">Color</view>  
			<view class="done-btn" @click="close()">done</view>  
		</view>  
		<view>  
  
			<!-- <image class="colorChange" src="../../../static/colorPicker/1.png" mode="aspectFit"></image>@touchstart="getPointxy" -->  
			<canvas :style="{ width: canvasW + 'px', height: canvasH + 'px'}" @touchstart="getPointxy"  
				@touchmove="pointxyMove" @touchend="getPointxyEnd" id="canvas" canvas-id="canvas"></canvas>  
			<!-- <view class="tt"></view> -->  
		</view>  
	</view>  
</template>  
  
  
<script>  
	export default {  
		name: 'colorModel',  
		data() {  
			return {  
				isShow: true,  
				colorVal: '#fff', //颜色值  
				canvasW: 0, //画布宽  
				canvasH: 0, //画布高  
				canvasLeft: 0,  
				canvasTop: 0,  
				canvasLength: 0, //图片半径  
				colorImg: '/static/colorPicker/color.png', //图片路径  
				imgWidth: 300, //图片宽  
				imgHeight: 300, //图片高  
				imgX: 0,  
				imgY: 0,  
				systemInfo: {}, //系统信息  
				ctx: {} //画布  
			}  
		},  
		onLoad() {  
  
		},  
		mounted() {  
  
		},  
		watch: {  
			show(val) {  
				if (val) {  
					this.showModal()  
				}  
			}  
		},  
		methods: {  
			showModal() {  
				this.getData();  
			},  
			close() {  
				this.isShow = false;  
				this.$emit('receivecolor', this.colorVal)  
			},  
			canvasFunction() { //画图  
				// let colorImg = "/static/colorPicker/color.png"; //要画的图片链接  
  
				// this.canvasW = image.width;;  
				// this.canvasH = image.height;  
  
				this.ctx = uni.createCanvasContext('canvas', this); //创建一个画布  
				// 填充背景色  
				this.ctx.setFillStyle('#fff'); //默认白色  
				this.ctx.fillRect(0, 0, this.canvasW, this.canvasH); //画布尺寸  
				// 商品图  
				this.ctx.drawImage(this.colorImg, this.canvasLeft, this.canvasTop, this.imgWidth, this.imgHeight);  
				this.ctx.fill();  
  
				// this.ctx.setFontSize(20)  
				// this.ctx.fillText('MINA', this.canvasW/2,this.canvasH/2);  
  
				this.ctx.draw();  
			},  
			getPointxyEnd(e) {  
				let {  
					x,  
					y  
				} = e.changedTouches[0];  
				// console.log(e);  
				let isPoint = this.handleDSize(x, y);  
				if (isPoint) {  
					  
					console.log(x+";"+y);  
					uni.canvasGetImageData({  
						canvasId: 'canvas',  
						x: x,  
						y: y,  
						width: this.canvasW,  
						height: this.canvasH,  
						success: (res) => {  
							// req(res)  
							// console.log(res.data);  
							// req(res)  
							let pixel = res.data;  
							let r = pixel[0];  
							let g = pixel[1];  
							let b = pixel[2];  
							let a = pixel[3] / 255;  
							let hex = "#" + ((a << 24) + (r << 16) + (g << 8) + b).toString(16).slice(  
								1);  
							// console.log(hex);  
							this.ctx.setFillStyle('#fff'); //默认白色  
							// console.log( "新的color"+this.colorVal);  
							// let color=this.getImageColorD(x, y);  
							// console.log(pixelColor)  
							this.ctx.fillRect(0, 0, this.canvasW, this.canvasH); //画布尺寸  
							this.ctx.drawImage(this.colorImg, this.canvasLeft, this.canvasTop, this.imgWidth,  
								this.imgHeight);  
							this.ctx.beginPath();  
							this.ctx.arc(x, y, 35, 0, 1.5 * Math.PI)  
							this.ctx.setStrokeStyle('#fff');  
							this.ctx.setShadow(0, 0, 20, 'white');  
							this.ctx.stroke();  
							this.ctx.setFillStyle(hex);  
							// console.log("结束的val" + this.colorVal);  
							this.ctx.fill();  
							this.ctx.draw();  
						}  
					})  
  
				}  
			},  
			pointxyMove(e) {  
				let {  
					x,  
					y  
				} = e.changedTouches[0];  
				// 绘制线条起点  
				let isPoint = this.handleDSize(x, y);  
				if (isPoint) {  
					this.ctx.setFillStyle('#fff'); //默认白色  
					this.ctx.fillRect(0, 0, this.canvasW, this.canvasH); //画布尺寸  
					this.ctx.drawImage(this.colorImg, this.canvasLeft, this.canvasTop, this.imgWidth, this.imgHeight);  
					this.ctx.beginPath();  
					this.ctx.arc(x, y, 35, 0, 2 * Math.PI)  
					this.ctx.setStrokeStyle('#fff');  
					this.ctx.setShadow(0, 0, 20, 'white');  
					this.ctx.stroke();  
					this.ctx.setFillStyle(this.colorVal);  
					this.ctx.fill();  
					this.ctx.draw();  
				}  
			},  
			async getPointxy(e) {  
				// 取出x、y的值  
				let {  
					x,  
					y  
				} = e.changedTouches[0];  
				// 绘制线条起点  
				// console.log(x);  
				// console.log(y);  
				let isPoint = this.handleDSize(x, y);  
				if (isPoint) {  
					this.ctx.setFillStyle('#fff'); //默认白色  
					// console.log( "新的color"+this.colorVal);  
					await this.getImageColor(x, y);  
					// console.log(pixelColor)  
					this.ctx.fillRect(0, 0, this.canvasW, this.canvasH); //画布尺寸  
					this.ctx.drawImage(this.colorImg, this.canvasLeft, this.canvasTop, this.imgWidth, this.imgHeight);  
					this.ctx.beginPath();  
					this.ctx.arc(x, y, 35, 0, 2 * Math.PI)  
					this.ctx.setStrokeStyle('#fff');  
					this.ctx.setShadow(0, 0, 20, 'white');  
					this.ctx.stroke();  
					this.$nextTick(() => {  
						this.colorVal;  
					})  
					this.ctx.setFillStyle(this.colorVal);  
					// this.ctx.setStrokeStyle(this.colorVal);  
					// // console.log( "新的color"+this.colorVal);  
					// this.ctx.strokeRect(10, 10, 150, 75);  
  
  
					// let pixelColor = res.data;  
  
					// let r = pixel[0];  
					// let g = pixel[1];  
					// let b = pixel[2];  
					// let a = pixel[3] / 255;  
					// let hex = "#" + ((a << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);  
					// console.log(hex);  
  
					this.ctx.fill();  
					this.ctx.draw();  
				}  
				// this.ctx.setFillStyle('red')  
				// this.ctx.fillRect(this.canvasW/2,this.canvasH/2 , 150, 100)  
				// this.ctx.draw();  
				// Draw arc  
			},  
			//限制圆形的边长  
			handleDSize(x, y) {  
				// let length = Math.sqrt(Math.pow(this.canvasW/2 -x)+Math.pow(this.canvasTop+300-y));   
				// let lenght= Math.pow(this.canvasW/2 -x);  
  
				// if (length > 300) {  
				// 	return false;  
				// } else {  
				let length = Math.sqrt(Math.pow(this.imgX - x, 2) + Math.pow(this.imgY - y, 2));  
				if (length > 150) {  
					return false  
				} else {  
  
					return true  
				}  
				// }  
			},  
			getData() {  
				// var that=this;  
				uni.getSystemInfo({  
					success: (res) => {  
						// console.log(res.windowHeight); // print 610  
						// result = uni.upx2px(res.windowHeight) + 200 // 这里加200或者加100为了看测试效果  
						// 不加200默认 return 292  
						this.canvasH = res.windowHeight;  
						this.canvasW = res.windowWidth;  
						this.canvasLeft = this.canvasW / 2 - this.imgWidth / 2;  
						this.canvasTop = (this.canvasH / 2 - this.imgHeight / 2) / 2;  
						// console.log("left:" + this.canvasLeft)  
						// console.log("top:" + this.canvasTop)  
						this.imgX = this.canvasLeft + this.imgWidth / 2;  
						this.imgY = this.canvasTop + this.imgHeight / 2;  
						// console.log("间距:"+this.canvasLeft+"宽度:"+this.canvasW / 2)  
						setTimeout(() => {  
							this.canvasFunction();  
						}, 200);  
						this.isShow = true;  
					}  
				});  
			},  
			// 获取图片信息  
			getMyImageInfo() {  
				uni.getImageInfo({  
					src: this.colorImg,  
					success: (res) => {  
						return res;  
					},  
				});  
			},  
			getSystemInfo() {  
				return new Promise((req, rej) => {  
					uni.getSystemInfo({  
						success: function(res) {  
							req(res)  
						}  
					});  
				})  
			},  
			// success: (res) => {  
			// 	let pixel = res.data;  
			// 	let r = pixel[0];  
			// 	let g = pixel[1];  
			// 	let b = pixel[2];  
			// 	let a = pixel[3] / 255;  
			// 	let hex = "#" + ((a << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);  
			// 	this.$nextTick(() => {  
			// 		this.colorVal = hex;  
			// 	}),  
			getImageColor(x, y) {  
				return new Promise((req, rej) => {  
					// console.log(x+","+y)  
					uni.canvasGetImageData({  
						canvasId: 'canvas',  
						x: x,  
						y: y,  
						width: this.canvasW,  
						height: this.canvasH,  
						success: (res) => {  
							// req(res)  
							// console.log(res.data);  
							// req(res)  
							let pixel = res.data;  
							let r = pixel[0];  
							let g = pixel[1];  
							let b = pixel[2];  
							let a = pixel[3] / 255;  
							let hex = "#" + ((a << 24) + (r << 16) + (g << 8) + b).toString(16).slice(  
								1);  
  
							// this.$nextTick(()=>{  
  
							this.colorVal = hex;  
							// console.log(this.colorVal)  
							// })  
						}  
					})  
				});  
			}  
		}  
	}  
</script>  
  
<style lang="scss" scoped>  
	.body {  
		width: 750rpx;  
		height: 100%;  
		top: 30rpx;  
		left: 0rpx;  
		border-radius: 50rpx 50rpx 0 0;  
		z-index: 15;  
		position: fixed;  
		background-color: white;  
	}  
  
	.tt {  
		width: 20rpx;  
		height: 700rpx;  
		margin: 0 auto;  
		background-color: black;  
		z-index: 999;  
	}  
  
	.top-panel {  
		top: 0rpx;  
		width: 750rpx;  
		height: 100rpx;  
		position: relative;  
		border-radius: 20rpx 20rpx 0rpx 0rpx;  
		background-color: lightgray;  
	}  
  
	.top-title {  
		width: 120rpx;  
		height: 50rpx;  
		left: 220rpx;  
		top: 20rpx;  
		position: relative;  
		display: inline-block;  
	}  
  
	.cancal-btn {  
		width: 120rpx;  
		height: 50rpx;  
		position: relative;  
		top: 20rpx;  
		left: 30rpx;  
		float: left;  
		color: orange;  
		display: inline-block;  
	}  
  
	.done-btn {  
		width: 120rpx;  
		height: 50rpx;  
		top: 20rpx;  
		position: relative;  
		float: right;  
		color: orange;  
		display: inline-block;  
	}  
  
	.colorChange {  
		left: 35rpx;  
		top: 60rpx;  
	}  
  
	.signCanvas {  
		width: 750rpx;  
		height: 1980rpx;  
		background-color: antiquewhite;  
		z-index: 17;  
	}  
  
	// .colorCanvas {  
	// 	left: 30px;  
	// 	top: 50px;  
	// 	background: black;  
	// 	z-index: 18;  
	// }  
</style>

操作步骤:

将图片文件放入 static/colorPicker 文件夹中 后运行 点击拖拽@touchend结束后 获取颜色和坐标点获取颜色不一致

预期结果:

描绘坐标点颜色和data 中 colorVal 颜色一致

实际结果:

描绘坐标点颜色和data 中 colorVal 颜色不一致

bug描述:

在canvas 中使用 @touchend 获取点击坐标后,使用uni.canvasGetImageData 获取图片颜色 ,获取颜色与坐标点颜色不一致

2022-07-12 12:34 负责人:无 分享
已邀请:
DCloud_UNI_WZF

DCloud_UNI_WZF

你在 touchstart 的时候把当前颜色的小球画到鼠标位置,touchmove 和 touchend 的时候小球一直在鼠标位置,所以拿到的一直是小球的颜色,表现出来就是颜色一直没变
下次调试可以先拿最简 demo 尝试是否可以复现自己的判断,比如只写一个touchend 查看获取色值是否有误

  • 9***@qq.com (作者)

    谢谢大佬,是我获取的时候没有考虑到这个问题


    2022-07-12 19:09

8***@qq.com

8***@qq.com

是这个问题,然后我把那个小圆球改成了不实心的,就获取正常了。

要回复问题请先登录注册