-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmove-el-with-arrows.js
62 lines (51 loc) · 1.28 KB
/
move-el-with-arrows.js
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
import { dqs } from './utils.js'
const { fromEvent, of, merge, combineLatest } = rxjs
const { filter, mapTo, startWith, share, map } = rxjs.operators
const circle = dqs('#circle')
const keyDown$ = fromEvent(window, 'keydown').pipe(share())
const keyUp$ = fromEvent(window, 'keyup').pipe(share())
const distance$ = of(10)
const createControlStream = code => {
const codeFilter = filter(ev => ev.code === code)
const on$ = keyDown$.pipe(codeFilter)
const off$ = keyUp$.pipe(codeFilter)
return merge(on$.pipe(mapTo(true)), off$.pipe(mapTo(false))).pipe(
startWith(false),
)
}
const controls$ = combineLatest(
createControlStream('ArrowUp'),
createControlStream('ArrowDown'),
createControlStream('ArrowLeft'),
createControlStream('ArrowRight'),
distance$,
)
const direction$ = controls$.pipe(
map(([UP, DOWN, LEFT, RIGHT, DISTANCE]) => ({
UP,
DOWN,
LEFT,
RIGHT,
DISTANCE,
})),
)
const move = ({ UP, DOWN, LEFT, RIGHT, DISTANCE }) => {
const pos = circle.getBoundingClientRect()
let top = pos.top
let left = pos.left
if (UP) {
top -= DISTANCE
}
if (DOWN) {
top += DISTANCE
}
if (LEFT) {
left -= DISTANCE
}
if (RIGHT) {
left += DISTANCE
}
circle.style.top = top
circle.style.left = left
}
direction$.subscribe(move)