} | } | ||||
const Video = { | const Video = { | ||||
setUp: (username) => ({dom}) => { | setUp: (username) => ({dom}) => { | ||||
dom.username = username | |||||
dom.srcObject = new MediaStream() | dom.srcObject = new MediaStream() | ||||
if(username === State.username) { | if(username === State.username) { | ||||
dom.classList.add('self') | dom.classList.add('self') |
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) |
<script src="/libs/purify.min.js"></script> | <script src="/libs/purify.min.js"></script> | ||||
<script src="/apps/streams.js"></script> | <script src="/apps/streams.js"></script> | ||||
<script src="/apps/chat.js"></script> | <script src="/apps/chat.js"></script> | ||||
<script src="/apps/volume.js"></script> | |||||
<script src="/pico.js" defer></script> | <script src="/pico.js" defer></script> | ||||
</head> | </head> | ||||
<body style="margin: 0; padding: 0;"> | <body style="margin: 0; padding: 0;"> |
delete detail.kind | delete detail.kind | ||||
Object.assign(State, detail) | Object.assign(State, detail) | ||||
}) | }) | ||||
const doNotLog = new Set(['login', 'state', 'post', 'peerInfo']) | |||||
const doNotLog = new Set(['login', 'state', 'post', 'peerInfo', 'volumeMapMove']) | |||||
/* | /* | ||||
* | * | ||||
* UTILS | * UTILS | ||||
State.isConnected ? [ | State.isConnected ? [ | ||||
m(StreamContainer), | m(StreamContainer), | ||||
m(Chat), | m(Chat), | ||||
params.get('map') === 'true' ? m(VolumeMap) : null, | |||||
] : m(Settings), | ] : m(Settings), | ||||
) | ) | ||||
}, | }, |