<template>
	<view v-show="properties.content" class="ksp-image-cutter" @tap="onok"
		style="position: relative; width: 100%; height: 100%; overflow: hidden;">
		<view class="body">
			<!-- 背景图 -->
			<view v-if="mask.show" class="mask"></view>
			<!-- 窗口 -->
			<view @touchstart="touchStart($event, 'plank')" :data-time="lastTapTime" @touchmove="touchMove"
				@touchend="touchEnd" @touchcancel="touchCancel" class="plank"
				:style="{transform: 'rotate(' + properties.angle + 'deg)'}">
				<view class="frame" @touchstart="touchStart($event, 'frame')" @touchstart.stop.prevent="touchHandle"
					:data-time="lastTapTime" :style="{left: frame.left + 'px', top: frame.top + 'px', 
				     width: frame.width + 'px', height: frame.height + 'px'}">
					<!-- 图片 -->
					<image v-if="properties.content" class="image" :data-time="lastTapTime" @load="imageLoad" :style="{'margin-left': -(frame.left - image.left) + 'px', 'margin-top': -(frame.top - image.top) + 'px',
					width: image.width + 'px', height: image.height + 'px'}" :src="properties.content"></image>
					<view class="rect"></view>
					<view class="line-one"></view>
					<view class="line-two"></view>
					<view class="line-three"></view>
					<view class="line-four"></view>
					<view @touchstart="touchStart($event, 'left')" @touchstart.stop.prevent="touchHandle"
						class="frame-left">
						<view class='left_edge'></view>
					</view>
					<view @touchstart="touchStart($event, 'right')" @touchstart.stop.prevent="touchHandle"
						class="frame-right">
						<view class='rightedge'> </view>
					</view>
					<view @touchstart="touchStart($event, 'top')" @touchstart.stop.prevent="touchHandle"
						class="frame-top">
						<view class='topedge'> </view>
					</view>
					<view @touchstart="touchStart($event, 'bottom')" @touchstart.stop.prevent="touchHandle"
						class="frame-bottom">
						<view class='bottomedge'> </view>
					</view>
					<view @touchstart="touchStart($event, 'left-top')" @touchstart.stop.prevent="touchHandle"
						class="frame-left-top-wrap">
						<view class='frame-left-top'> </view>
					</view>
					<view @touchstart="touchStart($event, 'left-bottom')" @touchstart.stop.prevent="touchHandle"
						class="frame-left-bottom-wrap">
						<view class='frame-left-bottom'> </view>
					</view>
					<view @touchstart="touchStart($event, 'right-top')" @touchstart.stop.prevent="touchHandle"
						class="frame-right-top-wrap">
						<view class='frame-right-top'> </view>
					</view>
					<view @touchstart="touchStart($event, 'right-bottom')" @touchstart.stop.prevent="touchHandle"
						class="frame-right-bottom-wrap">
						<view class='frame-right-bottom'> </view>
					</view>
				</view>
			</view>
		</view>

	</view>
</template>

