拆分图片
# 一、使用background-position模拟图片拆分
使用background的background-position计算不同位置图片显示的位置。也就是说每个div都是一个完整的图片,通过计算来让图片进行位移同时搭配overflow: hidden就可以显示不同部位的图片,模拟切图。
代码如下:
<template>
<div class="wrap">
<img :src="imgPath" style="width: 300px; height: 300px; margin: 0 20px;">
<div class="grid-base" :style="[girdStyle]">
<div class="puzzle-base" :style="[puzzleStyle]" v-for="(item, index) in size * size" :key="index">
<div class="puzzle-img" :style="[imgStyle(index)]"></div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
imgPath: {
type: String,
default: require('../assets/head.jpg')
},
size: {
type: Number,
default: 3
}
},
data(){
return {
width: 300, //拼图图片的总宽,宽高一直
gap: 2,
tWidth: 300, // gird的总宽度
}
},
computed: {
girdStyle () {
return {
width: this.tWidth + 'px',
height: this.tWidth + 'px',
'grid-row-gap': this.gap + 'px',
'grid-column-gap': this.gap + 'px',
'grid-template-columns': `repeat(${this.size}, ${this.pWidth}px)`,
'grid-template-rows': `repeat(${this.size}, ${this.pWidth}px)`
}
},
puzzleStyle () {
return {
width: this.pWidth + 'px',
height: this.pWidth + 'px',
}
},
imgStyle () {
return (index) => {
let x = -(index % 3) * this.width / this.size;
let y = -Math.floor(index / 3) * this.width / this.size;
return {
background: `url(${this.imgPath}) no-repeat ${x}px ${y}px/${this.width}px ${this.width}px`,
width: this.width + 'px',
height: this.width + 'px'
}
}
}
},
created() {
// 总宽 = (拼图一行个数 - 1) * 间隔 + 固定图片宽
this.tWidth = this.width + (this.size - 1) * this.gap;
this.pWidth = this.width / this.size;
}
}
</script>
<style lang="scss" scoped>
.wrap {
display: flex;
flex-direction: row;
align-items: center;
.grid {
display: grid;
.puzzle {
background-color: red;
}
}
.grid-base {
display: grid;
opacity: .5;
.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
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
# 二、使用canvas真实拆分图片
- 首先把要切的图绘制到canvas上
- 每个切片图的x、y、width、height
- 使用
getImageData获取截取该位置的imageData - 使用
putImageData把imageData再绘制到另一个canvas上 - 最后把该canvas的图像数据传递到img标签上即可
- 重复2~5步骤即可 代码如下:
<template>
<div class="wrap">
<img :src="imgPath" id="img-base" style="width: 300px; height: 300px; margin: 0 20px;">
<div class="grid-base" :style="[girdStyle]">
<div class="puzzle-base" :style="[puzzleStyle]" v-for="(item, index) in size * size" :key="index">
<img class="puzzle-img" src="" alt="" :style="imgStyle">
</div>
</div>
<canvas id="imageFac" width="300" height="300" style="display: none;"></canvas>
</div>
</template>
<script>
export default {
props: {
imgPath: {
type: String,
default: require('../assets/head.jpg')
},
size: {
type: Number,
default: 3
}
},
data(){
return {
width: 300, //拼图图片的总宽,宽高一直
gap: 2,
tWidth: 300, // gird的总宽度
}
},
computed: {
girdStyle () {
return {
width: this.tWidth + 'px',
height: this.tWidth + 'px',
'grid-row-gap': this.gap + 'px',
'grid-column-gap': this.gap + 'px',
'grid-template-columns': `repeat(${this.size}, ${this.pWidth}px)`,
'grid-template-rows': `repeat(${this.size}, ${this.pWidth}px)`
}
},
puzzleStyle () {
return {
width: this.pWidth + 'px',
height: this.pWidth + 'px',
}
},
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() {
var canvas = document.getElementById('imageFac').getContext('2d');
var imgBase = document.getElementById('img-base');
// 获取图片的真实高度
var width = this.getImgWidth(imgBase.src);
canvas.drawImage(imgBase, 0, 0, width, width, 0, 0, 300, 300);
const imgs = document.getElementsByClassName('puzzle-img');
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');
}
}
},
methods: {
getImgWidth (imgSrc) {
var image = new Image();
image.src = imgSrc;
var naturalWidth = image.width;
return naturalWidth;
}
}
}
</script>
<style lang="scss" scoped="">
.wrap {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap ;
.grid {
display: grid;
.puzzle {
background-color: red;
}
}
.grid-base {
display: grid;
.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
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
如下所示,两种方法实现的效果是一样的

上次更新: 2025/09/05, 8:09:00