slideshow.io/static/js/speaker.js

286 lines
6.8 KiB
JavaScript
Executable File

$(function() { sio = (function() {
var sio = {};
var counter = $('#counter');
var canvasPdf = $('#canvas-pdf').get(0);
var contextPdf = canvasPdf.getContext('2d');
var canvasPaint = $('#canvas-paint').get(0);
var contextPaint = canvasPaint.getContext('2d');
var pdf;
var currentPage = 1;
var startTime = 0;
var startSlide = 0;
var refreshIntervalId = 0;
var pointer = false;
var shouldUpdatePointer = false;
var canvasPdfBounding;
var lasers = {};
var drawAudienceLasers = false;
PDFJS.getDocument('/static/uploaded/' + filename + '.pdf?' + (Math.floor(Math.random() * 10000))).then(function getPdf(_pdf) {
pdf = _pdf;
updateUI();
});
var socket = io();
socket.on('welcome', function() {
socket.emit('speaker', filename, socket.id);
});
socket.on('pointer', canvasPointer);
function filterInt(value) {
if(/^(\-|\+)?([0-9]+|Infinity)$/.test(value))
return Number(value);
return NaN;
}
var updateUI = function() {
counter.val(currentPage + '/' + pdf.pdfInfo.numPages);
$('#previous,#first').prop('disabled', currentPage === 1);
$('#next,#last').prop('disabled', currentPage === pdf.pdfInfo.numPages);
pdf.getPage(currentPage).then(function(page) {
previousPage = currentPage;
var viewport = page.getViewport(2.0);
canvasPdf.width = viewport.width;
canvasPdf.height = viewport.height;
canvasPaint.width = viewport.width;
canvasPaint.height = viewport.height;
$('#canvases').width(canvasPdf.width + 'px');
$('#canvases').height(canvasPdf.height + 'px');
canvasPdfBounding = canvasPdf.getBoundingClientRect();
var renderContext = {
canvasContext: contextPdf,
viewport: viewport
};
page.render(renderContext);
});
};
function updateAudience() { socket.emit('change-slide', filename, currentPage); }
function formatTime(ms) {
var sec = padToTwo(Math.floor((ms / 1000) % 60));
var min = padToTwo(Math.floor(((ms / 1000 - sec) % 3600) / 60));
return min + ':' + sec;
}
function updateTimers() {
if (refreshIntervalId !== 0) {
$('#totalTime').html(formatTime(Date.now() - startTime));
$('#slideTime').html(formatTime(Date.now() - startSlide));
}
}
function padToTwo(number) {
if (number<=99) { number = ("0"+number).slice(-2); }
return number;
}
function resetTimeSlide() {
startSlide = Date.now();
updateTimers();
}
// Check if number is valid, and updates
// number undefined means sync all clients
function changeSlide(number) {
if (isNaN(number) || number < 1 || number > pdf.pdfInfo.numPages) {
return false;
}
if (currentPage === undefined || currentPage === number) {
updateAudience();
return true;
}
currentPage = number;
updateUI();
updateAudience();
resetTimeSlide();
return true;
}
function canvasPointer(id,x,y) {
// Clear canvas
canvasPaint.width = canvasPaint.width;
if (id != undefined) {
if (x != undefined && y != undefined) {
lasers[id] = {x:x, y:y};
} else {
delete lasers[id];
}
}
for (var laserIndex in lasers) {
var laser = lasers[laserIndex];
if (drawAudienceLasers === true || laserIndex === socket.id) {
contextPaint.fillStyle = laserIndex === socket.id ? 'red' : 'green';
contextPaint.beginPath();
contextPaint.arc(laser.x * canvasPdf.width, laser.y * canvasPdf.height, 10, 0, Math.PI*2, true);
contextPaint.closePath();
contextPaint.fill();
}
}
}
sio.onMouseDown = function(event) {
var x = event.offsetX / canvasPdf.width;
var y = event.offsetY / canvasPdf.height;
socket.emit('pointer', filename, socket.id, x, y);
pointer = true;
shouldUpdatePointer = true;
canvasPointer(socket.id, x, y);
};
sio.onMouseMove = function(event) {
if (pointer) {
var x = event.offsetX / canvasPdf.width;
var y = event.offsetY / canvasPdf.height;
if (shouldUpdatePointer) {
// Update
socket.emit('pointer', filename, socket.id, x, y);
shouldUpdatePointer = false;
setTimeout(function() {
shouldUpdatePointer = true;
}, 20);
}
canvasPointer(socket.id, x, y);
}
};
sio.onMouseUp = function(event) {
socket.emit('pointer', filename, socket.id);
pointer = false;
shouldUpdatePointer = false;
canvasPointer(socket.id);
};
sio.startPresentation = function() {
startTime = startSlide = Date.now();
refreshIntervalId = setInterval(updateTimers, 1000);
updateTimers();
$('#start').prop('disabled', true);
$('#stop').prop('disabled', false);
};
sio.stopPresentation = function() {
clearInterval(refreshIntervalId);
refreshIntervalId = 0;
$('#start').prop('disabled', false);
$('#stop').prop('disabled', true);
};
sio.changeSlideFromCounter = function() {
var slideNumber = filterInt($('#counter').val());
changeSlide(slideNumber);
// lose focus
$(':focus').blur();
};
sio.switchAudienceLaser = function() {
var laser = $('#viewer-laser');
if (drawAudienceLasers === false) {
// Laser is disabled, will be enabled
laser.text('Audience laser is enabled');
laser.removeClass('btn-default').addClass('btn-primary');
drawAudienceLasers = true;
} else {
laser.text('Audience laser is disabled');
laser.removeClass('btn-primary').addClass('btn-default');
drawAudienceLasers = false;
}
socket.emit('viewer-laser', filename, drawAudienceLasers);
};
sio.clearCounter = function() { $('#counter').val(''); };
sio.nextSlide = function() { changeSlide(currentPage + 1); };
sio.previousSlide = function() { changeSlide(currentPage - 1); };
sio.firstSlide = function() { changeSlide(1); };
sio.lastSlide = function() { changeSlide(pdf.pdfInfo.numPages); };
sio.syncAudience = updateAudience;
sio.update = updateUI;
$(window).resize(updateUI);
return sio;
})(); });