Httprelay.io mcast example (shared painting canvas)
by Jonas Jasas
HTML
<header>
<h1>Httprelay.io mcast example (shared painting canvas)</h1>
<p>
<a href="https://jsfiddle.net/jasajona/ky0cLgf9" target="_blank">Open this example</a> on other computer or in new browser window.
This drawing canvas is shared among other users that are on the same data channel.
Drawing data is sent as AJAX POST requests.
Other users data is red as AJAX GET requests in infinite loop.
You can set your private data channel by entering your channel name.
This example is not optimized, it produces insane amount of requests.
</p>
<p>
<em>IMPORTANT!</em> demo.httprelay.io instance runs in extremely limited environment.
In order to evaluate performance or use it in production please
<a href="https://gitlab.com/jonas.jasas/httprelay#installation" target="_blank">run your own instance</a>.
</p>
<p>
Data channel: https://demo.httprelay.io/mcast/<input id="mcastId" value="httprelay_examples-paint">
<button id="reset">Clear canvas</button>
<button id="history">Load history</button>
</p>
<em>Paint below the line:</em>
</header>
<canvas id="canvas"></canvas>
CSS
html {
height: 100%;
display: flex;
flex-direction: column;
align-content: stretch;
}
body {
display: flex;
flex: 1 0 100%;
flex-direction: column;
align-items: stretch;
margin: 0;
}
header {
flex: 0 1 auto;
margin: 1em;
}
#canvas {
display: flex;
flex: 1 1 100%;
border-top: 1px solid grey;
}
JavaScript
let mcastUrl
let color
let elCanvas = $('#canvas')
let ctx = elCanvas[0].getContext("2d")
$(window).on('resize load', () => reset())
$('#mcastId').on('change', () => reset())
$('#reset').on('click', () => reset())
$('#history').on('click', () => reset(true))
let drawDot = (x, y, c) => {
ctx.beginPath();
ctx.fillStyle = c
ctx.arc(x, y, 5, 0, 360)
ctx.fill()
}
elCanvas.on('mousemove mousedown', e => {
if(e.buttons){
let x = e.pageX - elCanvas.offset().left;
let y = e.pageY - elCanvas.offset().top;
drawDot(x, y, color)
$.ajax({url: mcastUrl, type: 'POST', data: x+'|'+y+'|'+color, contentType: 'text/plain'}); // Sending painted dot data
}
});
$.ajaxSetup({xhrFields: {withCredentials: true}}); // Important place, enables cookies! SeqId (order of requests) is passed via cookies
let getXhr
let receive = (fromOldest) => {
if (getXhr) getXhr.abort()
url = fromOldest ? mcastUrl+'?SeqId=0&nocache='+$.now() : mcastUrl
getXhr = $.get(url).done((data) => { // Reading data in infinite loop
let d = data.split('|')
drawDot(d[0], d[1], d[2]);
}).always(() => receive());
}
let reset = (fromOldest) => {
ctx.canvas.width = ctx.canvas.clientWidth
ctx.canvas.height = ctx.canvas.clientHeight
mcastUrl = 'https://demo.httprelay.io/mcast/' + $('#mcastId').val()
color = '#'+Math.floor(Math.random()*16777215).toString(16)
receive(fromOldest);
}