Skip to content

Commit

Permalink
Add remote zoom support
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonas Lochmann committed May 10, 2021
1 parent ee1dd73 commit d763b69
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 3 deletions.
4 changes: 2 additions & 2 deletions presentations/demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ <h1>THE END</h1>
</div>

<script src="dist/reveal.js"></script>
<script src="plugin/zoom/zoom.js"></script>
<script src="../_remote/remotezoom.js"></script>
<script src="plugin/notes/notes.js"></script>
<script src="plugin/search/search.js"></script>
<script src="plugin/markdown/markdown.js"></script>
Expand Down Expand Up @@ -499,7 +499,7 @@ <h1>THE END</h1>
},

// Learn about plugins: https://revealjs.com/plugins/
plugins: [ RevealZoom, RevealNotes, RevealSearch, RevealMarkdown, RevealHighlight, RevealRemote ]
plugins: [ RevealRemoteZoom, RevealNotes, RevealSearch, RevealMarkdown, RevealHighlight, RevealRemote ]
});

</script>
Expand Down
12 changes: 11 additions & 1 deletion remote/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@
reveal.addEventListener("overviewshown", sendMultiplexState);
reveal.addEventListener("paused", sendMultiplexState);
reveal.addEventListener("resumed", sendMultiplexState);
reveal.addEventListener("enable-zoom", sendMultiplexState);
reveal.addEventListener("disable-zoom", sendMultiplexState);

sendMultiplexState();
}
Expand Down Expand Up @@ -227,15 +229,23 @@


function sendMultiplexState() {
socket.emit("multiplex", { state: reveal.getState() });
var state = reveal.getState();
var zoomPlugin = reveal.getPlugin("remote-zoom");
var zoom = zoomPlugin ? zoomPlugin.getCurrentZoom() : null;

socket.emit("multiplex", { state: state, zoom: zoom });
}

function msgClientConnected() {
div.style.display = "none";
}

function msgSync(data) {
var zoomPlugin = reveal.getPlugin("remote-zoom");

reveal.setState(data.state);

if (zoomPlugin) { zoomPlugin.setCurrentZoom(data.zoom); }
}

function on(cmd, fn) {
Expand Down
104 changes: 104 additions & 0 deletions remote/remotezoom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
const RevealRemoteZoom = () => {
let reveal = null
let currentZoom = null
let currentSlideElement = null

function allowControl() {
const config = reveal.getConfig()

return config.controls && config.touch
}

function dispatchEnableZoom(focus) {
if (!isValidFocus(focus)) {
console.warn('invalid focus parameter for dispatchEnableZoom()'); return
}

reveal.dispatchEvent({
type: 'enable-zoom',
data: { focus }
})
}

function dispatchDisableZoom() {
reveal.dispatchEvent({ type: 'disable-zoom' })
}

const doubleClickListener = (e) => {
if (!allowControl()) return

if (currentZoom !== null) {
dispatchDisableZoom()
} else {
const location = getRelativeLocation({ element: currentSlideElement, event: e })

dispatchEnableZoom(location)
}
}

function setupForSlideElement(element) {
if (currentSlideElement !== null) {
applyZoom(null)
currentSlideElement.removeEventListener('dblclick', doubleClickListener)
}

element.addEventListener('dblclick', doubleClickListener)

currentSlideElement = element
}

function getRelativeLocation({event, element}) {
const elementLocation = element.getBoundingClientRect()

const x = Math.round((event.clientX - elementLocation.left) * 100 / (elementLocation.right - elementLocation.left))
const y = Math.round((event.clientY - elementLocation.top) * 100 / (elementLocation.bottom - elementLocation.top))

return { x, y }
}

function applyZoom(focus) {
if (focus === null) {
currentSlideElement.style.transform = ''
currentZoom = null
} else {
if (!isValidFocus(focus)) {
console.warn('invalid focus parameter for applyZoom()'); return
}

const transform = 'scale(200%) translate(' + (50 - focus.x) + '%, ' + (50 - focus.y) + '%)'

currentSlideElement.style.transform = transform
currentZoom = focus
}
}

function isValidFocus(focus) {
return typeof focus === 'object' && Number.isInteger(focus.x) && Number.isInteger(focus.y) &&
focus.x >= 0 && focus.x <= 100 && focus.y >= 0 && focus.y <= 100 && Object.keys(focus).length === 2
}

return {
id: 'remote-zoom',
init: (initReveal) => {
reveal = initReveal

reveal.addEventListener('slidechanged', (e) => setupForSlideElement(e.currentSlide))
reveal.addEventListener('ready', (e) => setupForSlideElement(e.currentSlide))
reveal.on('enable-zoom', (e) => applyZoom(e.focus))
reveal.on('disable-zoom', (e) => applyZoom(null))
reveal.on('overviewshown', () => dispatchDisableZoom());
},
getCurrentZoom: () => currentZoom,
setCurrentZoom: (focus) => {
if (focus === null) {
dispatchDisableZoom()
} else {
if (!isValidFocus(focus)) {
console.warn('invalid focus parameter for setCurrentZoom()'); return
}

dispatchEnableZoom(focus)
}
}
}
};

0 comments on commit d763b69

Please sign in to comment.