Kros的博客 Kros的博客
首页
  • CSS
  • 工具
  • Vue
  • js
  • Vue3
  • 算法
  • 折腾笔记
一言
  • 分类
  • 标签
  • 归档
码云

Kros

凡心所向,素履以往,生如逆旅,一苇以航
首页
  • CSS
  • 工具
  • Vue
  • js
  • Vue3
  • 算法
  • 折腾笔记
一言
  • 分类
  • 标签
  • 归档
码云
  • 拼图小游戏

    • 拼图思路总览
    • 拆分图片
    • 拆分图片打乱顺序
    • 拖动拆分的图片
    • 拖动图片到原图上
    • 优化重构项目
    • 问题与总结
  • 井字棋

  • 贪吃蛇

  • 扫雷

  • 项目
  • 拼图小游戏
kros
2021-02-24

拖动拆分的图片

拖动借助于组件vue-drag-resize ,引入该组件将代码重构如下:

<template>
	<div class="wrap" id="con">
		<div class="puzzle-box" :style="[puzzleBoxStyle]">
			<img :src="imgPath" id="img-base" style="width: 300px; height: 300px; opacity: .2;">

				<vue-drag-resize 
					:w="pWidth" 
					:h="pWidth" 
					:isResizable="false" 
					:parentLimitation="true" 
					:x="puzzleStyle().left"
					:y="puzzleStyle().top"
					v-for="(item, index) in size * size" 
					:key="index"
					@dragging="onDragging"
					@dragstop="onDragstop"
				>
					<img class="puzzle-img" src="" :style="imgStyle">
				</vue-drag-resize>
		</div>
		<div @click="calcSplitPuzzle"><button >生成拼图</button></div>
		<canvas id="imageFac" width="300" height="300" style="display: none;"></canvas>
	</div>
	
</template>

<script>
	import VueDragResize from 'vue-drag-resize'
	export default {
		components: { VueDragResize },
		props: {
			imgPath: {
				type: String,
				default: require('../assets/head.jpg')
			},
			size: {
				type: Number,
				default: 3
			}
		},
		data(){
			return {
				width: 300,  //拼图图片的总宽,宽高一直
				gap: 2,
				tWidth: 300, // gird的总宽度
				pWidth: 100
			}
		},
		computed: {
			puzzleBoxStyle () {
				return {
					// padding: '12px',
					// width: this.width + 'px',
					height: this.width + 'px',
					border: '1px solid #ccc',
					position: 'relative'
				}
			},
			puzzleStyle () {
				return (index) => {
					let left = Math.random() * (this.width - this.pWidth) + this.width;
					let top = Math.random() * (this.width - this.pWidth);
					return {
						left: left,
						top: top,
					}
				}
			},
			imgStyle () {
				return {
					width: this.pWidth + 'px',
					height: this.pWidth + 'px',
				}
			}
		},
		created() {
			// 总宽 = (拼图一行个数 - 1) * 间隔 + 固定图片宽
			this.tWidth = this.width + (this.size - 1) * this.gap;
			this.pWidth = this.width / this.size;
		},
		mounted() {
			setTimeout(() => {
				this.calcSplitPuzzle()
			}, 500)
		},
		methods: {
			getImgWidth (imgSrc) {
				var image = new Image();
				image.src = imgSrc;
				var naturalWidth = image.width;
				return naturalWidth;
			},
			calcSplitPuzzle() {
				var canvas = document.getElementById('imageFac').getContext('2d');
				var imgBase = document.getElementById('img-base');
				// 获取图片的真实高度
				var width = this.getImgWidth(imgBase.src);
				// imgBase.onload = () => {
					canvas.drawImage(imgBase, 0, 0, width, width, 0, 0, 300, 300);
					const imgs = document.getElementsByClassName('puzzle-img');
					console.log(imgs)
					for(let y = 0; y < this.size; y++) {
						for(let x = 0; x < this.size; x++) {
							let imageData = canvas.getImageData(x * this.pWidth, y * this.pWidth, this.pWidth, this.pWidth);
							var tempCanvas = document.createElement('canvas');
							tempCanvas.width = this.pWidth;
							tempCanvas.height = this.pWidth;
							tempCanvas.fillStyle = 'white';
							var tempCtx = tempCanvas.getContext('2d');
							tempCtx.putImageData(imageData, 0, 0);
							// 绘制图片
							imgs[y * this.size + x].src = tempCanvas.toDataURL('image/jpeg');
						}
					}
				// }	
			},
			onDragging(e) {
				console.log('draging', e)
			},
			onDragstop(e) {
				console.log('dragstop',e)
			}
		}
	}
</script>

<style lang="scss" scoped>
	.wrap {
		width: 100%;
		height: 100%;
		
		.grid {			
			display: grid;
			.puzzle {
				background-color: red;
			}
		}
		
		.puzzle-box {
			user-select: none;
			.puzzle-base {
				overflow: hidden;
				.puzzle-img {
				}
			}
		}
	}
</style>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

代码整体改动不大主要是在vue-drag-resize的使用上,必须要设置推动物体的初始化大小w和h以及将大小变化isResizable设置为false,其它都为可选设置。

最总效果如下:

pluuze

为什么使用vue-drag-resize而不是Vue.Draggable?

  • Vue.Draggable拖动更加适合于列表拖动,使用vue-drag-resize相对于来说更加适合单个图片拖动。我们只需要简单的物体拖动不带其它功能,如果时间允许也可以手撸一个。
上次更新: 2025/09/05, 8:09:00
拆分图片打乱顺序
拖动图片到原图上

← 拆分图片打乱顺序 拖动图片到原图上→

最近更新
01
Find the next perfect square
09-05
02
Regex validate PIN code
09-05
03
Find the odd int
09-05
更多文章>
Theme by Vdoing | Copyright © 2020-2025 kros king
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
icon-heart-o icon-heart icon-infinity icon-pause icon-play link next prev