|
|
@@ -0,0 +1,48 @@ |
|
|
|
const VolumeMap = { |
|
|
|
size: 200, |
|
|
|
positions: new Map(), |
|
|
|
onremove() { |
|
|
|
VolumeMap.positions.clear() |
|
|
|
}, |
|
|
|
getDot(username) { |
|
|
|
if(VolumeMap.positions.has(username)) { |
|
|
|
return VolumeMap.positions.get(username) |
|
|
|
} |
|
|
|
return [VolumeMap.size / 2, VolumeMap.size / 2] |
|
|
|
}, |
|
|
|
moveNotify({layerX, layerY}) { |
|
|
|
wire({kind: 'volumeMapMove', value: [layerX, layerY]}) |
|
|
|
}, |
|
|
|
moveDot({detail: {source, value}}) { |
|
|
|
VolumeMap.positions.set(source, value) |
|
|
|
const [x0, y0] = VolumeMap.getDot(State.username); |
|
|
|
for(const video of document.querySelectorAll('video:not(.self')) { |
|
|
|
const [x1, y1] = VolumeMap.getDot(video.username) |
|
|
|
const dist1 = Math.sqrt(Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2)) |
|
|
|
const dist2 = VolumeMap.size / Math.pow(dist1, 1.5) - 0.2 |
|
|
|
const dist3 = Math.max(Math.min(dist2, 1), 0) |
|
|
|
video.style.opacity = dist3 |
|
|
|
video.volume = dist3 |
|
|
|
} |
|
|
|
}, |
|
|
|
view() { |
|
|
|
const style = { |
|
|
|
'z-index': '999', |
|
|
|
'background-color': 'rgba(65, 105, 225, 0.8)', |
|
|
|
'font-family': 'monospace', |
|
|
|
'position': 'fixed', |
|
|
|
'height': VolumeMap.size + 'px', |
|
|
|
'width': VolumeMap.size + 'px', |
|
|
|
'right': '0', |
|
|
|
'top': '0', |
|
|
|
} |
|
|
|
return m('svg', {onclick: VolumeMap.moveNotify, style}, |
|
|
|
m('style', 'text { pointer-events: none }'), |
|
|
|
State.online.map(username => { |
|
|
|
const [x, y] = VolumeMap.getDot(username) |
|
|
|
return m('text', {x, y, fill: 'white'}, `・${username}`) |
|
|
|
}) |
|
|
|
) |
|
|
|
}, |
|
|
|
} |
|
|
|
addEventListener('volumeMapMove', VolumeMap.moveDot) |