Skip to content

Commit 1ef13ac

Browse files
feat:finished
1 parent db27c91 commit 1ef13ac

File tree

8 files changed

+307
-1
lines changed

8 files changed

+307
-1
lines changed

.gitignore

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
.DS_Store
2+
node_modules
3+
/dist
4+
5+
# local env files
6+
.env.local
7+
.env.*.local
8+
9+
# Log files
10+
npm-debug.log*
11+
yarn-debug.log*
12+
yarn-error.log*
13+
14+
# Editor directories and files
15+
.idea
16+
.vscode
17+
*.suo
18+
*.ntvs*
19+
*.njsproj
20+
*.sln
21+
*.sw*

README.md

+26-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,26 @@
1-
# vue-image-magnifier
1+
# vue-image-magnifier
2+
3+
## Project setup
4+
```
5+
npm install
6+
```
7+
8+
### Compiles and hot-reloads for development
9+
```
10+
npm run serve
11+
```
12+
13+
### Compiles and minifies for production
14+
```
15+
npm run build
16+
```
17+
18+
### Run your tests
19+
```
20+
npm run test
21+
```
22+
23+
### Lints and fixes files
24+
```
25+
npm run lint
26+
```

babel.config.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
presets: [
3+
'@vue/app'
4+
]
5+
}

package.json

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"name": "vue-image-magnifier",
3+
"version": "0.1.0",
4+
"private": true,
5+
"main": "lib/magnifier.umd.js",
6+
"scripts": {
7+
"serve": "vue-cli-service serve",
8+
"build": "vue-cli-service build --target lib --name magnifier --dest lib src/main.js",
9+
"lint": "vue-cli-service lint"
10+
},
11+
"dependencies": {
12+
"core-js": "^2.6.5",
13+
"vue": "^2.6.6"
14+
},
15+
"devDependencies": {
16+
"@vue/cli-plugin-babel": "^3.0.5",
17+
"@vue/cli-plugin-eslint": "^3.0.5",
18+
"@vue/cli-service": "^3.0.5",
19+
"babel-eslint": "^10.0.1",
20+
"eslint": "^5.8.0",
21+
"eslint-plugin-vue": "^5.0.0",
22+
"vue-template-compiler": "^2.5.21"
23+
},
24+
"eslintConfig": {
25+
"root": true,
26+
"env": {
27+
"node": true
28+
},
29+
"extends": [
30+
"plugin:vue/essential",
31+
"eslint:recommended"
32+
],
33+
"rules": {},
34+
"parserOptions": {
35+
"parser": "babel-eslint"
36+
}
37+
},
38+
"postcss": {
39+
"plugins": {
40+
"autoprefixer": {}
41+
}
42+
},
43+
"browserslist": [
44+
"> 1%",
45+
"last 2 versions",
46+
"not ie <= 8"
47+
]
48+
}

public/index.html

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width,initial-scale=1.0">
7+
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
8+
<title>vue-image-magnifier</title>
9+
</head>
10+
<body>
11+
<noscript>
12+
<strong>We're sorry but vue-image-magnifier doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
13+
</noscript>
14+
<div id="app"></div>
15+
<!-- built files will be auto injected -->
16+
</body>
17+
</html>

