New "bookmark" plugin allows hotkey fast-travel to specific steps (#852)
add plugin bookmark supporting direct access via hotkeys similar to "click", we can now fast travel using hotkeys e.g. 1 2 3
This commit is contained in:
1
build.js
1
build.js
@@ -13,6 +13,7 @@ files.push('src/plugins/autoplay/autoplay.js',
|
||||
'src/plugins/form/form.js',
|
||||
'src/plugins/fullscreen/fullscreen.js',
|
||||
'src/plugins/goto/goto.js',
|
||||
'src/plugins/bookmark/bookmark.js',
|
||||
'src/plugins/help/help.js',
|
||||
'src/plugins/impressConsole/impressConsole.js',
|
||||
'src/plugins/media/media.js',
|
||||
|
||||
@@ -28,21 +28,42 @@
|
||||
|
||||
<ul>
|
||||
<li>Impress.js allows you to layout your presentation in a 3D space</li>
|
||||
<li>Now <a href="https://github.com/impress/impress.js/tree/master/src/plugins/goto">the
|
||||
goto plugin</a> also allows you to specify
|
||||
<li><a href="https://github.com/impress/impress.js/tree/master/src/plugins/goto">The
|
||||
goto plugin</a> allows you to specify
|
||||
non-linear navigation!</li>
|
||||
<li>This demo can be navigated by
|
||||
<ul>
|
||||
<li>continuously pressing Space</li>
|
||||
<li>continuously pressing Right Arrow</li>
|
||||
<li>continuously pressing Down Arrow</li>
|
||||
<li>(or freely, pressing Up, Down, Right, Left as you choose)</li>
|
||||
</ul>
|
||||
<li>It's up to you to decide which is the better structure</li>
|
||||
</li>
|
||||
</div>
|
||||
|
||||
<div id="bm0" class="step" data-scale="1" data-rel-x="1500" data-rel-y="0"
|
||||
data-bookmark-key-list="0">
|
||||
<h1>Using bookmark hotkeys</h1>
|
||||
<ul>
|
||||
<li><a href="https://github.com/impress/impress.js/tree/master/src/plugins/bookmark">The
|
||||
bookmark plugin</a> also allows you to specify
|
||||
non-linear navigation, in a different way.</li>
|
||||
<li>This demo can <em>also</em> be navigated by
|
||||
<ul>
|
||||
<li>pressing 1 2 3 4 5 6 7 8 9 to fast travel directly</li>
|
||||
<li>pressing J J J, K K K, L L L to cycle vertically</li>
|
||||
<li>pressing U U U, I I I, O O O to cycle horizontally</li>
|
||||
<li>pressing Z or [ to zoom out to the full view</li>
|
||||
<li>pressing 0 to come back to this text</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>It's up to you to decide which is the better structure</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="contents" class="step" data-rel-x="1500" data-rel-y="1500" data-scale="1">
|
||||
<div id="contents" class="step" data-rel-x="0" data-rel-y="1500" data-scale="1"
|
||||
data-bookmark-key-list="w" >
|
||||
<h1>Choosing a treat</h1>
|
||||
|
||||
<ul>
|
||||
@@ -60,7 +81,8 @@
|
||||
<!-- Ice cream slides (3) -->
|
||||
<div id="icecream" class="step" data-x="2000" data-y="2000"
|
||||
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
|
||||
data-goto-next-list="contents icecream-pro contents crisps">
|
||||
data-goto-next-list="contents icecream-pro contents crisps"
|
||||
data-bookmark-key-list="7 u j" >
|
||||
<h1>Ice cream</h1>
|
||||
|
||||
<ul>
|
||||
@@ -73,7 +95,8 @@
|
||||
|
||||
<div id="icecream-pro" class="step" data-rel-x="0" data-rel-y="1000"
|
||||
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
|
||||
data-goto-next-list="icecream icecream-con applepie crisps-pro">
|
||||
data-goto-next-list="icecream icecream-con applepie crisps-pro"
|
||||
data-bookmark-key-list="4 i j" >
|
||||
<h1>Ice cream: Pro's</h1>
|
||||
|
||||
<ul>
|
||||
@@ -85,7 +108,8 @@
|
||||
|
||||
<div id="icecream-con" class="step" data-rel-x="0" data-rel-y="1000"
|
||||
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
|
||||
data-goto-next-list="icecream-pro crisps applepie-pro crisps-con">
|
||||
data-goto-next-list="icecream-pro crisps applepie-pro crisps-con"
|
||||
data-bookmark-key-list="1 o j" >
|
||||
<h1>Ice cream: Con's</h1>
|
||||
|
||||
<ul>
|
||||
@@ -99,7 +123,8 @@
|
||||
<!-- Crisps slides (3) -->
|
||||
<div id="crisps" class="step" data-x="3500" data-y="2000"
|
||||
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
|
||||
data-goto-next-list="icecream-con crisps-pro icecream applepie">
|
||||
data-goto-next-list="icecream-con crisps-pro icecream applepie"
|
||||
data-bookmark-key-list="8 u k" >
|
||||
<h1>Crisps</h1>
|
||||
|
||||
<ul>
|
||||
@@ -112,7 +137,8 @@
|
||||
|
||||
<div id="crisps-pro" class="step" data-rel-x="0" data-rel-y="1000"
|
||||
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
|
||||
data-goto-next-list="crisps crisps-con icecream-pro applepie-pro">
|
||||
data-goto-next-list="crisps crisps-con icecream-pro applepie-pro"
|
||||
data-bookmark-key-list="5 i k" >
|
||||
<h1>Crisps: Pro's</h1>
|
||||
|
||||
<ul>
|
||||
@@ -127,7 +153,8 @@
|
||||
|
||||
<div id="crisps-con" class="step" data-rel-x="0" data-rel-y="1000"
|
||||
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
|
||||
data-goto-next-list="crisps-pro applepie icecream-con applepie-con">
|
||||
data-goto-next-list="crisps-pro applepie icecream-con applepie-con"
|
||||
data-bookmark-key-list="2 o k" >
|
||||
<h1>Crisps: Con's</h1>
|
||||
|
||||
<ul>
|
||||
@@ -140,7 +167,8 @@
|
||||
<!-- Apple pie slides (3) -->
|
||||
<div id="applepie" class="step" data-x="5000" data-y="2000"
|
||||
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
|
||||
data-goto-next-list="crisps-con applepie-pro crisps icecream-pro">
|
||||
data-goto-next-list="crisps-con applepie-pro crisps icecream-pro"
|
||||
data-bookmark-key-list="9 u l" >
|
||||
<h1>Apple pie</h1>
|
||||
|
||||
<ul>
|
||||
@@ -152,7 +180,8 @@
|
||||
|
||||
<div id="applepie-pro" class="step" data-rel-x="0" data-rel-y="1000"
|
||||
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
|
||||
data-goto-next-list="applepie applepie-con crisps-pro icecream-con">
|
||||
data-goto-next-list="applepie applepie-con crisps-pro icecream-con"
|
||||
data-bookmark-key-list="6 i l" >
|
||||
<h1>Apple pie: Pro's</h1>
|
||||
|
||||
<ul>
|
||||
@@ -165,7 +194,8 @@
|
||||
|
||||
<div id="applepie-con" class="step" data-rel-x="0" data-rel-y="1000"
|
||||
data-goto-key-list="ArrowUp ArrowDown ArrowLeft ArrowRight"
|
||||
data-goto-next-list="applepie-pro conclusion crisps-con conclusion">
|
||||
data-goto-next-list="applepie-pro conclusion crisps-con conclusion"
|
||||
data-bookmark-key-list="3 o l" >
|
||||
<h1>Apple pie: Con's</h1>
|
||||
|
||||
<ul>
|
||||
@@ -175,7 +205,8 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div id="conclusion" class="step" data-rel-x="1000" data-rel-y="1000">
|
||||
<div id="conclusion" class="step" data-rel-x="1000" data-rel-y="1000"
|
||||
data-bookmark-key-list="q" >
|
||||
<h1>Conclusion</h1>
|
||||
|
||||
<p>Can I choose all three ;-)</p>
|
||||
@@ -186,7 +217,8 @@
|
||||
<a href="https://www.flickr.com/photos/stevepj2009/6296334551">stevepj2009@Flickr</a> </p>
|
||||
</div>
|
||||
|
||||
<div id="overview" class="step" data-x="3000" data-y="2000" data-scale="9" style="pointer-events: none;">
|
||||
<div id="overview" class="step" data-x="3000" data-y="2000" data-scale="9" style="pointer-events: none;"
|
||||
data-bookmark-key-list="z [" >
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
27
src/plugins/bookmark/README.md
Normal file
27
src/plugins/bookmark/README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Bookmark
|
||||
|
||||
Nonlinear navigation similar to the Goto plugin.
|
||||
|
||||
Goto supports nonlinear navigation by *locally* defining *out-links*, accessible via the arrow keys.
|
||||
|
||||
Bookmark supports nonlinear navigation by *globally* defining *in-links*, accessible via normal keys like 1,2,3,A,B,C.
|
||||
|
||||
Example:
|
||||
|
||||
```html
|
||||
<!-- data-bookmark-key-list allows an "inbound"-oriented style of non-linear navigation. -->
|
||||
<div id="..." class="step" data-bookmark-key-list="Digit1 KeyA 1 2 3 a b c">
|
||||
```
|
||||
|
||||
An `id` is required on the `div`.
|
||||
|
||||
If you assign the same key to multiple steps, that hotkey will cycle among them.
|
||||
|
||||
WARNING: It's up to you to avoid reserved hotkeys H, B, P, ?, etc.
|
||||
|
||||
Author
|
||||
------
|
||||
|
||||
Copyright 2023 Wong Meng Weng (@mengwong)
|
||||
Released under the MIT license.
|
||||
|
||||
72
src/plugins/bookmark/bookmark.js
Normal file
72
src/plugins/bookmark/bookmark.js
Normal file
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Bookmark Plugin
|
||||
*
|
||||
* The bookmark plugin consists of
|
||||
* a pre-init plugin,
|
||||
* a keyup listener, and
|
||||
* a pre-stepleave plugin.
|
||||
*
|
||||
* The pre-init plugin surveys all step divs to set up bookmark keybindings.
|
||||
* The pre-stepleave plugin alters the destination when a bookmark hotkey is pressed.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* <!-- data-bookmark-key-list allows an "inbound" style of non-linear navigation. -->
|
||||
* <div id="..." class="step" data-bookmark-key-list="Digit1 KeyA 1 2 3 a b c">
|
||||
*
|
||||
* See https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values for a table
|
||||
* of what strings to use for each key. Both .key and .code styles are recognized.
|
||||
*
|
||||
* It's up to the HTML author to avoid reserved hotkeys H, B, P, ? etc.
|
||||
*
|
||||
* Copyright 2016-2017 Henrik Ingo (@henrikingo)
|
||||
* Released under the MIT license.
|
||||
*/
|
||||
/* global document, impress */
|
||||
|
||||
( function( document ) {
|
||||
"use strict";
|
||||
var hotkeys = {};
|
||||
function hotkeyDest( event ) {
|
||||
return ( hotkeys.hasOwnProperty( event.key ) ? hotkeys[ event.key ] :
|
||||
hotkeys.hasOwnProperty( event.code ) ? hotkeys[ event.code ] : null ); }
|
||||
|
||||
// In pre-init phase, build a map of bookmark hotkey to div id, by reviewing all steps
|
||||
impress.addPreInitPlugin( function( root, api ) {
|
||||
root.querySelectorAll( ".step" ).forEach( function( div ) {
|
||||
if ( div.dataset.bookmarkKeyList !== undefined && div.id !== undefined ) {
|
||||
div.dataset.bookmarkKeyList.split( " " ).forEach( ( k ) => {
|
||||
if ( hotkeys.hasOwnProperty( k ) ) {
|
||||
hotkeys[ k ].push( div.id );
|
||||
} else { hotkeys[ k ] = [ div.id ]; } } ); } } );
|
||||
|
||||
api.lib.gc.addEventListener( document, "keyup", function( event ) {
|
||||
if ( hotkeyDest( event ) !== null ) {
|
||||
event.stopImmediatePropagation();
|
||||
api.next( event );
|
||||
|
||||
// Event.preventDefault();
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
// In pre-stepleave phase, match a hotkey and reset destination accordingly.
|
||||
impress.addPreStepLeavePlugin( function( event ) {
|
||||
|
||||
// Window.console.log(`bookmark: running as PreStepLeavePlugin; event=`);
|
||||
// window.console.log(event)
|
||||
if ( ( !event || !event.origEvent ) ) { return; }
|
||||
var dest = hotkeyDest( event.origEvent );
|
||||
if ( dest ) {
|
||||
|
||||
// Window.console.log(`bookmark: recognizing hotkey ${event.code} goes to ${dest}`)
|
||||
var newTarget = document.getElementById( dest[ 0 ] ); // jshint ignore:line
|
||||
if ( newTarget ) {
|
||||
event.detail.next = newTarget;
|
||||
dest.push( dest.shift() ); // Repeated hotkey presses cycle through each dest.
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
} )( document );
|
||||
|
||||
Reference in New Issue
Block a user