<script>
	// 封装
	import drag from '../../pages/index/js/drag.js'
	export default {
		props: {
			properties: {
				type: Object,
				default () {
					return {}
				}
			},
			url: {
				type: String,
				default: ""
			},
			fixed: {
				type: Boolean,
				default: false
			},
			width: {
				type: Number,
				default: 200
			},
			height: {
				type: Number,
				default: 200
			},
			maxWidth: {
				type: Number,
				default: 1024
			},
			maxHeight: {
				type: Number,
				default: 1024
			},
			blob: {
				type: Boolean,
				default: true
			}
		},
		data() {
			return {
				mask: {
					show: false
				},
				// 裁剪的窗口
				frame: {
					left: 100,
					top: 100,
					width: this.properties.width,
					height: this.properties.height
				},
				// 背景图
				image: {
					left: 100,
					top: 100,
					width: this.properties.initialWidth,
					height: this.properties.initialHeight
				},
				// 背景图初始
				real: {
					width: this.properties.initialWidth,
					height: this.properties.initialHeight
				},
				// 裁剪的窗口初始
				target: {
					width: this.properties.width,
					height: this.properties.height
				},
				touches: [],
				type: "",
				start: {
					frame: {
						left: 0,
						top: 0,
						width: 0,
						height: 0
					},
					image: {
						left: 0,
						top: 0,
						width: 0,
						height: 0
					},
				},
				timeoutId: -1,
				context: Object,
				targetContext: Object,
				//后添加属性值
				Centerleft: null,
				Centertop: null,
				lastTapTime: 0, //判断点击时间间隔
			};
		},
		mounted() {
			//#ifdef H5
			this.$el.addEventListener("touchmove", (ev) => {
				ev.preventDefault();
			});
			// #endif
			// this.context = uni.createCanvasContext("canvas", this);
			// this.targetContext = uni.createCanvasContext("target", this);
		},
		methods: {
			doubleTap(e) {
				console.log(e)
				var curTime = e.timeStamp
				var lastTime = e.currentTarget.dataset.time // 通过e.currentTarget.dataset.time 访问到绑定到该组件的自定义数据
				if (curTime - lastTime > 0) {
					if (curTime - lastTime < 300) { //是双击事件

					}
				}
				this.lastTapTime = curTime
			},
			/**
			 * 初始化方法
			 * 获取图片宽高后，把图片缩放至剪切框大小，
			 * 并使剪切框位于图片中央
			 **/
			init() {
				if (!this.properties.content) return
				let {
					windowWidth,
					windowHeight,
					pixelRatio
				} = wx.getSystemInfoSync()
				let clipSize = windowWidth / 750
				let clipHeight = windowHeight / 1206
				// 计算宽度高度
				this.real.width = this.properties.initialWidth * this.properties.initialScale
				this.real.height = this.properties.initialHeight * this.properties.initialScale
				this.image.width = this.properties.initialWidth * this.properties.initialScale
				this.image.height = this.properties.initialHeight * this.properties.initialScale
				this.image.angle = this.properties.angle
				this.frame.width = this.properties.width;
				this.frame.height = this.properties.height;
				this.frame.angle = this.properties.angle;

				let rotate = Math.abs(this.frame.angle) % 360 //计算角度
				if (this.frame.angle < 0) {
					let multiple = Math.ceil(Math.abs(this.frame.angle) / 360) //Math.ceil
					rotate = this.frame.angle + multiple * 360
				}
				if (rotate == 360) {
					rotate = 0;
				}
				this.frame.rotate = rotate; //设置新旋转角度

				// 默认居中
				this.Centerleft = (windowWidth - this.properties.width) / 2 - this.properties.frame_left
				this.Centertop = (windowHeight - this.properties.height) / 2 - this.properties.frame_top
				this.image.left = this.Centerleft
				this.image.top = this.Centertop
				this.frame.left = this.Centerleft
				this.frame.top = this.Centertop
				// 有值替换
				if (this.properties.frame_left) {
					this.frame.left = this.properties.frame_left + this.Centerleft
				}
				if (this.properties.frame_top) {
					this.frame.top = this.properties.frame_top + this.Centertop
				}
				if (this.properties.image_left) {
					this.image.left = this.properties.image_left + this.Centerleft
				}
				if (this.properties.image_top) {
					this.image.top = this.properties.image_top + this.Centertop
				}
				// 初始化的位置
				drag.initPos(this.frame)
				drag.initPos(this.image)
			},
			imageLoad(ev) {
				this.mask.show = true;
			},
			touchHandle(ev) {
				//console.log(ev)
				var curTime = ev.timeStamp
				var lastTime = ev.currentTarget.dataset.time // 通过e.currentTarget.dataset.time 访问到绑定到该组件的自定义数据
				if (curTime - lastTime > 0) {
					if (curTime - lastTime < 300) { //是双击事件
						this.onok()
					}
				}
				this.lastTapTime = curTime
			},
			touchStart(ev, type) {
				this.mask.show = false;
				if (this.touches.length == 0) {
					this.type = type;
					this.start.frame.left = this.frame.left;
					this.start.frame.top = this.frame.top;
					this.start.frame.width = this.frame.width;
					this.start.frame.height = this.frame.height;
					this.start.image.left = this.image.left;
					this.start.image.top = this.image.top;
					this.start.image.width = this.image.width;
					this.start.image.height = this.image.height;
				}
				var touches = ev.changedTouches;
				for (var i = 0; i < touches.length; i++) {
					var touch = touches[i];
					this.touches.push(touch);
				}
			},
			touchMove(ev) {
				ev.preventDefault();
				var touches = ev.touches;
				// 点击
				if (this.touches.length == 1) {
					if (this.type == "plank" || this.type == "frame" || this.fixed) {
						this.moveImage(this.touches[0], touches[0]);
					} else {
						this.scaleFrame(this.touches[0], touches[0], this.type);
					}

				} else if (this.touches.length == 2 && touches.length == 2) {
					// 双指头操作
					var ta = this.touches[0];
					var tb = this.touches[1];
					var tc = touches[0];
					var td = touches[1];
					if (ta.identifier != tc.identifier) {
						var temp = tc;
						tc = td;
						td = temp;
					}
					this.scaleImage(ta, tb, tc, td);
				}
			},
			touchEnd(ev) {
				this.type = "";
				this.touches = [];
				drag.getTransferPosition(this.frame.left, this.frame.top, this.frame.width, this.frame.height, this.frame
					.angle, this.frame.centerPos, this.frame)
				drag.getTransferPosition(this.image.left, this.image.top, this.image.width, this.image.height, this.image
					.angle, this.image.centerPos, this.image)
			},
			touchCancel(ev) {
				this.type = "";
				this.touches = [];
			},

			//计算距离
			calculateDistance(dx, dy) {
				let c = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)) //使用三角公式计算边c长度
				let angle = this.getAngle(dx, dy) //计算移动位置角度差
				let rad = (Math.PI / 180) * (angle - this.frame.rotate) //旋转角度转换公式
				let diffY = (Math.sin(rad) * c) //计算角度差x轴
				let diffX = (Math.cos(rad) * c) //计算角度差y轴
				return {
					x: diffX,
					y: diffY
				};
			},

			//计算相差角度
			getAngle(x, y) {
				let theta = Math.atan2(y, x) // range (-PI, PI]
				theta = Math.round((180 / Math.PI) * theta) // rads to degs, range (-180, 180]
				if (theta < 0) theta = 360 + theta // range [0, 360)
				return theta
			},


			moveImage(ta, tb) {
				// 计算角度
				// let roat = Math.abs(this.properties.angle) % 360
				// if (this.properties.angle < 0) {
				// 	let multiple = Math.ceil(Math.abs(this.properties.angle) / 360)
				// 	roat = this.properties.angle + multiple * 360
				// }
				var ax = tb.clientX - ta.clientX;
				var ay = tb.clientY - ta.clientY;


				let distance = this.calculateDistance(ax, ay);

				ax = distance.x;
				ay = distance.y;


				this.image.left = this.start.image.left + ax;
				this.image.top = this.start.image.top + ay;
				if (this.image.left > this.frame.left) {
					this.image.left = this.frame.left;
				}
				if (this.image.top > this.frame.top) {
					this.image.top = this.frame.top;
				}
				if (this.image.left + this.image.width < this.frame.left + this.frame.width) {
					this.image.left = this.frame.left + this.frame.width - this.image.width;
				}
				if (this.image.top + this.image.height < this.frame.top + this.frame.height) {
					this.image.top = this.frame.top + this.frame.height - this.image.height;
				}
			},
			scaleImage(ta, tb, tc, td) {
				var x1 = ta.clientX;
				var y1 = ta.clientY;
				var x2 = tb.clientX;
				var y2 = tb.clientY;
				var x3 = tc.clientX;
				var y3 = tc.clientY;
				var x4 = td.clientX;
				var y4 = td.clientY;
				var ol = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
				var el = Math.sqrt((x3 - x4) * (x3 - x4) + (y3 - y4) * (y3 - y4));
				var ocx = (x1 + x2) / 2;
				var ocy = (y1 + y2) / 2;
				var ecx = (x3 + x4) / 2;
				var ecy = (y3 + y4) / 2;
				var ax = ecx - ocx;
				var ay = ecy - ocy;
				var scale = el / ol;
				if (this.start.image.width * scale < this.frame.width) {
					scale = this.frame.width / this.start.image.width;
				}
				if (this.start.image.height * scale < this.frame.height) {
					scale = this.frame.height / this.start.image.height;
				}
				if (this.start.image.width * scale < this.frame.width) {
					scale = this.frame.width / this.start.image.width;
				}
				this.image.left = this.start.image.left + ax - (ocx - this.start.image.left) * (scale - 1);
				this.image.top = this.start.image.top + ay - (ocy - this.start.image.top) * (scale - 1);
				this.image.width = this.start.image.width * scale;
				this.image.height = this.start.image.height * scale;
				if (this.image.left > this.frame.left) {
					this.image.left = this.frame.left;
				}
				if (this.image.top > this.frame.top) {
					this.image.top = this.frame.top;
				}
				if (this.image.left + this.image.width < this.frame.left + this.frame.width) {
					this.image.left = this.frame.left + this.frame.width - this.image.width;
				}
				if (this.image.top + this.image.height < this.frame.top + this.frame.height) {
					this.image.top = this.frame.top + this.frame.height - this.image.height;
				}
			},
			scaleFrame(ta, tb, type) {
				// 计算角度
				var ax = tb.clientX - ta.clientX;
				var ay = tb.clientY - ta.clientY;


				let distance = this.calculateDistance(ax, ay);
				ax = distance.x;
				ay = distance.y;


				var x1 = this.start.frame.left;
				var y1 = this.start.frame.top;
				var x2 = this.start.frame.left + this.start.frame.width;
				var y2 = this.start.frame.top + this.start.frame.height;
				if (type == "left") {
					x1 += ax;
					this.frame.width = x2 - x1;
					if (this.frame.width <= 50) {
						x1 = x2 - 50
					}
				} else if (type == "right") {
					x2 += ax;
					this.frame.width = x2 - x1;
					if (this.frame.width <= 50) {
						x2 = x1 + 50
					}
				} else if (type == "top") {
					y1 += ay;
					this.frame.height = y2 - y1;
					if (this.frame.height <= 50) {
						y1 = y2 - 50
					}
				} else if (type == "bottom") {
					y2 += ay;
					this.frame.height = y2 - y1;
					if (this.frame.height <= 50) {
						y2 = y1 + 50
					}
				} else if (type == "left-top") {
					x1 += ax;
					y1 += ay;
					this.frame.width = x2 - x1;
					if (this.frame.width <= 50) {
						x1 = x2 - 50
					}
					this.frame.height = y2 - y1;
					if (this.frame.height <= 50) {
						y1 = y2 - 50
					}
				} else if (type == "left-bottom") {
					x1 += ax;
					y2 += ay;
					this.frame.width = x2 - x1;
					if (this.frame.width <= 50) {
						x1 = x2 - 50
					}
					this.frame.height = y2 - y1;
					if (this.frame.height <= 50) {
						y2 = y1 + 50
					}
				} else if (type == "right-top") {
					x2 += ax;
					y1 += ay;
					this.frame.width = x2 - x1;
					if (this.frame.width <= 50) {
						x2 = x1 + 50
					}
					this.frame.height = y2 - y1;
					if (this.frame.height <= 50) {
						y1 = y2 - 50
					}
				} else if (type == "right-bottom") {
					x2 += ax;
					y2 += ay;
					this.frame.width = x2 - x1;
					if (this.frame.width <= 50) {
						x2 = x1 + 50
					}
					this.frame.height = y2 - y1;
					if (this.frame.height <= 50) {
						y2 = y1 + 50
					}
				}
				if (x1 < this.image.left) {
					x1 = this.image.left;
				}
				if (y1 < this.image.top) {
					y1 = this.image.top;
				}
				if (x2 > this.image.left + this.image.width) {
					x2 = this.image.left + this.image.width;
				}
				if (y2 > this.image.top + this.image.height) {
					y2 = this.image.top + this.image.height;
				}
				this.frame.left = x1;
				this.frame.top = y1;
				this.frame.width = x2 - x1;
				this.frame.height = y2 - y1;
			},
			onok() {

				var scale = this.image.width / this.real.width;
				var x = (this.frame.left - this.image.left) / scale;
				var y = (this.frame.top - this.image.top) / scale;
				var width = this.frame.width / scale;
				var height = this.frame.height / scale;
				var tw = width;
				var th = height;

				this.target.width = tw;
				this.target.height = th;

				// 复制数据
				// 裁剪的宽和高
				this.properties.width = this.frame.width
				this.properties.height = this.frame.height
				// 图片放大比率
				this.properties.initialScale = this.properties.initialScale * scale
				this.properties.initialscaling = this.properties.initialScale
				// 裁剪区和原图顶点
				this.properties.frame_left = 0
				this.properties.frame_top = 0
				this.properties.image_left = -(this.frame.left - this.image.left)
				this.properties.image_top = -(this.frame.top - this.image.top)
				// 初始x,y放大比率
				this.properties.initialScalex = 1
				this.properties.initialScaley = 1
				this.$emit('ok', this.properties);


			},
			// 返回
			oncancle() {
				this.$emit("cancel");
			}
		}
	}
