Skip to content

Commit 3514c46

Browse files
committed
Fix #77 - dragging of profile image should work on mouse/touch move for all devices
1 parent 41aee08 commit 3514c46

File tree

3 files changed

+76
-126
lines changed

3 files changed

+76
-126
lines changed

README.md

-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ The workaround is to instruct users to use HTML tags in their comments.
6969
+ Dragging the profile image is sometimes glitchy, especially on desktop.
7070
I didn't make too much of an effort to correct that,
7171
seeing that even major websites such as YouTube and Twitch.tv exhibit a glitchy volume controller in their player.
72-
+ Dragging the profile image doesn't work on tablets for some reason, only double-clicking does.
7372

7473
### Unicode
7574

src/components/ProfileImg/index.jsx

+76-100
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { StaticQuery, graphql } from "gatsby"
33
import Img from "gatsby-image"
44
import Context from '../Context'
55
import { Author } from '../../consts/author'
6-
import './style.scss'
76

87
export const squareImage = graphql`
98
fragment squareImage on File {
@@ -22,100 +21,38 @@ class ProfileImg extends React.Component {
2221
backWidth: 0,
2322
isMouseUp: true
2423
}
25-
this.toggleMouse = this.toggleMouse.bind(this)
24+
25+
this.moveElementRef = React.createRef()
26+
this.mouseUpElementRef = React.createRef()
27+
28+
this.mouseMove = this.mouseMove.bind(this)
29+
this.touchMove = this.touchMove.bind(this)
2630
this.setMouseUp = this.setMouseUp.bind(this)
2731
this.setMouseDown = this.setMouseDown.bind(this)
2832
}
2933

30-
setBackWidth(newWidth) {
31-
this.setState({
32-
backWidth: newWidth
33-
})
34-
}
35-
36-
setMouseUp(event) {
37-
this.toggleMouse(event, true)
38-
}
39-
40-
setMouseDown(event) {
41-
this.toggleMouse(event, false)
42-
}
43-
44-
toggleMouse(event, isMouseUp) {
45-
const isLeftClick = event.which === 1
46-
if (isLeftClick) {
47-
this.setState({isMouseUp})
48-
}
49-
}
50-
51-
5234
render() {
5335
return (
54-
<StaticQuery
55-
query={graphql`
56-
query ProfileImgQuery {
57-
front: file(relativePath: { eq: "icon2.png" }) {
58-
...squareImage
36+
<StaticQuery
37+
query={graphql`
38+
query ProfileImgQuery {
39+
front: file(relativePath: { eq: "icon2.png" }) {
40+
...squareImage
41+
}
42+
43+
back: file(relativePath: { eq: "icon.png" }) {
44+
...squareImage
45+
}
5946
}
60-
61-
back: file(relativePath: { eq: "icon.png" }) {
62-
...squareImage
63-
}
64-
}
65-
`}
66-
render={data => this.renderWithQueryData(data)}
67-
/>)
47+
`}
48+
render={data => this.renderWithQueryData(data)}
49+
/>
50+
)
6851
}
6952

7053
renderWithQueryData(data) {
7154
const { className } = this.props
7255
const { language } = this.context.page
73-
const _this = this
74-
75-
function setupMove(div, eventType, extractCoordinates, params = {}) {
76-
if (div) {
77-
div.addEventListener(eventType, (event) => {
78-
const container = div.parentElement
79-
const { x } = extractCoordinates(event)
80-
const { left } = container.getBoundingClientRect()
81-
const newWidth = x - left
82-
_this.setBackWidth(Math.max(newWidth, 0))
83-
}, {once: true, ...params})
84-
}
85-
}
86-
87-
function addToggleMouseListener(target, type, listener) {
88-
target.removeEventListener(type, listener)
89-
target.addEventListener(type, listener)
90-
}
91-
92-
function setupMouseUp(div) {
93-
if (div && !_this.state.isMouseUp) {
94-
addToggleMouseListener(div, 'mouseup', _this.setMouseUp)
95-
}
96-
}
97-
98-
function setupMouseMove(div) {
99-
if (div) {
100-
const toggleEvent = (_this.state.isMouseUp) ? 'mousedown' : 'mouseup'
101-
const toggleAction = (_this.state.isMouseUp) ? _this.setMouseDown : _this.setMouseUp
102-
addToggleMouseListener(div, toggleEvent,toggleAction)
103-
}
104-
105-
if (!_this.state.isMouseUp) {
106-
setupMove(div, 'mousemove', (event) => {
107-
const { clientX: x, clientY: y } = event
108-
return {x, y}
109-
})
110-
}
111-
}
112-
113-
function setupTouchMove(div) {
114-
setupMove(div, 'touchmove', (event) => {
115-
const { clientX: x, clientY: y } = event.changedTouches[0]
116-
return {x, y}
117-
}, {passive: true})
118-
}
11956

12057
const authorName = Author.name[language.get().id]
12158
return (
@@ -128,19 +65,19 @@ class ProfileImg extends React.Component {
12865
}}
12966
>
13067
<div
131-
ref={setupMouseMove}
132-
className="profile-img-mousemove"
68+
ref={this.moveElementRef}
69+
className="profile-img-pointermove"
13370
style={{
13471
width: "130%",
13572
height: "100%",
13673
left: "-15%",
13774
position: "absolute",
13875
background: "transparent",
139-
zIndex: 2
76+
zIndex: 1
14077
}}
14178
/>
14279
<div
143-
ref={setupMouseUp}
80+
ref={this.mouseUpElementRef}
14481
className="profile-img-mouseup"
14582
style={{
14683
position: "fixed",
@@ -151,19 +88,7 @@ class ProfileImg extends React.Component {
15188
top: 0,
15289
left: 0,
15390
background: "transparent",
154-
display: (_this.state.isMouseUp) ? "none" : "inherit"
155-
}}
156-
/>
157-
<div
158-
ref={setupTouchMove}
159-
className="profile-img-touchmove"
160-
style={{
161-
width: "130%",
162-
height: "100%",
163-
left: "-15%",
164-
position: "absolute",
165-
background: "transparent",
166-
zIndex: 1
91+
display: (this.state.isMouseUp) ? "none" : "inherit"
16792
}}
16893
/>
16994
<Img
@@ -193,6 +118,57 @@ class ProfileImg extends React.Component {
193118
</div>
194119
)
195120
}
121+
122+
componentDidMount() {
123+
this.moveElementRef.current.addEventListener('mousemove', this.mouseMove)
124+
this.moveElementRef.current.addEventListener('touchmove', this.touchMove, {passive: true})
125+
this.moveElementRef.current.addEventListener('mouseup', this.setMouseUp)
126+
this.moveElementRef.current.addEventListener('mousedown', this.setMouseDown)
127+
this.mouseUpElementRef.current.addEventListener('mouseup', this.setMouseUp)
128+
}
129+
130+
componentWillUnmount() {
131+
this.moveElementRef.current.removeEventListener('mousemove', this.mouseMove)
132+
this.moveElementRef.current.removeEventListener('touchmove', this.touchMove)
133+
this.moveElementRef.current.removeEventListener('mouseup', this.setMouseUp)
134+
this.moveElementRef.current.removeEventListener('mousedown', this.setMouseDown)
135+
this.mouseUpElementRef.current.removeEventListener('mouseup', this.setMouseUp)
136+
}
137+
138+
mouseMove(event) {
139+
if (!this.state.isMouseUp) {
140+
this.setBackWidth(event.clientX)
141+
}
142+
}
143+
144+
touchMove(event) {
145+
this.setBackWidth(event.changedTouches[0].clientX)
146+
}
147+
148+
setBackWidth(x) {
149+
const container = this.mouseUpElementRef.current.parentElement
150+
const { left } = container.getBoundingClientRect()
151+
const newWidth = x - left
152+
153+
this.setState({
154+
backWidth: Math.max(newWidth, 0)
155+
})
156+
}
157+
158+
setMouseUp(event) {
159+
this.toggleMouse(event, true)
160+
}
161+
162+
setMouseDown(event) {
163+
this.toggleMouse(event, false)
164+
}
165+
166+
toggleMouse(event, isMouseUp) {
167+
const isLeftClick = event.which === 1
168+
if (isLeftClick) {
169+
this.setState({isMouseUp})
170+
}
171+
}
196172
}
197173

198174
ProfileImg.contextType = Context

src/components/ProfileImg/style.scss

-25
This file was deleted.

0 commit comments

Comments
 (0)