[mirotalk] - responsive whiteboard
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
||||
# ====================================================
|
||||
# MiroTalk P2P v.1.6.69 - Environment Configuration
|
||||
# MiroTalk P2P v.1.6.70 - Environment Configuration
|
||||
# ====================================================
|
||||
|
||||
# App environment
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
/**
|
||||
* ==============================================
|
||||
* MiroTalk P2P v.1.6.69 - Configuration File
|
||||
* MiroTalk P2P v.1.6.70 - Configuration File
|
||||
* ==============================================
|
||||
*
|
||||
* Branding and customizations require a license:
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ dependencies: {
|
||||
* @license For commercial use or closed source, contact us at license.mirotalk@gmail.com or purchase directly from CodeCanyon
|
||||
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-p2p-webrtc-realtime-video-conferences/38376661
|
||||
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
|
||||
* @version 1.6.69
|
||||
* @version 1.6.70
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "mirotalk",
|
||||
"version": "1.6.69",
|
||||
"version": "1.6.70",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "mirotalk",
|
||||
"version": "1.6.69",
|
||||
"version": "1.6.70",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@mattermost/client": "11.1.0",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mirotalk",
|
||||
"version": "1.6.69",
|
||||
"version": "1.6.70",
|
||||
"description": "A free WebRTC browser-based video call",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
--iframe-height: 480px;
|
||||
|
||||
/* whiteboard resize */
|
||||
--wb-width: 800px;
|
||||
--wb-height: 600px;
|
||||
--wb-width: 1920px;
|
||||
--wb-height: 1080px;
|
||||
|
||||
/* my settings */
|
||||
--mySettings-select-w: 100%;
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
position: fixed;
|
||||
margin: auto;
|
||||
padding: 10px;
|
||||
width: var(--wb-width);
|
||||
height: var(--wb-height);
|
||||
width: calc(var(--wb-width) * 1px);
|
||||
height: calc(var(--wb-height) * 1px);
|
||||
max-width: 100vw;
|
||||
max-height: 100vh;
|
||||
background: var(--wb-bg);
|
||||
border: var(--border);
|
||||
box-shadow: var(--box-shadow);
|
||||
@@ -27,7 +29,34 @@
|
||||
-webkit-animation-duration: 1s;
|
||||
-moz-animation-duration: 1s;
|
||||
animation-duration: 1s;
|
||||
overflow: hidden;
|
||||
overflow: visible;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Mobile optimizations */
|
||||
@media (max-width: 768px) {
|
||||
#whiteboard {
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.whiteboard-header {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.whiteboard-header-title button,
|
||||
.whiteboard-header-options button {
|
||||
padding: 5px;
|
||||
font-size: 0.75rem;
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.whiteboardColorPicker {
|
||||
width: 16px;
|
||||
height: 12px;
|
||||
margin: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.whiteboard-header {
|
||||
@@ -45,6 +74,11 @@
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.whiteboard-header-options {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#whiteboardUnlockBtn,
|
||||
#whiteboardLockBtn {
|
||||
display: none;
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ let brand = {
|
||||
},
|
||||
about: {
|
||||
imageUrl: '../images/mirotalk-logo.gif',
|
||||
title: 'WebRTC P2P v1.6.69',
|
||||
title: 'WebRTC P2P v1.6.70',
|
||||
html: `
|
||||
<button
|
||||
id="support-button"
|
||||
|
||||
+90
-27
@@ -15,7 +15,7 @@
|
||||
* @license For commercial use or closed source, contact us at license.mirotalk@gmail.com or purchase directly from CodeCanyon
|
||||
* @license CodeCanyon: https://codecanyon.net/item/mirotalk-p2p-webrtc-realtime-video-conferences/38376661
|
||||
* @author Miroslav Pejic - miroslav.pejic.85@gmail.com
|
||||
* @version 1.6.69
|
||||
* @version 1.6.70
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -116,8 +116,10 @@ const fileSharingInput = '*'; // allow all file extensions
|
||||
const Base64Prefix = 'data:application/pdf;base64,';
|
||||
const wbPdfInput = 'application/pdf';
|
||||
const wbImageInput = 'image/*';
|
||||
const wbWidth = 1280;
|
||||
const wbHeight = 768;
|
||||
|
||||
// Reference dimensions for whiteboard (16:9 aspect ratio)
|
||||
const wbReferenceWidth = 1920;
|
||||
const wbReferenceHeight = 1080;
|
||||
|
||||
// Peer infos
|
||||
const extraInfo = getId('extraInfo');
|
||||
@@ -11193,8 +11195,9 @@ function toggleWhiteboard() {
|
||||
}
|
||||
|
||||
whiteboard.classList.toggle('show');
|
||||
whiteboard.style.top = '50%';
|
||||
whiteboard.style.left = '50%';
|
||||
|
||||
centerWhiteboard();
|
||||
|
||||
wbIsOpen = !wbIsOpen;
|
||||
screenReaderAccessibility.announceMessage(wbIsOpen ? 'Whiteboard opened' : 'Whiteboard closed');
|
||||
}
|
||||
@@ -11208,6 +11211,32 @@ function setupWhiteboard() {
|
||||
setupWhiteboardLocalListeners();
|
||||
setupWhiteboardShortcuts();
|
||||
setupWhiteboardDragAndDrop();
|
||||
setupWhiteboardResizeListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whiteboard: setup resize listener for responsive behavior
|
||||
*/
|
||||
function setupWhiteboardResizeListener() {
|
||||
let resizeTimer;
|
||||
window.addEventListener('resize', () => {
|
||||
// Debounce resize events to avoid performance issues
|
||||
clearTimeout(resizeTimer);
|
||||
resizeTimer = setTimeout(() => {
|
||||
if (wbCanvas && wbIsOpen) {
|
||||
setupWhiteboardCanvasSize();
|
||||
}
|
||||
}, 250);
|
||||
});
|
||||
|
||||
// Also handle orientation change for mobile devices
|
||||
window.addEventListener('orientationchange', () => {
|
||||
setTimeout(() => {
|
||||
if (wbCanvas && wbIsOpen) {
|
||||
setupWhiteboardCanvasSize();
|
||||
}
|
||||
}, 300);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -11221,32 +11250,62 @@ function setupWhiteboardCanvas() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Whiteboard: setup canvas size
|
||||
* Whiteboard: setup canvas size to always fit full screen with proper scaling
|
||||
*/
|
||||
function setupWhiteboardCanvasSize() {
|
||||
const optimalSize = [wbWidth, wbHeight];
|
||||
const scaleFactorX = window.innerWidth / optimalSize[0];
|
||||
const scaleFactorY = window.innerHeight / optimalSize[1];
|
||||
if (scaleFactorX < scaleFactorY && scaleFactorX < 1) {
|
||||
wbCanvas.setWidth(optimalSize[0] * scaleFactorX);
|
||||
wbCanvas.setHeight(optimalSize[1] * scaleFactorX);
|
||||
wbCanvas.setZoom(scaleFactorX);
|
||||
setWhiteboardSize(optimalSize[0] * scaleFactorX, optimalSize[1] * scaleFactorX);
|
||||
} else if (scaleFactorX > scaleFactorY && scaleFactorY < 1) {
|
||||
wbCanvas.setWidth(optimalSize[0] * scaleFactorY);
|
||||
wbCanvas.setHeight(optimalSize[1] * scaleFactorY);
|
||||
wbCanvas.setZoom(scaleFactorY);
|
||||
setWhiteboardSize(optimalSize[0] * scaleFactorY, optimalSize[1] * scaleFactorY);
|
||||
} else {
|
||||
wbCanvas.setWidth(optimalSize[0]);
|
||||
wbCanvas.setHeight(optimalSize[1]);
|
||||
wbCanvas.setZoom(1);
|
||||
setWhiteboardSize(optimalSize[0], optimalSize[1]);
|
||||
}
|
||||
// Get available viewport dimensions
|
||||
const viewportWidth = window.innerWidth;
|
||||
const viewportHeight = window.innerHeight;
|
||||
|
||||
// Account for whiteboard container padding
|
||||
const containerPadding = isMobileDevice ? 10 : 20; // 5px * 2 for mobile, 10px * 2 for desktop
|
||||
|
||||
// Header height varies by device
|
||||
const headerHeight = isMobileDevice ? 40 : 60; // Smaller header on mobile
|
||||
|
||||
const extraMargin = 20; // Small margin to avoid any overflow
|
||||
|
||||
const availableWidth = viewportWidth - containerPadding - extraMargin;
|
||||
const availableHeight = viewportHeight - containerPadding - headerHeight - extraMargin;
|
||||
|
||||
// Calculate scale factor to fit the viewport while maintaining aspect ratio
|
||||
const scaleX = availableWidth / wbReferenceWidth;
|
||||
const scaleY = availableHeight / wbReferenceHeight;
|
||||
const scale = Math.min(scaleX, scaleY);
|
||||
|
||||
// Set canvas dimensions to scaled reference size
|
||||
const canvasWidth = wbReferenceWidth * scale;
|
||||
const canvasHeight = wbReferenceHeight * scale;
|
||||
|
||||
// Update canvas dimensions and zoom
|
||||
wbCanvas.setWidth(canvasWidth);
|
||||
wbCanvas.setHeight(canvasHeight);
|
||||
wbCanvas.setZoom(scale);
|
||||
|
||||
// Update CSS variables for whiteboard container
|
||||
// Add padding and header to get total container size
|
||||
setWhiteboardSize(canvasWidth + containerPadding, canvasHeight + headerHeight + containerPadding);
|
||||
|
||||
// Recenter whiteboard on screen
|
||||
centerWhiteboard();
|
||||
|
||||
// Recalculate offsets and render
|
||||
wbCanvas.calcOffset();
|
||||
wbCanvas.renderAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whiteboard: center on screen
|
||||
*/
|
||||
function centerWhiteboard() {
|
||||
if (whiteboard) {
|
||||
// Force reflow to ensure centering is applied
|
||||
whiteboard.style.top = '50%';
|
||||
whiteboard.style.left = '50%';
|
||||
whiteboard.style.transform = 'translate(-50%, -50%)';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whiteboard: setup size
|
||||
* @param {string} w width
|
||||
@@ -11975,10 +12034,14 @@ async function wbUpdate() {
|
||||
function handleJsonToWbCanvas(config) {
|
||||
if (!wbIsOpen) toggleWhiteboard();
|
||||
wbIsRedoing = true;
|
||||
|
||||
// Parse the JSON and load it
|
||||
wbCanvas.loadFromJSON(config.wbCanvasJson, function () {
|
||||
wbCanvas.renderAll();
|
||||
// After loading, ensure proper scaling is maintained
|
||||
setupWhiteboardCanvasSize();
|
||||
wbIsRedoing = false;
|
||||
});
|
||||
|
||||
if (!isPresenter && !wbCanvas.isDrawingMode && wbIsLock) {
|
||||
wbDrawing(false);
|
||||
}
|
||||
@@ -13086,7 +13149,7 @@ function showAbout() {
|
||||
Swal.fire({
|
||||
background: swBg,
|
||||
position: 'center',
|
||||
title: brand.about?.title && brand.about.title.trim() !== '' ? brand.about.title : 'WebRTC P2P v1.6.69',
|
||||
title: brand.about?.title && brand.about.title.trim() !== '' ? brand.about.title : 'WebRTC P2P v1.6.70',
|
||||
imageUrl: brand.about?.imageUrl && brand.about.imageUrl.trim() !== '' ? brand.about.imageUrl : images.about,
|
||||
customClass: { image: 'img-about' },
|
||||
html: `
|
||||
|
||||
Reference in New Issue
Block a user