src/components/ImageMagnifier.vue

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
<template>
2+
<div class="image-magnifier">
3+
<img :width="width"
4+
:height="height"
5+
:src="src"
6+
class="image-magnifier__img"
7+
@mouseover="handleOver"
8+
@mousemove="handleMove"
9+
@mouseout="handleOut"
10+
ref="img"
11+
/>
12+
<div class="image-magnifier__mask" :style="maskStyle" v-show="zoomShow" ref="mask">
13+
</div>
14+
<div class="image-magnifier__zoom" :style="zoomStyle" v-show="zoomShow">
15+
<img :src="zoomSrc" :style="zoomImgStyle"/>
16+
</div>
17+
</div>
18+
</template>
19+
20+
<script>
21+
export default {
22+
name: "ImageMagnifier",
23+
props: {
24+
width: {
25+
default: 'auto'
26+
},
27+
height: {
28+
default: 'auto'
29+
},
30+
src: {},
31+
zoomSrc: {},
32+
zoomWidth: {
33+
default: 'auto'
34+
},
35+
zoomHeight: {
36+
default: 'auto'
37+
},
38+
zoomClass: {},
39+
maskWidth: {
40+
default: 100
41+
},
42+
maskHeight: {
43+
default: 100
44+
},
45+
maskBgColor: {
46+
default: '#409eff'
47+
},
48+
maskOpacity: {
49+
default: .5
50+
},
51+
maskClass: {}
52+
},
53+
data() {
54+
return {
55+
zoomShow: false,
56+
imgRect: '',
57+
maskRect: '',
58+
maskX: 0,
59+
maskY: 0,
60+
zoomImage: '',
61+
zoomLeft: '',
62+
zoomImgWidth: 0,
63+
zoomImgHeight: 0,
64+
zoomPosition: {
65+
x: 0,
66+
y: 0
67+
}
68+
}
69+
},
70+
computed: {
71+
maskStyle() {
72+
return {
73+
position: 'absolute',
74+
width: `${this.maskWidth}px`,
75+
height: `${this.maskHeight}px`,
76+
opacity: this.maskOpacity,
77+
backgroundColor: this.maskBgColor,
78+
left: 0,
79+
top: 0,
80+
transform: `translate(${this.maskX}px, ${this.maskY}px)`,
81+
pointerEvents: 'none'
82+
}
83+
},
84+
zoomStyle() {
85+
return {
86+
width: `${this.zoomWidth}px`,
87+
height: `${this.zoomHeight}px`,
88+
position: 'absolute',
89+
left: `${this.zoomLeft}px`,
90+
top: 0,
91+
overflow: 'hidden'
92+
}
93+
},
94+
zoomImgStyle() {
95+
return {
96+
width: `${this.zoomImgWidth}px`,
97+
height: `${this.zoomImgHeight}px`,
98+
transform: `translate(-${this.zoomPosition.x}px, -${this.zoomPosition.y}px)`,
99+
}
100+
}
101+
102+
},
103+
created() {
104+
105+
},
106+
methods: {
107+
handleOver() {
108+
this.zoomShow = true;
109+
this.imgRect = this.$refs.img && this.$refs.img.getBoundingClientRect();
110+
this.$nextTick(() => {
111+
this.maskRect = this.$refs.mask && this.$refs.mask.getBoundingClientRect();
112+
this.zoomImgWidth = (this.imgRect.width / this.maskRect.width) * this.zoomWidth;
113+
this.zoomImgHeight = (this.imgRect.height / this.maskRect.height) * this.zoomHeight;
114+
})
115+
116+
117+
},
118+
handleMove(e) {
119+
this.maskX = this.outXCheck(e.pageX - this.imgRect.left);
120+
this.maskY = this.outYCheck(e.pageY - this.imgRect.top);
121+
this.zoomLeft = this.imgRect.width + 10;
122+
this.zoomPosition.x = this.maskX * (this.zoomImgWidth / this.imgRect.width)
123+
this.zoomPosition.y = this.maskY * (this.zoomImgHeight / this.imgRect.height)
124+
},
125+
handleOut() {
126+
this.zoomShow = false;
127+
},
128+
outXCheck(x) {
129+
x = x - this.maskRect.width / 2;
130+
if (x < 0) {
131+
return 0;
132+
}
133+
if (x + this.maskRect.width > this.imgRect.width) {
134+
return this.imgRect.width - this.maskRect.width;
135+
}
136+
return x;
137+
},
138+
outYCheck(y) {
139+
y = y - this.maskRect.height / 2;
140+
if (y < 0) {
141+
return 0;
142+
}
143+
if (y + this.maskRect.height > this.imgRect.height) {
144+
return this.imgRect.height - this.maskRect.height;
145+
}
146+
return y;
147+
}
148+
}
149+
}
150+
</script>
151+
152+
<style scoped>
153+
.image-magnifier {
154+
position: relative;
155+
cursor: move;
156+
}
157+
158+
.image-magnifier__img {
159+
160+
}
161+
162+
.image-magnifier__mask {
163+
}
164+
165+
.image-magnifier__zoom {
166+
}
167+
</style>

src/main.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import ImageMagnifier from './components/ImageMagnifier.vue';
2+
const install = function (Vue) {
3+
Vue.component('image-magnifier', ImageMagnifier);
4+
}
5+
6+
export default {
7+
install,
8+
ImageMagnifier
9+
}
10+
11+
export {
12+
ImageMagnifier
13+
}
14+

vue.config.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module.exports = {
2+
pages: {
3+
demo: {
4+
entry: 'example/main.js',
5+
template: 'public/index.html',
6+
filename: 'index.html'
7+
}
8+
}
9+
}

0 commit comments

Comments
 (0)