-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathindex.js
More file actions
125 lines (106 loc) · 2.71 KB
/
index.js
File metadata and controls
125 lines (106 loc) · 2.71 KB
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
/* eslint jsx-a11y/mouse-events-have-key-events: 0 */
import React, { Component, createRef } from 'react'
import PropTypes from 'prop-types'
import styles from './style.css'
class Zoom extends Component {
constructor (props) {
super(props)
this.state = {
zoom: false,
mouseX: null,
mouseY: null,
}
this.imageRef = createRef()
this.handleMouseOver = this.handleMouseOver.bind(this)
this.handleMouseOut = this.handleMouseOut.bind(this)
this.handleMouseMovement = this.handleMouseMovement.bind(this)
}
handleMouseOver () {
this.setState({
zoom: true,
})
}
handleMouseOut () {
this.setState({
zoom: false,
})
}
handleMouseMovement (e) {
const {
left: offsetLeft,
top: offsetTop,
} = this.imageRef.current.getBoundingClientRect()
const {
current: {
style: {
height,
width,
},
},
} = this.imageRef
const x = ((e.pageX - offsetLeft) / parseInt(width, 10)) * 100
const y = ((e.pageY - offsetTop) / parseInt(height, 10)) * 100
this.setState({
mouseX: x,
mouseY: y,
})
}
render () {
const {
mouseX,
mouseY,
zoom,
} = this.state
const { zoomScale, height, width, img, transitionTime } = this.props
const transform = {
transformOrigin: `${mouseX}% ${mouseY}%`,
}
const outerDivStyle = {
height: `${height}px`,
width: `${width}px`,
overflow: "hidden",
};
const innerDivStyle = {
height: `${height}px`,
backgroundRepeat: "no-repeat",
backgroundPosition: "center",
backgroundSize: "auto 100%",
transition: `transform ${transitionTime}s ease-out`,
backgroundImage: `url('${img}')`,
};
return (
<div
style={outerDivStyle}
onMouseOver={this.handleMouseOver}
onMouseOut={this.handleMouseOut}
onMouseMove={this.handleMouseMovement}
ref={this.imageRef}
>
<div
style={{
...transform,
...this.innerDivStyle,
transform: zoom ? `scale(${zoomScale})` : 'scale(1.0)',
}}
className={styles.zoomImg}
/>
</div>
)
}
}
Zoom.propTypes = {
/** The path to the image. It can be a url. */
img: PropTypes.string.isRequired,
/** The zoom scale. */
zoomScale: PropTypes.number.isRequired,
/** The height of the image in pixels */
height: PropTypes.number.isRequired,
/** The width of the image in pixels */
width: PropTypes.number.isRequired,
/** The time (in seconds) that will take to scale your image. */
transitionTime: PropTypes.number,
}
Zoom.defaultProps = {
transitionTime: 0.1,
}
export default Zoom