</script>

<style lang="scss" scoped>
	.ksp-image-cutter {
		position: absolute;
		width: 100%;
		height: 100%;
		top: 0;
		bottom: 0;
		z-index: 1000;
	}

	.body {
		position: absolute;
		left: 0upx;
		right: 0upx;
		top: 0upx;
		bottom: 0upx;
	}

	.mask {
		position: absolute;
		left: 0upx;
		right: 0upx;
		top: 0upx;
		bottom: 0upx;
		background: black;
		opacity: 0.4;
	}

	.plank {
		position: absolute;
		left: 0upx;
		right: 0upx;
		top: 0upx;
		bottom: 0upx;
	}

	.image {
		position: absolute;
	}

	.frame {
		position: absolute;
	}

	.canvas {
		position: absolute;
		display: block;
		left: 0px;
		top: 0px;
	}

	.rect {
		position: absolute;
		left: -2px;
		top: -2px;
		width: 100%;
		height: 100%;
		border: 2px solid white;
	}

	.line-one {
		position: absolute;
		width: 100%;
		height: 1px;
		background: white;
		left: 0;
		top: 33.3%;
	}

	.line-two {
		position: absolute;
		width: 100%;
		height: 1px;
		background: white;
		left: 0;
		top: 66.7%;
	}

	.line-three {
		position: absolute;
		width: 1px;
		height: 100%;
		background: white;
		top: 0;
		left: 33.3%;
	}

	.line-four {
		position: absolute;
		width: 1px;
		height: 100%;
		background: white;
		top: 0;
		left: 66.7%;
	}

	.frame-left {
		position: absolute;
		left: -30upx;
		width: 40upx;
		height: 100%;
		top: 0;
		background: transparent;

		.left_edge {
			position: absolute;
			z-index: 99;
			left: 24upx;
			width: 6upx;
			height: 40upx;
			background: #5CE6B5;
			top: calc(50% - 20upx);
		}
	}

	.frame-right {
		position: absolute;
		z-index: 99;
		right: -30upx;
		width: 40upx;
		height: 100%;
		background: transparent;
		top: 0;

		.rightedge {
			position: absolute;
			z-index: 99;
			right: 24upx;
			width: 6upx;
			height: 40upx;
			background: #5CE6B5;
			top: calc(50% - 20upx);
		}
	}

	.frame-top {
		position: absolute;
		z-index: 99;
		top: -30upx;
		width: 100%;
		height: 40upx;
		background: transparent;
		left: 0;
		right: 0;
		margin: auto;

		.topedge {
			position: absolute;
			z-index: 99;
			top: 24upx;
			width: 40upx;
			height: 6upx;
			background: #5CE6B5;
			left: 0;
			right: 0;
			margin: auto;
		}
	}

	.frame-bottom {
		position: absolute;
		z-index: 99;
		bottom: -30upx;
		width: 100%;
		height: 40upx;
		background: transparent;
		left: 0;
		right: 0;
		margin: auto;

		.bottomedge {
			position: absolute;
			z-index: 99;
			bottom: 24upx;
			width: 40upx;
			height: 6upx;
			background: #5CE6B5;
			left: 0;
			right: 0;
			margin: auto;
		}
	}

	.left_edge::after,
	.rightedge::after,
	.topedge::after,
	.bottomedge::after {
		content: '';
		position: absolute;
		left: 0;
		right: 0;
		top: 0;
		bottom: 0;
		transform: scale(2);
	}

	.frame-left-top-wrap {
		position: absolute;
		z-index: 100;
		width: 60upx;
		height: 60upx;
		left: -30upx;
		top: -30upx;

		.frame-left-top {
			position: absolute;
			z-index: 100;
			width: 30upx;
			height: 30upx;
			left: 24upx;
			top: 24upx;
			border-left: 6upx solid #5CE6B5;
			border-top: 6upx solid #5CE6B5;
		}
	}

	.frame-left-bottom-wrap {
		position: absolute;
		z-index: 100;
		width: 60upx;
		height: 60upx;
		left: -30upx;
		bottom: -30upx;

		.frame-left-bottom {
			position: absolute;
			z-index: 100;
			width: 30upx;
			height: 30upx;
			left: 24upx;
			bottom: 24upx;
			border-left: 6upx solid #5CE6B5;
			border-bottom: 6upx solid #5CE6B5;
		}
	}

	.frame-right-top-wrap {
		position: absolute;
		z-index: 100;
		width: 60upx;
		height: 60upx;
		right: -30upx;
		top: -30upx;

		.frame-right-top {
			position: absolute;
			z-index: 100;
			width: 30upx;
			height: 30upx;
			right: 24upx;
			top: 24upx;
			border-right: 6upx solid #5CE6B5;
			border-top: 6upx solid #5CE6B5;
		}
	}

	.frame-right-bottom-wrap {
		position: absolute;
		z-index: 100;
		width: 60upx;
		height: 60upx;
		right: -30upx;
		bottom: -30upx;

		.frame-right-bottom {
			position: absolute;
			z-index: 100;
			width: 30upx;
			height: 30upx;
			right: 24upx;
			bottom: 24upx;
			border-right: 6upx solid #5CE6B5;
			border-bottom: 6upx solid #5CE6B5;
		}
	}

	.frame-left-top::after,
	.frame-right-top::after,
	.frame-left-bottom::after,
	.frame-right-bottom::after {
		content: '';
		position: absolute;
		left: 0;
		right: 0;
		top: 0;
		bottom: 0;
		transform: scale(1.5);
	}
</style>
