3
3
v-bind:style =" containerStyle"
4
4
v-on:touchstart =" startSlide"
5
5
v-on:mousedown =" startSlide" >
6
+
6
7
<img :src =" after" alt =" after"
7
8
v-on:mousedown.prevent
8
9
v-on:load =" setDimensions" />
10
+
9
11
<img :src =" before" alt =" before"
10
12
v-on:mousedown.prevent
11
13
v-bind:style =" beforeImgStyle" />
14
+
12
15
<div class =" twentytwenty-overlay"
13
16
v-bind:style =" overlayStyle" >
14
17
<div v-if =" beforeLabel" class =" twentytwenty-before-label" >{{beforeLabel}}</div >
15
18
<div v-if =" afterLabel" class =" twentytwenty-after-label" >{{afterLabel}}</div >
16
19
</div >
20
+
17
21
<div class =" twentytwenty-handle"
18
- v-bind:style =" handleStyle" >
22
+ v-bind:style =" handleStyle"
23
+ tabindex =" 0"
24
+ v-on:keydown =" handleArrowNavigation" >
19
25
<div class =" twentytwenty-arrow-left" ></div >
20
26
<div class =" twentytwenty-arrow-right" ></div >
21
27
</div >
22
28
</div >
23
29
</template >
24
30
25
31
<script >
32
+
26
33
export default {
27
34
data () {
28
35
return {
@@ -33,7 +40,6 @@ export default {
33
40
overlayStyle: {}
34
41
}
35
42
},
36
-
37
43
props: {
38
44
before: {
39
45
type: String ,
@@ -52,50 +58,57 @@ export default {
52
58
offset: {
53
59
type: [String , Number ],
54
60
default: 0.5 ,
55
- validator : (value ) => {
56
- return (value > 0 && value <= 1 )
57
- }
61
+ validator : (value ) => (value > 0 && value <= 1 )
62
+ },
63
+ keyboardStep: {
64
+ type: [String , Number ],
65
+ default: 0.2 ,
66
+ validator : (value ) => (value > 0 && value <= 1 )
58
67
}
59
68
},
60
-
61
69
methods: {
62
70
setDimensions () {
63
71
const img = this .$el .querySelector (" img" )
64
72
this .imgOffset = img .getBoundingClientRect ()
65
73
this .containerStyle = { width: ` ${ this .w } px` , height: ` ${ this .h } px` };
66
74
},
67
-
68
75
startSlide (event ) {
69
76
this .sliding = true
70
77
this .moveSlide (event )
71
78
this .overlayStyle = { opacity: 0 }
72
79
},
73
-
80
+ handleArrowNavigation (event ) {
81
+ return this .moveSlide (event )
82
+ },
74
83
moveSlide (event ) {
75
84
if (this .sliding ) {
76
85
var x = (event .touches ? event .touches [0 ].pageX : event .pageX ) - this .imgOffset .left
77
86
x = (x < 0 ) ? 0 : ((x > this .w ) ? this .w : x)
78
-
79
- this .slideOffset = (x / this .w )
87
+ return this .slideOffset = (x / this .w )
88
+ }
89
+ if (event .key ) {
90
+ switch (event .key ) {
91
+ case " Left" : // IE/Edge key
92
+ case " ArrowLeft" : this .slideOffset = ((this .floatOffset - this .floatKeyboardStep ) >= 0 ) ? this .floatOffset - this .floatKeyboardStep : 0 ; break ;
93
+ case " Right" : // IE/Edge key
94
+ case " ArrowRight" : this .slideOffset = ((this .floatOffset + this .floatKeyboardStep ) <= 1 ) ? this .floatOffset + this .floatKeyboardStep : 1 ; break ;
95
+ default : return ;
96
+ }
80
97
}
81
98
},
82
-
83
99
endSlide () {
84
100
this .sliding = false
85
101
this .overlayStyle = {}
86
102
},
87
-
88
103
resize () {
89
104
this .containerStyle = {};
90
105
this .$nextTick (() => this .setDimensions ());
91
106
}
92
107
},
93
-
94
108
computed: {
95
109
beforeImgStyle () {
96
110
return { clip: ` rect(0, ${ this .x } px, ${ this .h } px, 0)` }
97
111
},
98
-
99
112
handleStyle () {
100
113
const size = 40 ;
101
114
return {
@@ -105,30 +118,29 @@ export default {
105
118
left: ` calc(${ this .slideOffset * 100 } % - ${ size/ 2 } px)`
106
119
}
107
120
},
108
-
109
121
x () {
110
122
return this .w * this .slideOffset
111
123
},
112
-
113
124
w () {
114
- if (this .imgOffset )
115
- return this .imgOffset .width
125
+ return this .imgOffset ? this .imgOffset .width : null
116
126
},
117
-
118
127
h () {
119
- if (this .imgOffset )
120
- return this .imgOffset .height
128
+ return this .imgOffset ? this .imgOffset .height : null
129
+ },
130
+ floatOffset () {
131
+ return parseFloat (this .slideOffset )
132
+ },
133
+ floatKeyboardStep () {
134
+ return parseFloat (this .keyboardStep )
121
135
}
122
136
},
123
-
124
137
mounted () {
125
138
document .addEventListener (" touchmove" , this .moveSlide )
126
139
document .addEventListener (" touchend" , this .endSlide )
127
140
document .addEventListener (" mousemove" , this .moveSlide )
128
141
document .addEventListener (" mouseup" , this .endSlide )
129
142
window .addEventListener (" resize" , this .resize )
130
143
},
131
-
132
144
beforeDestroy () {
133
145
document .removeEventListener (" touchmove" , this .moveSlide )
134
146
document .removeEventListener (" touchend" , this .endSlide )
@@ -195,6 +207,10 @@ export default {
195
207
margin-top : -4px ;
196
208
user-select : none ;
197
209
}
210
+ .twentytwenty-container .twentytwenty-handle :active ,
211
+ .twentytwenty-container .twentytwenty-handle :focus {
212
+ outline : 0 ;
213
+ }
198
214
.twentytwenty-container .twentytwenty-handle :before , .twentytwenty-container .twentytwenty-handle :after {
199
215
content : " " ;
200
216
border : 2px solid white ;
0 commit comments