First talk
|
@ -0,0 +1,251 @@
|
|||
# reveal.js
|
||||
|
||||
A CSS 3D slideshow tool for quickly creating good looking HTML presentations. Doesn't _rely_ on any external libraries but [highlight.js](http://softwaremaniacs.org/soft/highlight/en/description/) is included by default for code highlighting.
|
||||
|
||||
Note that this requires a browser with support for CSS 3D transforms and ``classList``. If CSS 3D support is not detected, the presentation will degrade to less exciting 2D transitions. A [classList polyfill](http://purl.eligrey.com/github/classList.js/blob/master/classList.js) is incuded to make this work in < iOS 5, < Safari 5.1 and IE.
|
||||
|
||||
Curious about how it looks in action? [Check out the demo page](http://lab.hakim.se/reveal-js/).
|
||||
|
||||
## Usage
|
||||
|
||||
### Markup
|
||||
|
||||
Markup heirarchy needs to be ``<div class="reveal"> <div class="slides"> <section>`` where the ``<section>`` represents one slide and can be repeated indefinitely. If you place multiple ``<section>``'s inside of another ``<section>`` they will be shown as vertical slides. For example:
|
||||
|
||||
```html
|
||||
<div class="reveal">
|
||||
<div class="slides">
|
||||
<section>Single Horizontal Slide</section>
|
||||
<section>
|
||||
<section>Vertical Slide 1</section>
|
||||
<section>Vertical Slide 2</section>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
### Configuration
|
||||
|
||||
At the end of your page, after ``<script src="js/reveal.js"></script>``, you need to initialize reveal by running the following code. Note that all config values are optional and will default as specified below.
|
||||
|
||||
```javascript
|
||||
Reveal.initialize({
|
||||
// Display controls in the bottom right corner
|
||||
controls: true,
|
||||
|
||||
// Display a presentation progress bar
|
||||
progress: true,
|
||||
|
||||
// Push each slide change to the browser history
|
||||
history: false,
|
||||
|
||||
// Enable keyboard shortcuts for navigation
|
||||
keyboard: true,
|
||||
|
||||
// Loop the presentation
|
||||
loop: false,
|
||||
|
||||
// Number of milliseconds between automatically proceeding to the
|
||||
// next slide, disabled when set to 0
|
||||
autoSlide: 0,
|
||||
|
||||
// Enable slide navigation via mouse wheel
|
||||
mouseWheel: true,
|
||||
|
||||
// Apply a 3D roll to links on hover
|
||||
rollingLinks: true,
|
||||
|
||||
// UI style
|
||||
theme: 'default', // default/neon/beige
|
||||
|
||||
// Transition style
|
||||
transition: 'default' // default/cube/page/concave/linear(2d)
|
||||
});
|
||||
```
|
||||
|
||||
### API
|
||||
|
||||
The Reveal class provides a minimal JavaScript API for controlling its navigation:
|
||||
|
||||
- Reveal.navigateTo( indexh, indexv );
|
||||
- Reveal.navigateLeft();
|
||||
- Reveal.navigateRight();
|
||||
- Reveal.navigateUp();
|
||||
- Reveal.navigateDown();
|
||||
- Reveal.navigatePrev();
|
||||
- Reveal.navigateNext();
|
||||
- Reveal.toggleOverview();
|
||||
|
||||
### States
|
||||
|
||||
If you set ``data-state="somestate"`` on a slide ``<section>``, "somestate" will be applied as a class on the document element when that slide is opened. This allows you to apply broad style changes to the page based on the active slide.
|
||||
|
||||
Furthermore you can also listen to these changes in state via JavaScript:
|
||||
|
||||
```javascript
|
||||
Reveal.addEventListener( 'somestate', function() {
|
||||
// TODO: Sprinkle magic
|
||||
}, false );
|
||||
```
|
||||
|
||||
### Slide change event
|
||||
|
||||
An 'slidechanged' event is fired each time the slide is changed (regardless of state). The event object holds the index values of the current slide as well as a reference to the previous and current slide HTML nodes.
|
||||
|
||||
```javascript
|
||||
Reveal.addEventListener( 'slidechanged', function( event ) {
|
||||
// event.previousSlide, event.currentSlide, event.indexh, event.indexv
|
||||
} );
|
||||
```
|
||||
|
||||
### Fragment events
|
||||
|
||||
When a slide fragment is either shown or hidden reveal.js will dispatch an event.
|
||||
|
||||
```javascript
|
||||
Reveal.addEventListener( 'fragmentshown', function( event ) {
|
||||
// event.fragment = the fragment DOM element
|
||||
} );
|
||||
Reveal.addEventListener( 'fragmenthidden', function( event ) {
|
||||
// event.fragment = the fragment DOM element
|
||||
} );
|
||||
```
|
||||
|
||||
### Folder Structure
|
||||
- **css/** Core styles without which the project does not function
|
||||
- **js/** Like above but for JavaScript
|
||||
- **plugin/** Components that have been developed as extensions to reveal.js
|
||||
- **lib/** All other third party assets (JavaScript, CSS, fonts)
|
||||
|
||||
## Speaker Notes
|
||||
|
||||
If you're interested in using speaker notes, reveal.js comes with a Node server that allows you to deliver your presentation in one browser while viewing speaker notes in another.
|
||||
|
||||
To include speaker notes in your presentation, simply add an `<aside class="notes">` element to any slide. These notes will be hidden in the main presentation view.
|
||||
|
||||
You'll also need to [install Node.js](http://nodejs.org/); then, install the server dependencies by running `npm install`.
|
||||
|
||||
Once Node.js and the dependencies are installed, run the following command from the root directory:
|
||||
|
||||
node plugin/speakernotes
|
||||
|
||||
By default, the slides will be served at [localhost:1947](http://localhost:1947).
|
||||
|
||||
You can change the appearance of the speaker notes by editing the file at `plugin/speakernotes/notes.html`.
|
||||
|
||||
### Known Issues
|
||||
|
||||
- The notes page is supposed to show the current slide and the next slide, but when it first starts, it always shows the first slide in both positions.
|
||||
|
||||
## Examples
|
||||
|
||||
* http://lab.hakim.se/reveal-js/ (original)
|
||||
* http://www.ideapolisagency.com/ by [@achrafkassioui](http://twitter.com/achrafkassioui)
|
||||
* http://lucienfrelin.com/ by [@lucienfrelin](http://twitter.com/lucienfrelin)
|
||||
* http://creatorrr.github.com/ThePoet/
|
||||
* http://moduscreate.com/ by [@ModusCreate](https://twitter.com/ModusCreate)
|
||||
* http://idea.diwank.name/ by [Diwank Singh](http://diwank.name/)
|
||||
* [Webapp Development Stack & Tooling](http://dl.dropbox.com/u/39519/talks/jquk-tooling%2Bappstack/index.html) by [Paul Irish](https://github.com/paulirish)
|
||||
* [Lock-free algorithms](http://concurrencykit.org/presentations/lockfree_introduction/) by Samy Al Bahra
|
||||
* [Not Your Average Drag and Drop](http://www.thecssninja.com/talks/not_your_average_dnd/) by [Ryan Seddon](https://github.com/ryanseddon)
|
||||
* [Elasticsearch](http://spinscale.github.com/elasticsearch/2012-03-jugm.html) by [@spinscale](http://twitter.com/spinscale)
|
||||
* [JavaScript Tooling](http://dl.dropbox.com/u/39519/talks/jsconf-tools/index.html) by [Paul Irish](https://github.com/paulirish)
|
||||
* [The Graphical Web: Fostering Creativity](http://vhardy.github.com/presentations/html5-community-meet-up-2012/) by [Vincent Hardy](https://github.com/vhardy)
|
||||
* [Mobile Web Programming is a Bloody Mess](http://westcoastlogic.com/slides/debug-mobile/) by [Brian LeRoux](https://github.com/brianleroux)
|
||||
* [Bio Database Access and Sequence Alignment](http://www.philipbjorge.com/bioinformatics-presentation/) by [Philip Bjorge](https://github.com/philipbjorge)
|
||||
* [Web vs Native](http://prez.mahemoff.com/state-native/) by [Michael Mahemoff](https://github.com/mahemoff)
|
||||
* [Continuously Integrated JS Development](http://trodrigues.net/presentations/buster-ci/) by [Tiago Rodrigues](https://github.com/trodrigues)
|
||||
* [To be Future Friendly is to be Device Agnostic](http://dl.dropbox.com/u/409429/presentations/toster-2012/index.html) by [Joe McCann](https://github.com/joemccann)
|
||||
* [The Web Development Workflow of 2013](http://dl.dropbox.com/u/39519/talks/fluent/index.html) by [Paul Irish](https://github.com/paulirish)
|
||||
* [How To Cope With Graphical Challenges Using Latest Web Technologies](http://alexw.me/playground/slideshows/w3c_netcraft/) by [Alex Wolkov](https://github.com/altryne)
|
||||
* [Going Deeper with jQuery Mobile](http://andymatthews.net/downloads/presentations/going-deeper-with-jquery-mobile/) by [Andy Matthews](https://github.com/commadelimited)
|
||||
* [Studio Nord](http://studionord.org)
|
||||
* [Herrljunga Cider](http://herrljungacider.se/uk/campaign/)
|
||||
|
||||
|
||||
[Send me a link](http://hakim.se/about/contact) if you used reveal.js for a project or presentation.
|
||||
|
||||
|
||||
## History
|
||||
|
||||
#### 1.4 (master/beta)
|
||||
- Main #reveal container is now selected via a class instead of ID
|
||||
- API methods for adding or removing all event listeners
|
||||
- The ```slidechange``` event now includes currentSlide and previousSlide
|
||||
- Fixed bug where 'slidechange' was firing twice when history was enabled
|
||||
- Folder structure updates for scalability (see /lib & /plugin)
|
||||
- Slide notes by [rmurphey](https://github.com/rmurphey)
|
||||
- Bumped up default font-size for code samples
|
||||
- Added beige theme
|
||||
- Added 'autoSlide' config
|
||||
- Bug fix: The 'slidechanged' event is now firing upon 'hashchange'. Thanks [basecode](https://github.com/basecode)
|
||||
- Bug fix: JS error when the 'progress' option was true but there was no progress DOM element
|
||||
- ```keyboard``` config flag for disabling all keyboard navigation
|
||||
|
||||
#### 1.3
|
||||
- Revised keyboard shortcuts, including ESC for overview, N for next, P for previous. Thanks [mahemoff](https://github.com/mahemoff)
|
||||
- Added support for looped presentations via config
|
||||
- Fixed IE9 fallback
|
||||
- Added event binding methods (Reveal.addEventListener, Reveal.removeEventListener)
|
||||
- Added 'slidechanged' event
|
||||
- Added print styles. Thanks [skypanther](https://github.com/skypanther)
|
||||
- The address bar now hides automatically on mobile browsers
|
||||
- Space and return keys can be used to exit the overview mode
|
||||
- Events for fragment states ('fragmentshown'/'fragmenthidden')
|
||||
- Support for swipe navigation on touch devices. Thanks [akiersky](https://github.com/akiersky)
|
||||
- Support for pinch to overview on touch devices
|
||||
|
||||
#### 1.2
|
||||
|
||||
- Big changes to DOM structure:
|
||||
- Previous #main wrapper is now called #reveal
|
||||
- Slides were moved one level deeper, into #reveal .slides
|
||||
- Controls and progress bar were moved into #reveal
|
||||
- CSS is now much more explicit, rooted at #reveal, to prevent conflicts
|
||||
- Config option for disabling updates to URL, defaults to true
|
||||
- Anchors with image children no longer rotate in 3D on hover
|
||||
- Support for mouse wheel navigation ([naugtur](https://github.com/naugtur))
|
||||
- Delayed updates to URL hash to work around a bug in Chrome
|
||||
- Included a classList polyfill for IE9
|
||||
- Support for wireless presenter keys
|
||||
- States can now be applied as classes on the document element by adding data-state on a slide
|
||||
|
||||
#### 1.1
|
||||
|
||||
- Added an optional presentation progress bar
|
||||
- Images wrapped in anchors no longer unexpectedly flip in 3D
|
||||
- Slides that contain other slides are given the 'stack' class
|
||||
- Added 'transition' option for specifying transition styles
|
||||
- Added 'theme' option for specifying UI styles
|
||||
- New transitions: 'box' & 'page'
|
||||
- New theme: 'neon'
|
||||
|
||||
#### 1.0
|
||||
|
||||
- New and improved style
|
||||
- Added controls in bottom right which indicate where you can navigate
|
||||
- Reveal views in iteratively by giving them the .fragment class
|
||||
- Code sample syntax highlighting thanks to [highlight.js](http://softwaremaniacs.org/soft/highlight/en/description/)
|
||||
- Initialization options (toggling controls, toggling rolling links, transition theme)
|
||||
|
||||
#### 0.3
|
||||
|
||||
- Added licensing terms
|
||||
- Fixed broken links on touch devices
|
||||
|
||||
#### 0.2
|
||||
|
||||
- Refactored code and added inline documentation
|
||||
- Slides now have unique URL's
|
||||
- A basic API to invoke navigation was added
|
||||
|
||||
#### 0.1
|
||||
|
||||
- First release
|
||||
- Transitions and a white theme
|
||||
|
||||
## License
|
||||
|
||||
MIT licensed
|
||||
|
||||
Copyright (C) 2012 Hakim El Hattab, http://hakim.se
|
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 414 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 8.0 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 131 KiB |
After Width: | Height: | Size: 51 KiB |
|
@ -0,0 +1,159 @@
|
|||
|
||||
/* Default Print Stylesheet Template
|
||||
by Rob Glazebrook of CSSnewbie.com
|
||||
Last Updated: June 4, 2008
|
||||
|
||||
Feel free (nay, compelled) to edit, append, and
|
||||
manipulate this file as you see fit. */
|
||||
|
||||
|
||||
/* SECTION 1: Set default width, margin, float, and
|
||||
background. This prevents elements from extending
|
||||
beyond the edge of the printed page, and prevents
|
||||
unnecessary background images from printing */
|
||||
* {
|
||||
-webkit-print-color-adjust: exact;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: 22pt;
|
||||
width: auto;
|
||||
height: auto;
|
||||
border: 0;
|
||||
margin: 0 5%;
|
||||
padding: 0;
|
||||
float: none !important;
|
||||
overflow: visible;
|
||||
background: #333;
|
||||
}
|
||||
|
||||
html {
|
||||
width: auto;
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/* SECTION 2: Remove any elements not needed in print.
|
||||
This would include navigation, ads, sidebars, etc. */
|
||||
.nestedarrow,
|
||||
.controls a,
|
||||
.reveal .progress,
|
||||
.reveal.overview,
|
||||
.fork-reveal,
|
||||
.share-reveal,
|
||||
.state-background {
|
||||
display:none;
|
||||
}
|
||||
|
||||
/* SECTION 3: Set body font face, size, and color.
|
||||
Consider using a serif font for readability. */
|
||||
body, p, td, li, div, a {
|
||||
font-size: 22pt;
|
||||
}
|
||||
|
||||
/* SECTION 4: Set heading font face, sizes, and color.
|
||||
Diffrentiate your headings from your body text.
|
||||
Perhaps use a large sans-serif for distinction. */
|
||||
h1,h2,h3,h4,h5,h6 {
|
||||
text-shadow: 0 0 0 #000 !important;
|
||||
}
|
||||
|
||||
/* SECTION 5: Make hyperlinks more usable.
|
||||
Ensure links are underlined, and consider appending
|
||||
the URL to the end of the link for usability. */
|
||||
a:link,
|
||||
a:visited {
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
|
||||
/* SECTION 6: more reveal.js specific additions by @skypanther */
|
||||
ul, ol, div, p {
|
||||
visibility: visible;
|
||||
position: static;
|
||||
width: auto;
|
||||
height: auto;
|
||||
display: block;
|
||||
overflow: visible;
|
||||
margin: auto;
|
||||
}
|
||||
.reveal .slides {
|
||||
position: static;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
|
||||
left: auto;
|
||||
top: auto;
|
||||
margin-left: auto;
|
||||
margin-top: auto;
|
||||
padding: auto;
|
||||
|
||||
overflow: visible;
|
||||
display: block;
|
||||
|
||||
text-align: center;
|
||||
-webkit-perspective: none;
|
||||
-moz-perspective: none;
|
||||
-ms-perspective: none;
|
||||
perspective: none;
|
||||
|
||||
-webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */
|
||||
-moz-perspective-origin: 50% 50%;
|
||||
-ms-perspective-origin: 50% 50%;
|
||||
perspective-origin: 50% 50%;
|
||||
}
|
||||
.reveal .slides>section, .reveal .slides>section>section,
|
||||
.reveal .slides>section.past, .reveal .slides>section.future,
|
||||
.reveal.linear .slides>section, .reveal.linear .slides>section>section,
|
||||
.reveal.linear .slides>section.past, .reveal.linear .slides>section.future {
|
||||
|
||||
visibility: visible;
|
||||
position: static;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
min-height: initial;
|
||||
display: block;
|
||||
overflow: visible;
|
||||
|
||||
left: 0%;
|
||||
top: 0%;
|
||||
margin-left: 0px;
|
||||
margin-top: 50px;
|
||||
padding: 20px 0px;
|
||||
|
||||
opacity: 1;
|
||||
|
||||
-webkit-transform-style: flat;
|
||||
-moz-transform-style: flat;
|
||||
-ms-transform-style: flat;
|
||||
transform-style: flat;
|
||||
|
||||
-webkit-transform: none;
|
||||
-moz-transform: none;
|
||||
-ms-transform: none;
|
||||
transform: none;
|
||||
}
|
||||
.reveal section {
|
||||
page-break-after: always !important;
|
||||
display: block !important;
|
||||
}
|
||||
.reveal section.stack {
|
||||
margin: 0px !important;
|
||||
padding: 0px !important;
|
||||
page-break-after: avoid !important;
|
||||
}
|
||||
.reveal section .fragment {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.reveal img {
|
||||
box-shadow: none;
|
||||
}
|
||||
.reveal .roll {
|
||||
overflow: visible;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
.reveal small a {
|
||||
font-size: 16pt !important;
|
||||
}
|
|
@ -0,0 +1,167 @@
|
|||
/* Default Print Stylesheet Template
|
||||
by Rob Glazebrook of CSSnewbie.com
|
||||
Last Updated: June 4, 2008
|
||||
|
||||
Feel free (nay, compelled) to edit, append, and
|
||||
manipulate this file as you see fit. */
|
||||
|
||||
|
||||
/* SECTION 1: Set default width, margin, float, and
|
||||
background. This prevents elements from extending
|
||||
beyond the edge of the printed page, and prevents
|
||||
unnecessary background images from printing */
|
||||
body {
|
||||
background: #fff url(none);
|
||||
font-size: 13pt;
|
||||
width: auto;
|
||||
height: auto;
|
||||
border: 0;
|
||||
margin: 0 5%;
|
||||
padding: 0;
|
||||
float: none !important;
|
||||
overflow: visible;
|
||||
}
|
||||
html {
|
||||
background: #fff;
|
||||
width: auto;
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/* SECTION 2: Remove any elements not needed in print.
|
||||
This would include navigation, ads, sidebars, etc. */
|
||||
.nestedarrow,
|
||||
.controls a,
|
||||
.reveal .progress span,
|
||||
.reveal.overview {
|
||||
display:none;
|
||||
}
|
||||
|
||||
/* SECTION 3: Set body font face, size, and color.
|
||||
Consider using a serif font for readability. */
|
||||
body, p, td, li, div, a {
|
||||
font-size: 13pt;
|
||||
font-family: Georgia, "Times New Roman", Times, serif !important;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/* SECTION 4: Set heading font face, sizes, and color.
|
||||
Diffrentiate your headings from your body text.
|
||||
Perhaps use a large sans-serif for distinction. */
|
||||
h1,h2,h3,h4,h5,h6 {
|
||||
color: #000!important;
|
||||
height: auto;
|
||||
line-height: normal;
|
||||
font-family: Georgia, "Times New Roman", Times, serif !important;
|
||||
text-shadow: 0 0 0 #000 !important;
|
||||
text-align: left;
|
||||
letter-spacing: normal;
|
||||
}
|
||||
/* Need to reduce the size of the fonts for printing */
|
||||
h1 { font-size: 26pt !important; }
|
||||
h2 { font-size: 22pt !important; }
|
||||
h3 { font-size: 20pt !important; }
|
||||
h4 { font-size: 20pt !important; font-variant: small-caps; }
|
||||
h5 { font-size: 19pt !important; }
|
||||
h6 { font-size: 18pt !important; font-style: italic; }
|
||||
|
||||
/* SECTION 5: Make hyperlinks more usable.
|
||||
Ensure links are underlined, and consider appending
|
||||
the URL to the end of the link for usability. */
|
||||
a:link,
|
||||
a:visited {
|
||||
color: #000 !important;
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
}
|
||||
.reveal a:link:after,
|
||||
.reveal a:visited:after {
|
||||
content: " (" attr(href) ") ";
|
||||
color: #222 !important;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
|
||||
/* SECTION 6: more reveal.js specific additions by @skypanther */
|
||||
ul, ol, div, p {
|
||||
visibility: visible;
|
||||
position: static;
|
||||
width: auto;
|
||||
height: auto;
|
||||
display: block;
|
||||
overflow: visible;
|
||||
margin: auto;
|
||||
text-align: left !important;
|
||||
}
|
||||
.reveal .slides {
|
||||
position: static;
|
||||
width: auto;
|
||||
height: auto;
|
||||
|
||||
left: auto;
|
||||
top: auto;
|
||||
margin-left: auto;
|
||||
margin-top: auto;
|
||||
padding: auto;
|
||||
|
||||
overflow: visible;
|
||||
display: block;
|
||||
|
||||
text-align: center;
|
||||
-webkit-perspective: none;
|
||||
-moz-perspective: none;
|
||||
-ms-perspective: none;
|
||||
perspective: none;
|
||||
|
||||
-webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */
|
||||
-moz-perspective-origin: 50% 50%;
|
||||
-ms-perspective-origin: 50% 50%;
|
||||
perspective-origin: 50% 50%;
|
||||
}
|
||||
.reveal .slides>section, .reveal .slides>section>section,
|
||||
.reveal .slides>section.past, .reveal .slides>section.future,
|
||||
.reveal.linear .slides>section, .reveal.linear .slides>section>section,
|
||||
.reveal.linear .slides>section.past, .reveal.linear .slides>section.future {
|
||||
|
||||
visibility: visible;
|
||||
position: static;
|
||||
width: 90%;
|
||||
height: auto;
|
||||
display: block;
|
||||
overflow: visible;
|
||||
|
||||
left: 0%;
|
||||
top: 0%;
|
||||
margin-left: 0px;
|
||||
margin-top: 0px;
|
||||
padding: 20px 0px;
|
||||
|
||||
opacity: 1;
|
||||
|
||||
-webkit-transform-style: flat;
|
||||
-moz-transform-style: flat;
|
||||
-ms-transform-style: flat;
|
||||
transform-style: flat;
|
||||
|
||||
-webkit-transform: none;
|
||||
-moz-transform: none;
|
||||
-ms-transform: none;
|
||||
transform: none;
|
||||
}
|
||||
.reveal section {
|
||||
page-break-after: always !important;
|
||||
display: block !important;
|
||||
}
|
||||
.reveal section.stack {
|
||||
page-break-after: avoid !important;
|
||||
}
|
||||
.reveal section .fragment {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.reveal section img {
|
||||
display: block;
|
||||
margin: 15px 0px;
|
||||
background: rgba(255,255,255,1);
|
||||
border: 1px solid #666;
|
||||
box-shadow: none;
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/* http://meyerweb.com/eric/tools/css/reset/
|
||||
v2.0 | 20110126
|
||||
License: none (public domain)
|
||||
*/
|
||||
|
||||
html, body, div, span, applet, object, iframe,
|
||||
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
||||
a, abbr, acronym, address, big, cite, code,
|
||||
del, dfn, em, img, ins, kbd, q, s, samp,
|
||||
small, strike, strong, sub, sup, tt, var,
|
||||
b, u, i, center,
|
||||
dl, dt, dd, ol, ul, li,
|
||||
fieldset, form, label, legend,
|
||||
table, caption, tbody, tfoot, thead, tr, th, td,
|
||||
article, aside, canvas, details, embed,
|
||||
figure, figcaption, footer, header, hgroup,
|
||||
menu, nav, output, ruby, section, summary,
|
||||
time, mark, audio, video {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
font-size: 100%;
|
||||
font: inherit;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
/* HTML5 display-role reset for older browsers */
|
||||
article, aside, details, figcaption, figure,
|
||||
footer, header, hgroup, menu, nav, section {
|
||||
display: block;
|
||||
}
|
||||
body {
|
||||
line-height: 1;
|
||||
}
|
||||
ol, ul {
|
||||
list-style: none;
|
||||
}
|
||||
blockquote, q {
|
||||
quotes: none;
|
||||
}
|
||||
blockquote:before, blockquote:after,
|
||||
q:before, q:after {
|
||||
content: '';
|
||||
content: none;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
|
||||
/* HTML5BP:
|
||||
These selection declarations have to be separate.
|
||||
No text-shadow: twitter.com/miketaylr/status/12228805301
|
||||
Also: hot pink. */
|
||||
::-moz-selection{ background: #FF5E99; color:#fff; text-shadow: none; }
|
||||
::selection { background:#FF5E99; color:#fff; text-shadow: none; }
|
||||
|
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 69 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 134 KiB |
After Width: | Height: | Size: 13 KiB |
|
@ -0,0 +1,346 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>UX & Usability Designing</title>
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
<link href='http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
|
||||
<!-- <link rel="stylesheet" href="css/reset.css">-->
|
||||
<link rel="stylesheet" href="css/main.css">
|
||||
<script>
|
||||
// If the query includes 'print-pdf' we'll use the PDF print sheet
|
||||
document.write( '<link rel="stylesheet" href="css/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
|
||||
</script>
|
||||
<body>
|
||||
|
||||
<div class="reveal">
|
||||
|
||||
<!-- Used to fade in a background when a specific slide state is reached -->
|
||||
<div class="state-background"></div>
|
||||
|
||||
<!-- Any section element inside of this container is displayed as a slide -->
|
||||
<div class="slides">
|
||||
<section>
|
||||
<h1>UX & Usability Designing</h1>
|
||||
<h3 class="inverted">- Abhay Rana (me@captnemo.in)</h3>
|
||||
<script>
|
||||
// Delicously hacky. Look away.
|
||||
if( navigator.userAgent.match( /(iPhone|iPad|iPod|Android)/i ) ) document.write( '<p style="color: rgba(0,0,0,0.3); text-shadow: none;">('+'Tap to navigate'+')</p>' );
|
||||
</script>
|
||||
</section>
|
||||
<section>
|
||||
<section>
|
||||
<h2>Types Of Designing</h2>
|
||||
<h3>Informational Design</h3>
|
||||
<ul>
|
||||
<li>Posters</li>
|
||||
<li>Notices</li>
|
||||
<li>Content Websites</li>
|
||||
</ul>
|
||||
<br><br>
|
||||
<h3>Interactive Design</h3>
|
||||
<ul>
|
||||
<li>User-oriented</li>
|
||||
<li>Interactive</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Informational Design</h2>
|
||||
<img src="chrome.jpg">
|
||||
<br><small>http://www.flickr.com/photos/ell-r-brown/5308119110/sizes/m/</small>
|
||||
</section>
|
||||
<Section>
|
||||
<h2>Interactive Design</h2>
|
||||
<img src="hangout.png">
|
||||
<br><small>https://plus.google.com/hangouts/</small>
|
||||
|
||||
</section>
|
||||
<section>
|
||||
<h2>Youtube Leanback</h2>
|
||||
<img src="yt-2.png"><br>
|
||||
<small>http://www.youtube.com/leanback</small>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Postbox App</h2>
|
||||
<img src="postbox.png"><br>
|
||||
<small>http://www.postbox-inc.com/</small>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<section>
|
||||
<h2 style="margin-top:-100px">Why do we need this?</h2>
|
||||
<img src="amazon-1.jpg" />
|
||||
<img src="amazon-3.jpg" />
|
||||
<img src="amazon-4.jpg" />
|
||||
<img src="amazon-6.jpg" />
|
||||
<img src="amazon-7.png" />
|
||||
<br><small>Amazon circa 2001, 2003, 2005, 2007, 2011 via archive.org</small>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Multi-Level Menus</h2>
|
||||
<img src="amazon-5.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2>Flipkart.com</h2>
|
||||
<img src="flipkart-1.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2>Indiaplaza.in</h2>
|
||||
<img src="indiaplaza.in.jpg">
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section>
|
||||
<h2>Interface Oriented Designing</h2>
|
||||
<p>Some examples of interfaces ? </p>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Touch Based Interfaces</h2>
|
||||
<img src="ios-1.jpg"><br>
|
||||
<small>http://itunes.apple.com/gb/app/dvd-profiler-for-ios/id408455612?mt=8</small>
|
||||
</section>
|
||||
<section>
|
||||
<h3>Touchable Websites</h2>
|
||||
<img src="flipkart-2.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h3>Command Line ?</h2>
|
||||
<img src="cmd.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h3>Voice Activated</h3>
|
||||
<img src="siri.jpg"><br><small>http://goo.gl/4vFql</small>
|
||||
</section>
|
||||
<section>
|
||||
<h3>Gesture Based</h3>
|
||||
<img src="kinect.jpg">
|
||||
<br><small>http://gamerant.com/microsoft-kinect-reviews-guide-benk-51320/</small>
|
||||
</section>
|
||||
<section>
|
||||
<h3>Dream worthy Interfaces</h3>
|
||||
<img src="avengers.png">
|
||||
<br><small>Avengers, 2012 - Warner Bros</small>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<section>
|
||||
<h2>Good Interfaces</h2>
|
||||
<p>What do they all have in common?</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2>User-centered</h2>
|
||||
<img src="google.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2>Easily Learnable</h2>
|
||||
<img src="paint.jpg">
|
||||
<img src="fb.jpg">
|
||||
<img src="yt.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2>Fits in the environment</h2>
|
||||
<ul>
|
||||
<li>Angry Birds in <b>Windows</b></li>
|
||||
<li>Dreamweaver in <b>iPhones</b></li>
|
||||
<li>Windows on a <b>DJ Set</b></li>
|
||||
<li>Temple Run using your <b>Mouse</b></li>
|
||||
<li>Using Mouse to control a robot</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>And the gist is...</h2>
|
||||
</section>
|
||||
<section>
|
||||
<h2 style="font-size:269px">DON'T MAKE ME THINK</h2>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section>
|
||||
<h2>Design Paradigms</h2>
|
||||
<h4>Don't make me learn</h4>
|
||||
<ul>
|
||||
<li>Use existing design ideas</li>
|
||||
<li>Don't re-invent the wheel</li>
|
||||
<li>Design to learn quickly</li>
|
||||
<li>Minimum Effort</li>
|
||||
<li>Users are Lazy</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Tabs</h2>
|
||||
<img src="tabs.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2>Sensible Defaults</h2>
|
||||
<p>Examples: </p>
|
||||
<ul>
|
||||
<li>Choose default country</li>
|
||||
<li>Choose most-used price range</li>
|
||||
<li>Show popular content</li>
|
||||
<li>Reduce Design induced Frustration</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Navigation Heirarchy</h2>
|
||||
<img src="menus.png">
|
||||
<p>Give your users an idea of what is important</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Eye Tracking</h2>
|
||||
<img src="eye.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2>Using Icons</h2>
|
||||
<ul>
|
||||
<li>Bad Icons: <br><img src="gmail.jpg"></li>
|
||||
<li>Fine Icons/Buttons: <br><img src="gmail-2.jpg"></li>
|
||||
<li>More Bad Icons: <br><img src="idm.jpg"></li>
|
||||
<li>Good: <br><img src="wmp.jpg"></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Call To Action</h2>
|
||||
<img src="gmail-field.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2>More CTA</h2>
|
||||
<img src="gs.png">
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<section>
|
||||
<h2>Design Workflows</h2>
|
||||
<blockquote>Produce at least 3 alternatives for every design decision - <a href="https://news.ycombinator.com/item?id=4312953">msuther</a></blockquote>
|
||||
</section>
|
||||
<section>
|
||||
<h2>SketchFlow</h2>
|
||||
<img src="sketch.jpg">
|
||||
<p>Go through every screen & its relation with other screens</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Mockups</h2>
|
||||
<img src="mockup.jpg">
|
||||
<p>Sketches, Wireframes, Mockups, Pixels, Shots</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Think Over every interaction</h2>
|
||||
<p>Is this the easiest, most obvious interaction that the user would choose?</p>
|
||||
<p>Can I offer an alternative to this interaction?</p>
|
||||
<p>Don't miss out the power users</p>
|
||||
<p>Don't try to do everything, do ONE THING WELL </p>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<section>
|
||||
<h2>References</h2>
|
||||
<p>This is just a small sample of what is out there in the web</p>
|
||||
<h1>Doing><br>Learning><br>Reading</h1>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Don't Make Me Think - Steve Krug</h2>
|
||||
<img src="dmmt.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2>GUI Bloopers</h2>
|
||||
<img src="blooper-1.jpg">
|
||||
<img src="blooper.jpg">
|
||||
<img src="blooper-2.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2><a href="http://littlebigdetails.com"> Little Big Details </a></h2>
|
||||
<img src="lbd.jpg">
|
||||
<img src="lbd2.png">
|
||||
<img src="lbd3.png">
|
||||
</section>
|
||||
<section>
|
||||
<h2><a href="http://usabilityhell.com/">Usability Hell</a></h2>
|
||||
<img src="london.png">
|
||||
</section>
|
||||
<section>
|
||||
<h2><a href="http://ux.stackexchange.com"></a>ux.stackexchange</h2>
|
||||
<img src="ux.jpg">
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<section><h2>Questions?</h2></section>
|
||||
<section>
|
||||
<h1>Think</h1>
|
||||
<h3>about how would you improve</h3>
|
||||
<ul>
|
||||
<li>A coffee machine</li>
|
||||
<li>A power socket</li>
|
||||
<li>google.com</li>
|
||||
<li>muzi</li>
|
||||
<li>anything really...</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Thanks</h2>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<!-- The navigational controls UI -->
|
||||
<aside class="controls">
|
||||
<a class="left" href="#">◄</a>
|
||||
<a class="right" href="#">►</a>
|
||||
<a class="up" href="#">▲</a>
|
||||
<a class="down" href="#">▼</a>
|
||||
</aside>
|
||||
|
||||
<!-- Presentation progress bar -->
|
||||
<div class="progress"><span></span></div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="lib/js/head.min.js"></script>
|
||||
|
||||
<script>
|
||||
// Load reveal.js as well as a classList polyfill if needed
|
||||
head.js( !document.body.classList ? 'lib/js/classList.js' : null )
|
||||
.js( 'js/reveal.js', function() {
|
||||
|
||||
// Parse the query string into a key/value object
|
||||
var query = {};
|
||||
location.search.replace( /[A-Z0-9]+?=(\w*)/gi, function(a) {
|
||||
query[ a.split( '=' ).shift() ] = a.split( '=' ).pop();
|
||||
} );
|
||||
|
||||
// Fires when a slide with data-state=customevent is activated
|
||||
Reveal.addEventListener( 'customevent', function() {
|
||||
console.log( '"customevent" has fired' );
|
||||
} );
|
||||
|
||||
// Fires each time a new slide is activated
|
||||
Reveal.addEventListener( 'slidechanged', function( event ) {
|
||||
// event.previousSlide, event.currentSlide, event.indexh, event.indexv
|
||||
} );
|
||||
|
||||
// Full list of configuration options available here:
|
||||
// https://github.com/hakimel/reveal.js#configuration
|
||||
Reveal.initialize({
|
||||
controls: true,
|
||||
progress: true,
|
||||
history: true,
|
||||
|
||||
theme: query.theme || 'default', // default/neon/beige
|
||||
transition: query.transition || 'default' // default/cube/page/concave/linear(2d)
|
||||
});
|
||||
|
||||
} );
|
||||
|
||||
// If we're runnning the notes server we need to include some additional JS
|
||||
// TODO Is there a better way to determine if we're running the notes server?
|
||||
if( window.location.host === 'localhost:1947' ) {
|
||||
head.js( 'socket.io/socket.io.js', 'plugin/speakernotes/client.js' );
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,347 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>UX & Usability Designing</title>
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
<link href='http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
|
||||
<!-- <link rel="stylesheet" href="css/reset.css">-->
|
||||
<link rel="stylesheet" href="css/main.css">
|
||||
<link rel="stylesheet" href="css/print.css" type="text/css" media="print">
|
||||
<script>
|
||||
// If the query includes 'print-pdf' we'll use the PDF print sheet
|
||||
document.write( '<link rel="stylesheet" href="css/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
|
||||
</script>
|
||||
<body>
|
||||
|
||||
<div class="reveal">
|
||||
|
||||
<!-- Used to fade in a background when a specific slide state is reached -->
|
||||
<div class="state-background"></div>
|
||||
|
||||
<!-- Any section element inside of this container is displayed as a slide -->
|
||||
<div class="slides">
|
||||
<section>
|
||||
<h1>UX & Usability Designing</h1>
|
||||
<h3 class="inverted">- Abhay Rana (me@captnemo.in)</h3>
|
||||
<script>
|
||||
// Delicously hacky. Look away.
|
||||
if( navigator.userAgent.match( /(iPhone|iPad|iPod|Android)/i ) ) document.write( '<p style="color: rgba(0,0,0,0.3); text-shadow: none;">('+'Tap to navigate'+')</p>' );
|
||||
</script>
|
||||
</section>
|
||||
<section>
|
||||
<section>
|
||||
<h2>Types Of Designing</h2>
|
||||
<h3>Informational Design</h3>
|
||||
<ul>
|
||||
<li>Posters</li>
|
||||
<li>Notices</li>
|
||||
<li>Content Websites</li>
|
||||
</ul>
|
||||
<br><br>
|
||||
<h3>Interactive Design</h3>
|
||||
<ul>
|
||||
<li>User-oriented</li>
|
||||
<li>Interactive</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Informational Design</h2>
|
||||
<img src="chrome.jpg">
|
||||
<br><small>http://www.flickr.com/photos/ell-r-brown/5308119110/sizes/m/</small>
|
||||
</section>
|
||||
<Section>
|
||||
<h2>Interactive Design</h2>
|
||||
<img src="hangout.png">
|
||||
<br><small>https://plus.google.com/hangouts/</small>
|
||||
|
||||
</section>
|
||||
<section>
|
||||
<h2>Youtube Leanback</h2>
|
||||
<img src="yt-2.png"><br>
|
||||
<small>http://www.youtube.com/leanback</small>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Postbox App</h2>
|
||||
<img src="postbox.png"><br>
|
||||
<small>http://www.postbox-inc.com/</small>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<section>
|
||||
<h2 style="margin-top:-100px">Why do we need this?</h2>
|
||||
<img src="amazon-1.jpg" />
|
||||
<img src="amazon-3.jpg" />
|
||||
<img src="amazon-4.jpg" />
|
||||
<img src="amazon-6.jpg" />
|
||||
<img src="amazon-7.png" />
|
||||
<br><small>Amazon circa 2001, 2003, 2005, 2007, 2011 via archive.org</small>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Multi-Level Menus</h2>
|
||||
<img src="amazon-5.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2>Flipkart.com</h2>
|
||||
<img src="flipkart-1.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2>Indiaplaza.in</h2>
|
||||
<img src="indiaplaza.in.jpg">
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section>
|
||||
<h2>Interface Oriented Designing</h2>
|
||||
<p>Some examples of interfaces ? </p>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Touch Based Interfaces</h2>
|
||||
<img src="ios-1.jpg"><br>
|
||||
<small>http://itunes.apple.com/gb/app/dvd-profiler-for-ios/id408455612?mt=8</small>
|
||||
</section>
|
||||
<section>
|
||||
<h3>Touchable Websites</h2>
|
||||
<img src="flipkart-2.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h3>Command Line ?</h2>
|
||||
<img src="cmd.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h3>Voice Activated</h3>
|
||||
<img src="siri.jpg"><br><small>http://goo.gl/4vFql</small>
|
||||
</section>
|
||||
<section>
|
||||
<h3>Gesture Based</h3>
|
||||
<img src="kinect.jpg">
|
||||
<br><small>http://gamerant.com/microsoft-kinect-reviews-guide-benk-51320/</small>
|
||||
</section>
|
||||
<section>
|
||||
<h3>Dream worthy Interfaces</h3>
|
||||
<img src="avengers.png">
|
||||
<br><small>Avengers, 2012 - Warner Bros</small>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<section>
|
||||
<h2>Good Interfaces</h2>
|
||||
<p>What do they all have in common?</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2>User-centered</h2>
|
||||
<img src="google.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2>Easily Learnable</h2>
|
||||
<img src="paint.jpg">
|
||||
<img src="fb.jpg">
|
||||
<img src="yt.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2>Fits in the environment</h2>
|
||||
<ul>
|
||||
<li>Angry Birds in <b>Windows</b></li>
|
||||
<li>Dreamweaver in <b>iPhones</b></li>
|
||||
<li>Windows on a <b>DJ Set</b></li>
|
||||
<li>Temple Run using your <b>Mouse</b></li>
|
||||
<li>Using Mouse to control a robot</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>And the gist is...</h2>
|
||||
</section>
|
||||
<section>
|
||||
<h2 style="font-size:269px">DON'T MAKE ME THINK</h2>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<section>
|
||||
<h2>Design Paradigms</h2>
|
||||
<h4>Don't make me learn</h4>
|
||||
<ul>
|
||||
<li>Use existing design ideas</li>
|
||||
<li>Don't re-invent the wheel</li>
|
||||
<li>Design to learn quickly</li>
|
||||
<li>Minimum Effort</li>
|
||||
<li>Users are Lazy</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Tabs</h2>
|
||||
<img src="tabs.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2>Sensible Defaults</h2>
|
||||
<p>Examples: </p>
|
||||
<ul>
|
||||
<li>Choose default country</li>
|
||||
<li>Choose most-used price range</li>
|
||||
<li>Show popular content</li>
|
||||
<li>Reduce Design induced Frustration</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Navigation Heirarchy</h2>
|
||||
<img src="menus.png">
|
||||
<p>Give your users an idea of what is important</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Eye Tracking</h2>
|
||||
<img src="eye.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2>Using Icons</h2>
|
||||
<ul>
|
||||
<li>Bad Icons: <br><img src="gmail.jpg"></li>
|
||||
<li>Fine Icons/Buttons: <br><img src="gmail-2.jpg"></li>
|
||||
<li>More Bad Icons: <br><img src="idm.jpg"></li>
|
||||
<li>Good: <br><img src="wmp.jpg"></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Call To Action</h2>
|
||||
<img src="gmail-field.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2>More CTA</h2>
|
||||
<img src="gs.png">
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<section>
|
||||
<h2>Design Workflows</h2>
|
||||
<blockquote>Produce at least 3 alternatives for every design decision - <a href="https://news.ycombinator.com/item?id=4312953">msuther</a></blockquote>
|
||||
</section>
|
||||
<section>
|
||||
<h2>SketchFlow</h2>
|
||||
<img src="sketch.jpg">
|
||||
<p>Go through every screen & its relation with other screens</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Mockups</h2>
|
||||
<img src="mockup.jpg">
|
||||
<p>Sketches, Wireframes, Mockups, Pixels, Shots</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Think Over every interaction</h2>
|
||||
<p>Is this the easiest, most obvious interaction that the user would choose?</p>
|
||||
<p>Can I offer an alternative to this interaction?</p>
|
||||
<p>Don't miss out the power users</p>
|
||||
<p>Don't try to do everything, do ONE THING WELL </p>
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<section>
|
||||
<h2>References</h2>
|
||||
<p>This is just a small sample of what is out there in the web</p>
|
||||
<h1>Doing><br>Learning><br>Reading</h1>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Don't Make Me Think - Steve Krug</h2>
|
||||
<img src="dmmt.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2>GUI Bloopers</h2>
|
||||
<img src="blooper-1.jpg">
|
||||
<img src="blooper.jpg">
|
||||
<img src="blooper-2.jpg">
|
||||
</section>
|
||||
<section>
|
||||
<h2><a href="http://littlebigdetails.com"> Little Big Details </a></h2>
|
||||
<img src="lbd.jpg">
|
||||
<img src="lbd2.png">
|
||||
<img src="lbd3.png">
|
||||
</section>
|
||||
<section>
|
||||
<h2><a href="http://usabilityhell.com/">Usability Hell</a></h2>
|
||||
<img src="london.png">
|
||||
</section>
|
||||
<section>
|
||||
<h2><a href="http://ux.stackexchange.com"></a>ux.stackexchange</h2>
|
||||
<img src="ux.jpg">
|
||||
</section>
|
||||
</section>
|
||||
<section>
|
||||
<section><h2>Questions?</h2></section>
|
||||
<section>
|
||||
<h1>Think</h1>
|
||||
<h3>about how would you improve</h3>
|
||||
<ul>
|
||||
<li>A coffee machine</li>
|
||||
<li>A power socket</li>
|
||||
<li>google.com</li>
|
||||
<li>muzi</li>
|
||||
<li>anything really...</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h2>Thanks</h2>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<!-- The navigational controls UI -->
|
||||
<aside class="controls">
|
||||
<a class="left" href="#">◄</a>
|
||||
<a class="right" href="#">►</a>
|
||||
<a class="up" href="#">▲</a>
|
||||
<a class="down" href="#">▼</a>
|
||||
</aside>
|
||||
|
||||
<!-- Presentation progress bar -->
|
||||
<div class="progress"><span></span></div>
|
||||
|
||||
</div>
|
||||
|
||||
<script src="lib/js/head.min.js"></script>
|
||||
|
||||
<script>
|
||||
// Load reveal.js as well as a classList polyfill if needed
|
||||
head.js( !document.body.classList ? 'lib/js/classList.js' : null )
|
||||
.js( 'js/reveal.js', function() {
|
||||
|
||||
// Parse the query string into a key/value object
|
||||
var query = {};
|
||||
location.search.replace( /[A-Z0-9]+?=(\w*)/gi, function(a) {
|
||||
query[ a.split( '=' ).shift() ] = a.split( '=' ).pop();
|
||||
} );
|
||||
|
||||
// Fires when a slide with data-state=customevent is activated
|
||||
Reveal.addEventListener( 'customevent', function() {
|
||||
console.log( '"customevent" has fired' );
|
||||
} );
|
||||
|
||||
// Fires each time a new slide is activated
|
||||
Reveal.addEventListener( 'slidechanged', function( event ) {
|
||||
// event.previousSlide, event.currentSlide, event.indexh, event.indexv
|
||||
} );
|
||||
|
||||
// Full list of configuration options available here:
|
||||
// https://github.com/hakimel/reveal.js#configuration
|
||||
Reveal.initialize({
|
||||
controls: true,
|
||||
progress: true,
|
||||
history: true,
|
||||
|
||||
theme: query.theme || 'default', // default/neon/beige
|
||||
transition: query.transition || 'default' // default/cube/page/concave/linear(2d)
|
||||
});
|
||||
|
||||
} );
|
||||
|
||||
// If we're runnning the notes server we need to include some additional JS
|
||||
// TODO Is there a better way to determine if we're running the notes server?
|
||||
if( window.location.host === 'localhost:1947' ) {
|
||||
head.js( 'socket.io/socket.io.js', 'plugin/speakernotes/client.js' );
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 55 KiB |
After Width: | Height: | Size: 95 KiB |
|
@ -0,0 +1,996 @@
|
|||
/*!
|
||||
* reveal.js 1.4
|
||||
* http://lab.hakim.se/reveal-js
|
||||
* MIT licensed
|
||||
*
|
||||
* Copyright (C) 2012 Hakim El Hattab, http://hakim.se
|
||||
*/
|
||||
var Reveal = (function(){
|
||||
|
||||
var HORIZONTAL_SLIDES_SELECTOR = '.reveal .slides>section',
|
||||
VERTICAL_SLIDES_SELECTOR = '.reveal .slides>section.present>section',
|
||||
|
||||
IS_TOUCH_DEVICE = !!( 'ontouchstart' in window ),
|
||||
|
||||
// The horizontal and verical index of the currently active slide
|
||||
indexh = 0,
|
||||
indexv = 0,
|
||||
|
||||
// Configurations defaults, can be overridden at initialization time
|
||||
config = {
|
||||
// Display controls in the bottom right corner
|
||||
controls: true,
|
||||
|
||||
// Display a presentation progress bar
|
||||
progress: true,
|
||||
|
||||
// Push each slide change to the browser history
|
||||
history: false,
|
||||
|
||||
// Enable keyboard shortcuts for navigation
|
||||
keyboard: true,
|
||||
|
||||
// Loop the presentation
|
||||
loop: false,
|
||||
|
||||
// Number of milliseconds between automatically proceeding to the
|
||||
// next slide, disabled when set to 0
|
||||
autoSlide: 0,
|
||||
|
||||
// Enable slide navigation via mouse wheel
|
||||
mouseWheel: true,
|
||||
|
||||
// Apply a 3D roll to links on hover
|
||||
rollingLinks: true,
|
||||
|
||||
// UI style
|
||||
theme: 'default', // default/neon/beige
|
||||
|
||||
// Transition style
|
||||
transition: 'default' // default/cube/page/concave/linear(2d)
|
||||
},
|
||||
|
||||
// Slides may hold a data-state attribute which we pick up and apply
|
||||
// as a class to the body. This list contains the combined state of
|
||||
// all current slides.
|
||||
state = [],
|
||||
|
||||
// Cached references to DOM elements
|
||||
dom = {},
|
||||
|
||||
// Detect support for CSS 3D transforms
|
||||
supports3DTransforms = document.body.style['WebkitPerspective'] !== undefined ||
|
||||
document.body.style['MozPerspective'] !== undefined ||
|
||||
document.body.style['msPerspective'] !== undefined ||
|
||||
document.body.style['OPerspective'] !== undefined ||
|
||||
document.body.style['perspective'] !== undefined,
|
||||
|
||||
supports2DTransforms = document.body.style['WebkitTransform'] !== undefined ||
|
||||
document.body.style['MozTransform'] !== undefined ||
|
||||
document.body.style['msTransform'] !== undefined ||
|
||||
document.body.style['OTransform'] !== undefined ||
|
||||
document.body.style['transform'] !== undefined,
|
||||
|
||||
// Detect support for elem.classList
|
||||
supportsClassList = !!document.body.classList;
|
||||
|
||||
// Throttles mouse wheel navigation
|
||||
mouseWheelTimeout = 0,
|
||||
|
||||
// An interval used to automatically move on to the next slide
|
||||
autoSlideTimeout = 0,
|
||||
|
||||
// Delays updates to the URL due to a Chrome thumbnailer bug
|
||||
writeURLTimeout = 0,
|
||||
|
||||
// Holds information about the currently ongoing touch input
|
||||
touch = {
|
||||
startX: 0,
|
||||
startY: 0,
|
||||
startSpan: 0,
|
||||
startCount: 0,
|
||||
handled: false,
|
||||
threshold: 40
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Starts up the slideshow by applying configuration
|
||||
* options and binding various events.
|
||||
*/
|
||||
function initialize( options ) {
|
||||
|
||||
if( ( !supports2DTransforms && !supports3DTransforms ) || !supportsClassList ) {
|
||||
document.body.setAttribute( 'class', 'no-transforms' );
|
||||
|
||||
// If the browser doesn't support core features we won't be
|
||||
// using JavaScript to control the presentation
|
||||
return;
|
||||
}
|
||||
|
||||
// Cache references to DOM elements
|
||||
dom.wrapper = document.querySelector( '.reveal' );
|
||||
dom.progress = document.querySelector( '.reveal .progress' );
|
||||
dom.progressbar = document.querySelector( '.reveal .progress span' );
|
||||
|
||||
if ( config.controls ) {
|
||||
dom.controls = document.querySelector( '.reveal .controls' );
|
||||
dom.controlsLeft = document.querySelector( '.reveal .controls .left' );
|
||||
dom.controlsRight = document.querySelector( '.reveal .controls .right' );
|
||||
dom.controlsUp = document.querySelector( '.reveal .controls .up' );
|
||||
dom.controlsDown = document.querySelector( '.reveal .controls .down' );
|
||||
}
|
||||
|
||||
addEventListeners();
|
||||
|
||||
// Copy options over to our config object
|
||||
extend( config, options );
|
||||
|
||||
// Updates the presentation to match the current configuration values
|
||||
configure();
|
||||
|
||||
// Read the initial hash
|
||||
readURL();
|
||||
|
||||
// Start auto-sliding if it's enabled
|
||||
cueAutoSlide();
|
||||
|
||||
// Set up hiding of the browser address bar
|
||||
if( navigator.userAgent.match( /(iphone|ipod|android)/i ) ) {
|
||||
// Give the page some scrollable overflow
|
||||
document.documentElement.style.overflow = 'scroll';
|
||||
document.body.style.height = '120%';
|
||||
|
||||
// Events that should trigger the address bar to hide
|
||||
window.addEventListener( 'load', removeAddressBar, false );
|
||||
window.addEventListener( 'orientationchange', removeAddressBar, false );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function configure() {
|
||||
if( supports3DTransforms === false ) {
|
||||
// Fall back on the 2D transform theme 'linear'
|
||||
config.transition = 'linear';
|
||||
}
|
||||
|
||||
if( config.controls && dom.controls ) {
|
||||
dom.controls.style.display = 'block';
|
||||
}
|
||||
|
||||
if( config.progress && dom.progress ) {
|
||||
dom.progress.style.display = 'block';
|
||||
}
|
||||
|
||||
if( config.transition !== 'default' ) {
|
||||
dom.wrapper.classList.add( config.transition );
|
||||
}
|
||||
|
||||
if( config.theme !== 'default' ) {
|
||||
document.documentElement.classList.add( 'theme-' + config.theme );
|
||||
}
|
||||
|
||||
if( config.mouseWheel ) {
|
||||
document.addEventListener( 'DOMMouseScroll', onDocumentMouseScroll, false ); // FF
|
||||
document.addEventListener( 'mousewheel', onDocumentMouseScroll, false );
|
||||
}
|
||||
|
||||
if( config.rollingLinks ) {
|
||||
// Add some 3D magic to our anchors
|
||||
linkify();
|
||||
}
|
||||
}
|
||||
|
||||
function addEventListeners() {
|
||||
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
|
||||
document.addEventListener( 'touchmove', onDocumentTouchMove, false );
|
||||
document.addEventListener( 'touchend', onDocumentTouchEnd, false );
|
||||
window.addEventListener( 'hashchange', onWindowHashChange, false );
|
||||
|
||||
if( config.keyboard ) {
|
||||
document.addEventListener( 'keydown', onDocumentKeyDown, false );
|
||||
}
|
||||
|
||||
if ( config.controls && dom.controls ) {
|
||||
dom.controlsLeft.addEventListener( 'click', preventAndForward( navigateLeft ), false );
|
||||
dom.controlsRight.addEventListener( 'click', preventAndForward( navigateRight ), false );
|
||||
dom.controlsUp.addEventListener( 'click', preventAndForward( navigateUp ), false );
|
||||
dom.controlsDown.addEventListener( 'click', preventAndForward( navigateDown ), false );
|
||||
}
|
||||
}
|
||||
|
||||
function removeEventListeners() {
|
||||
document.removeEventListener( 'keydown', onDocumentKeyDown, false );
|
||||
document.removeEventListener( 'touchstart', onDocumentTouchStart, false );
|
||||
document.removeEventListener( 'touchmove', onDocumentTouchMove, false );
|
||||
document.removeEventListener( 'touchend', onDocumentTouchEnd, false );
|
||||
window.removeEventListener( 'hashchange', onWindowHashChange, false );
|
||||
|
||||
if ( config.controls && dom.controls ) {
|
||||
dom.controlsLeft.removeEventListener( 'click', preventAndForward( navigateLeft ), false );
|
||||
dom.controlsRight.removeEventListener( 'click', preventAndForward( navigateRight ), false );
|
||||
dom.controlsUp.removeEventListener( 'click', preventAndForward( navigateUp ), false );
|
||||
dom.controlsDown.removeEventListener( 'click', preventAndForward( navigateDown ), false );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend object a with the properties of object b.
|
||||
* If there's a conflict, object b takes precedence.
|
||||
*/
|
||||
function extend( a, b ) {
|
||||
for( var i in b ) {
|
||||
a[ i ] = b[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Measures the distance in pixels between point a
|
||||
* and point b.
|
||||
*
|
||||
* @param {Object} a point with x/y properties
|
||||
* @param {Object} b point with x/y properties
|
||||
*/
|
||||
function distanceBetween( a, b ) {
|
||||
var dx = a.x - b.x,
|
||||
dy = a.y - b.y;
|
||||
|
||||
return Math.sqrt( dx*dx + dy*dy );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents an events defaults behavior calls the
|
||||
* specified delegate.
|
||||
*
|
||||
* @param {Function} delegate The method to call
|
||||
* after the wrapper has been executed
|
||||
*/
|
||||
function preventAndForward( delegate ) {
|
||||
return function( event ) {
|
||||
event.preventDefault();
|
||||
delegate.call();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes the address bar to hide on mobile devices,
|
||||
* more vertical space ftw.
|
||||
*/
|
||||
function removeAddressBar() {
|
||||
setTimeout( function() {
|
||||
window.scrollTo( 0, 1 );
|
||||
}, 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the document level 'keydown' event.
|
||||
*
|
||||
* @param {Object} event
|
||||
*/
|
||||
function onDocumentKeyDown( event ) {
|
||||
// FFT: Use document.querySelector( ':focus' ) === null
|
||||
// instead of checking contentEditable?
|
||||
|
||||
// Disregard the event if the target is editable or a
|
||||
// modifier is present
|
||||
if ( event.target.contentEditable != 'inherit' || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
|
||||
|
||||
var triggered = false;
|
||||
|
||||
switch( event.keyCode ) {
|
||||
// p, page up
|
||||
case 80: case 33: navigatePrev(); triggered = true; break;
|
||||
// n, page down
|
||||
case 78: case 34: navigateNext(); triggered = true; break;
|
||||
// h, left
|
||||
case 72: case 37: navigateLeft(); triggered = true; break;
|
||||
// l, right
|
||||
case 76: case 39: navigateRight(); triggered = true; break;
|
||||
// k, up
|
||||
case 75: case 38: navigateUp(); triggered = true; break;
|
||||
// j, down
|
||||
case 74: case 40: navigateDown(); triggered = true; break;
|
||||
// home
|
||||
case 36: navigateTo( 0 ); triggered = true; break;
|
||||
// end
|
||||
case 35: navigateTo( Number.MAX_VALUE ); triggered = true; break;
|
||||
// space
|
||||
case 32: overviewIsActive() ? deactivateOverview() : navigateNext(); triggered = true; break;
|
||||
// return
|
||||
case 13: if( overviewIsActive() ) { deactivateOverview(); triggered = true; } break;
|
||||
}
|
||||
|
||||
// If the input resulted in a triggered action we should prevent
|
||||
// the browsers default behavior
|
||||
if( triggered ) {
|
||||
event.preventDefault();
|
||||
}
|
||||
else if ( event.keyCode === 27 && supports3DTransforms ) {
|
||||
toggleOverview();
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
// If auto-sliding is enabled we need to cue up
|
||||
// another timeout
|
||||
cueAutoSlide();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the document level 'touchstart' event,
|
||||
* enables support for swipe and pinch gestures.
|
||||
*/
|
||||
function onDocumentTouchStart( event ) {
|
||||
touch.startX = event.touches[0].clientX;
|
||||
touch.startY = event.touches[0].clientY;
|
||||
touch.startCount = event.touches.length;
|
||||
|
||||
// If there's two touches we need to memorize the distance
|
||||
// between those two points to detect pinching
|
||||
if( event.touches.length === 2 ) {
|
||||
touch.startSpan = distanceBetween( {
|
||||
x: event.touches[1].clientX,
|
||||
y: event.touches[1].clientY
|
||||
}, {
|
||||
x: touch.startX,
|
||||
y: touch.startY
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the document level 'touchmove' event.
|
||||
*/
|
||||
function onDocumentTouchMove( event ) {
|
||||
// Each touch should only trigger one action
|
||||
if( !touch.handled ) {
|
||||
var currentX = event.touches[0].clientX;
|
||||
var currentY = event.touches[0].clientY;
|
||||
|
||||
// If the touch started off with two points and still has
|
||||
// two active touches; test for the pinch gesture
|
||||
if( event.touches.length === 2 && touch.startCount === 2 ) {
|
||||
|
||||
// The current distance in pixels between the two touch points
|
||||
var currentSpan = distanceBetween( {
|
||||
x: event.touches[1].clientX,
|
||||
y: event.touches[1].clientY
|
||||
}, {
|
||||
x: touch.startX,
|
||||
y: touch.startY
|
||||
} );
|
||||
|
||||
// If the span is larger than the desire amount we've got
|
||||
// ourselves a pinch
|
||||
if( Math.abs( touch.startSpan - currentSpan ) > touch.threshold ) {
|
||||
touch.handled = true;
|
||||
|
||||
if( currentSpan < touch.startSpan ) {
|
||||
activateOverview();
|
||||
}
|
||||
else {
|
||||
deactivateOverview();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// There was only one touch point, look for a swipe
|
||||
else if( event.touches.length === 1 ) {
|
||||
var deltaX = currentX - touch.startX,
|
||||
deltaY = currentY - touch.startY;
|
||||
|
||||
if( deltaX > touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
|
||||
touch.handled = true;
|
||||
navigateLeft();
|
||||
}
|
||||
else if( deltaX < -touch.threshold && Math.abs( deltaX ) > Math.abs( deltaY ) ) {
|
||||
touch.handled = true;
|
||||
navigateRight();
|
||||
}
|
||||
else if( deltaY > touch.threshold ) {
|
||||
touch.handled = true;
|
||||
navigateUp();
|
||||
}
|
||||
else if( deltaY < -touch.threshold ) {
|
||||
touch.handled = true;
|
||||
navigateDown();
|
||||
}
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the document level 'touchend' event.
|
||||
*/
|
||||
function onDocumentTouchEnd( event ) {
|
||||
touch.handled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles mouse wheel scrolling, throttled to avoid
|
||||
* skipping multiple slides.
|
||||
*/
|
||||
function onDocumentMouseScroll( event ){
|
||||
clearTimeout( mouseWheelTimeout );
|
||||
|
||||
mouseWheelTimeout = setTimeout( function() {
|
||||
var delta = event.detail || -event.wheelDelta;
|
||||
if( delta > 0 ) {
|
||||
navigateNext();
|
||||
}
|
||||
else {
|
||||
navigatePrev();
|
||||
}
|
||||
}, 100 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the window level 'hashchange' event.
|
||||
*
|
||||
* @param {Object} event
|
||||
*/
|
||||
function onWindowHashChange( event ) {
|
||||
readURL();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap all links in 3D goodness.
|
||||
*/
|
||||
function linkify() {
|
||||
if( supports3DTransforms ) {
|
||||
var nodes = document.querySelectorAll( '.reveal .slides section a:not(.image)' );
|
||||
|
||||
for( var i = 0, len = nodes.length; i < len; i++ ) {
|
||||
var node = nodes[i];
|
||||
|
||||
if( node.textContent && !node.querySelector( 'img' ) && ( !node.className || !node.classList.contains( node, 'roll' ) ) ) {
|
||||
node.classList.add( 'roll' );
|
||||
node.innerHTML = '<span data-title="'+ node.text +'">' + node.innerHTML + '</span>';
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the overview of slides (quick nav) by
|
||||
* scaling down and arranging all slide elements.
|
||||
*
|
||||
* Experimental feature, might be dropped if perf
|
||||
* can't be improved.
|
||||
*/
|
||||
function activateOverview() {
|
||||
|
||||
dom.wrapper.classList.add( 'overview' );
|
||||
|
||||
var horizontalSlides = Array.prototype.slice.call( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ) );
|
||||
|
||||
for( var i = 0, len1 = horizontalSlides.length; i < len1; i++ ) {
|
||||
var hslide = horizontalSlides[i],
|
||||
htransform = 'translateZ(-2500px) translate(' + ( ( i - indexh ) * 105 ) + '%, 0%)';
|
||||
|
||||
hslide.setAttribute( 'data-index-h', i );
|
||||
hslide.style.display = 'block';
|
||||
hslide.style.WebkitTransform = htransform;
|
||||
hslide.style.MozTransform = htransform;
|
||||
hslide.style.msTransform = htransform;
|
||||
hslide.style.OTransform = htransform;
|
||||
hslide.style.transform = htransform;
|
||||
|
||||
if( !hslide.classList.contains( 'stack' ) ) {
|
||||
// Navigate to this slide on click
|
||||
hslide.addEventListener( 'click', onOverviewSlideClicked, true );
|
||||
}
|
||||
|
||||
var verticalSlides = Array.prototype.slice.call( hslide.querySelectorAll( 'section' ) );
|
||||
|
||||
for( var j = 0, len2 = verticalSlides.length; j < len2; j++ ) {
|
||||
var vslide = verticalSlides[j],
|
||||
vtransform = 'translate(0%, ' + ( ( j - indexv ) * 105 ) + '%)';
|
||||
|
||||
vslide.setAttribute( 'data-index-h', i );
|
||||
vslide.setAttribute( 'data-index-v', j );
|
||||
vslide.style.display = 'block';
|
||||
vslide.style.WebkitTransform = vtransform;
|
||||
vslide.style.MozTransform = vtransform;
|
||||
vslide.style.msTransform = vtransform;
|
||||
vslide.style.OTransform = vtransform;
|
||||
vslide.style.transform = vtransform;
|
||||
|
||||
// Navigate to this slide on click
|
||||
vslide.addEventListener( 'click', onOverviewSlideClicked, true );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exits the slide overview and enters the currently
|
||||
* active slide.
|
||||
*/
|
||||
function deactivateOverview() {
|
||||
dom.wrapper.classList.remove( 'overview' );
|
||||
|
||||
var slides = Array.prototype.slice.call( document.querySelectorAll( '.reveal .slides section' ) );
|
||||
|
||||
for( var i = 0, len = slides.length; i < len; i++ ) {
|
||||
var element = slides[i];
|
||||
|
||||
// Resets all transforms to use the external styles
|
||||
element.style.WebkitTransform = '';
|
||||
element.style.MozTransform = '';
|
||||
element.style.msTransform = '';
|
||||
element.style.OTransform = '';
|
||||
element.style.transform = '';
|
||||
|
||||
element.removeEventListener( 'click', onOverviewSlideClicked );
|
||||
}
|
||||
|
||||
slide();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the overview is currently active.
|
||||
*
|
||||
* @return {Boolean} true if the overview is active,
|
||||
* false otherwise
|
||||
*/
|
||||
function overviewIsActive() {
|
||||
return dom.wrapper.classList.contains( 'overview' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when a slide is and we're in the overview.
|
||||
*/
|
||||
function onOverviewSlideClicked( event ) {
|
||||
// TODO There's a bug here where the event listeners are not
|
||||
// removed after deactivating the overview.
|
||||
if( overviewIsActive() ) {
|
||||
event.preventDefault();
|
||||
|
||||
deactivateOverview();
|
||||
|
||||
indexh = this.getAttribute( 'data-index-h' );
|
||||
indexv = this.getAttribute( 'data-index-v' );
|
||||
|
||||
slide();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates one dimension of slides by showing the slide
|
||||
* with the specified index.
|
||||
*
|
||||
* @param {String} selector A CSS selector that will fetch
|
||||
* the group of slides we are working with
|
||||
* @param {Number} index The index of the slide that should be
|
||||
* shown
|
||||
*
|
||||
* @return {Number} The index of the slide that is now shown,
|
||||
* might differ from the passed in index if it was out of
|
||||
* bounds.
|
||||
*/
|
||||
function updateSlides( selector, index ) {
|
||||
|
||||
// Select all slides and convert the NodeList result to
|
||||
// an array
|
||||
var slides = Array.prototype.slice.call( document.querySelectorAll( selector ) ),
|
||||
slidesLength = slides.length;
|
||||
|
||||
if( slidesLength ) {
|
||||
|
||||
// Should the index loop?
|
||||
if( config.loop ) {
|
||||
index %= slidesLength;
|
||||
|
||||
if( index < 0 ) {
|
||||
index = slidesLength + index;
|
||||
}
|
||||
}
|
||||
|
||||
// Enforce max and minimum index bounds
|
||||
index = Math.max( Math.min( index, slidesLength - 1 ), 0 );
|
||||
|
||||
for( var i = 0; i < slidesLength; i++ ) {
|
||||
var slide = slides[i];
|
||||
|
||||
// Optimization; hide all slides that are three or more steps
|
||||
// away from the present slide
|
||||
if( overviewIsActive() === false ) {
|
||||
// The distance loops so that it measures 1 between the first
|
||||
// and last slides
|
||||
var distance = Math.abs( ( index - i ) % ( slidesLength - 3 ) ) || 0;
|
||||
|
||||
slide.style.display = distance > 3 ? 'none' : 'block';
|
||||
}
|
||||
|
||||
slides[i].classList.remove( 'past' );
|
||||
slides[i].classList.remove( 'present' );
|
||||
slides[i].classList.remove( 'future' );
|
||||
|
||||
if( i < index ) {
|
||||
// Any element previous to index is given the 'past' class
|
||||
slides[i].classList.add( 'past' );
|
||||
}
|
||||
else if( i > index ) {
|
||||
// Any element subsequent to index is given the 'future' class
|
||||
slides[i].classList.add( 'future' );
|
||||
}
|
||||
|
||||
// If this element contains vertical slides
|
||||
if( slide.querySelector( 'section' ) ) {
|
||||
slides[i].classList.add( 'stack' );
|
||||
}
|
||||
}
|
||||
|
||||
// Mark the current slide as present
|
||||
slides[index].classList.add( 'present' );
|
||||
|
||||
// If this slide has a state associated with it, add it
|
||||
// onto the current state of the deck
|
||||
var slideState = slides[index].getAttribute( 'data-state' );
|
||||
if( slideState ) {
|
||||
state = state.concat( slideState.split( ' ' ) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Since there are no slides we can't be anywhere beyond the
|
||||
// zeroth index
|
||||
index = 0;
|
||||
}
|
||||
|
||||
return index;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the visual slides to represent the currently
|
||||
* set indices.
|
||||
*/
|
||||
function slide( h, v ) {
|
||||
// Remember the state before this slide
|
||||
var stateBefore = state.concat();
|
||||
|
||||
// Reset the state array
|
||||
state.length = 0;
|
||||
|
||||
var indexhBefore = indexh,
|
||||
indexvBefore = indexv;
|
||||
|
||||
// Activate and transition to the new slide
|
||||
indexh = updateSlides( HORIZONTAL_SLIDES_SELECTOR, h === undefined ? indexh : h );
|
||||
indexv = updateSlides( VERTICAL_SLIDES_SELECTOR, v === undefined ? indexv : v );
|
||||
|
||||
// Apply the new state
|
||||
stateLoop: for( var i = 0, len = state.length; i < len; i++ ) {
|
||||
// Check if this state existed on the previous slide. If it
|
||||
// did, we will avoid adding it repeatedly.
|
||||
for( var j = 0; j < stateBefore.length; j++ ) {
|
||||
if( stateBefore[j] === state[i] ) {
|
||||
stateBefore.splice( j, 1 );
|
||||
continue stateLoop;
|
||||
}
|
||||
}
|
||||
|
||||
document.documentElement.classList.add( state[i] );
|
||||
|
||||
// Dispatch custom event matching the state's name
|
||||
dispatchEvent( state[i] );
|
||||
}
|
||||
|
||||
// Clean up the remaints of the previous state
|
||||
while( stateBefore.length ) {
|
||||
document.documentElement.classList.remove( stateBefore.pop() );
|
||||
}
|
||||
|
||||
// Update progress if enabled
|
||||
if( config.progress && dom.progress ) {
|
||||
dom.progressbar.style.width = ( indexh / ( document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR ).length - 1 ) ) * window.innerWidth + 'px';
|
||||
}
|
||||
|
||||
// Close the overview if it's active
|
||||
if( overviewIsActive() ) {
|
||||
activateOverview();
|
||||
}
|
||||
|
||||
updateControls();
|
||||
|
||||
clearTimeout( writeURLTimeout );
|
||||
writeURLTimeout = setTimeout( writeURL, 1500 );
|
||||
|
||||
// Only fire if the slide index is different from before
|
||||
if( indexh !== indexhBefore || indexv !== indexvBefore ) {
|
||||
// Query all horizontal slides in the deck
|
||||
var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
|
||||
|
||||
// Find the previous and current horizontal slides
|
||||
var previousHorizontalSlide = horizontalSlides[ indexhBefore ],
|
||||
currentHorizontalSlide = horizontalSlides[ indexh ];
|
||||
|
||||
// Query all vertical slides inside of the previous and current horizontal slides
|
||||
var previousVerticalSlides = previousHorizontalSlide.querySelectorAll( 'section' );
|
||||
currentVerticalSlides = currentHorizontalSlide.querySelectorAll( 'section' );
|
||||
|
||||
// Dispatch an event notifying observers of the change in slide
|
||||
dispatchEvent( 'slidechanged', {
|
||||
// Include the current indices in the event
|
||||
'indexh': indexh,
|
||||
'indexv': indexv,
|
||||
|
||||
// Passes direct references to the slide HTML elements, attempts to find
|
||||
// a vertical slide and falls back on the horizontal parent
|
||||
'previousSlide': previousVerticalSlides[ indexvBefore ] || previousHorizontalSlide,
|
||||
'currentSlide': currentVerticalSlides[ indexv ] || currentHorizontalSlide
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the state and link pointers of the controls.
|
||||
*/
|
||||
function updateControls() {
|
||||
if ( !config.controls || !dom.controls ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var routes = availableRoutes();
|
||||
|
||||
// Remove the 'enabled' class from all directions
|
||||
[ dom.controlsLeft, dom.controlsRight, dom.controlsUp, dom.controlsDown ].forEach( function( node ) {
|
||||
node.classList.remove( 'enabled' );
|
||||
} )
|
||||
|
||||
if( routes.left ) dom.controlsLeft.classList.add( 'enabled' );
|
||||
if( routes.right ) dom.controlsRight.classList.add( 'enabled' );
|
||||
if( routes.up ) dom.controlsUp.classList.add( 'enabled' );
|
||||
if( routes.down ) dom.controlsDown.classList.add( 'enabled' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine what available routes there are for navigation.
|
||||
*
|
||||
* @return {Object} containing four booleans: left/right/up/down
|
||||
*/
|
||||
function availableRoutes() {
|
||||
var horizontalSlides = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR );
|
||||
var verticalSlides = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR );
|
||||
|
||||
return {
|
||||
left: indexh > 0,
|
||||
right: indexh < horizontalSlides.length - 1,
|
||||
up: indexv > 0,
|
||||
down: indexv < verticalSlides.length - 1
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the current URL (hash) and navigates accordingly.
|
||||
*/
|
||||
function readURL() {
|
||||
// Break the hash down to separate components
|
||||
var bits = window.location.hash.slice(2).split('/');
|
||||
|
||||
// Read the index components of the hash
|
||||
var h = parseInt( bits[0] ) || 0 ;
|
||||
var v = parseInt( bits[1] ) || 0 ;
|
||||
|
||||
navigateTo( h, v );
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the page URL (hash) to reflect the current
|
||||
* state.
|
||||
*/
|
||||
function writeURL() {
|
||||
if( config.history ) {
|
||||
var url = '/';
|
||||
|
||||
// Only include the minimum possible number of components in
|
||||
// the URL
|
||||
if( indexh > 0 || indexv > 0 ) url += indexh;
|
||||
if( indexv > 0 ) url += '/' + indexv;
|
||||
|
||||
window.location.hash = url;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches an event of the specified type from the
|
||||
* reveal DOM element.
|
||||
*/
|
||||
function dispatchEvent( type, properties ) {
|
||||
var event = document.createEvent( "HTMLEvents", 1, 2 );
|
||||
event.initEvent( type, true, true );
|
||||
extend( event, properties );
|
||||
dom.wrapper.dispatchEvent( event );
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate to the next slide fragment.
|
||||
*
|
||||
* @return {Boolean} true if there was a next fragment,
|
||||
* false otherwise
|
||||
*/
|
||||
function nextFragment() {
|
||||
// Vertical slides:
|
||||
if( document.querySelector( VERTICAL_SLIDES_SELECTOR + '.present' ) ) {
|
||||
var verticalFragments = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR + '.present .fragment:not(.visible)' );
|
||||
if( verticalFragments.length ) {
|
||||
verticalFragments[0].classList.add( 'visible' );
|
||||
|
||||
// Notify subscribers of the change
|
||||
dispatchEvent( 'fragmentshown', { fragment: verticalFragments[0] } );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Horizontal slides:
|
||||
else {
|
||||
var horizontalFragments = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR + '.present .fragment:not(.visible)' );
|
||||
if( horizontalFragments.length ) {
|
||||
horizontalFragments[0].classList.add( 'visible' );
|
||||
|
||||
// Notify subscribers of the change
|
||||
dispatchEvent( 'fragmentshown', { fragment: horizontalFragments[0] } );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate to the previous slide fragment.
|
||||
*
|
||||
* @return {Boolean} true if there was a previous fragment,
|
||||
* false otherwise
|
||||
*/
|
||||
function previousFragment() {
|
||||
// Vertical slides:
|
||||
if( document.querySelector( VERTICAL_SLIDES_SELECTOR + '.present' ) ) {
|
||||
var verticalFragments = document.querySelectorAll( VERTICAL_SLIDES_SELECTOR + '.present .fragment.visible' );
|
||||
if( verticalFragments.length ) {
|
||||
verticalFragments[ verticalFragments.length - 1 ].classList.remove( 'visible' );
|
||||
|
||||
// Notify subscribers of the change
|
||||
dispatchEvent( 'fragmenthidden', { fragment: verticalFragments[ verticalFragments.length - 1 ] } );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Horizontal slides:
|
||||
else {
|
||||
var horizontalFragments = document.querySelectorAll( HORIZONTAL_SLIDES_SELECTOR + '.present .fragment.visible' );
|
||||
if( horizontalFragments.length ) {
|
||||
horizontalFragments[ horizontalFragments.length - 1 ].classList.remove( 'visible' );
|
||||
|
||||
// Notify subscribers of the change
|
||||
dispatchEvent( 'fragmenthidden', { fragment: horizontalFragments[ horizontalFragments.length - 1 ] } );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function cueAutoSlide() {
|
||||
clearTimeout( autoSlideTimeout );
|
||||
|
||||
// Cue the next auto-slide if enabled
|
||||
if( config.autoSlide ) {
|
||||
autoSlideTimeout = setTimeout( navigateNext, config.autoSlide );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers a navigation to the specified indices.
|
||||
*
|
||||
* @param {Number} h The horizontal index of the slide to show
|
||||
* @param {Number} v The vertical index of the slide to show
|
||||
*/
|
||||
function navigateTo( h, v ) {
|
||||
slide( h, v );
|
||||
}
|
||||
|
||||
function navigateLeft() {
|
||||
// Prioritize hiding fragments
|
||||
if( overviewIsActive() || previousFragment() === false ) {
|
||||
slide( indexh - 1, 0 );
|
||||
}
|
||||
}
|
||||
function navigateRight() {
|
||||
// Prioritize revealing fragments
|
||||
if( overviewIsActive() || nextFragment() === false ) {
|
||||
slide( indexh + 1, 0 );
|
||||
}
|
||||
}
|
||||
function navigateUp() {
|
||||
// Prioritize hiding fragments
|
||||
if( overviewIsActive() || previousFragment() === false ) {
|
||||
slide( indexh, indexv - 1 );
|
||||
}
|
||||
}
|
||||
function navigateDown() {
|
||||
// Prioritize revealing fragments
|
||||
if( overviewIsActive() || nextFragment() === false ) {
|
||||
slide( indexh, indexv + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigates backwards, prioritized in the following order:
|
||||
* 1) Previous fragment
|
||||
* 2) Previous vertical slide
|
||||
* 3) Previous horizontal slide
|
||||
*/
|
||||
function navigatePrev() {
|
||||
// Prioritize revealing fragments
|
||||
if( previousFragment() === false ) {
|
||||
if( availableRoutes().up ) {
|
||||
navigateUp();
|
||||
}
|
||||
else {
|
||||
// Fetch the previous horizontal slide, if there is one
|
||||
var previousSlide = document.querySelector( '.reveal .slides>section.past:nth-child(' + indexh + ')' );
|
||||
|
||||
if( previousSlide ) {
|
||||
indexv = ( previousSlide.querySelectorAll('section').length + 1 ) || 0;
|
||||
indexh --;
|
||||
slide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as #navigatePrev() but navigates forwards.
|
||||
*/
|
||||
function navigateNext() {
|
||||
// Prioritize revealing fragments
|
||||
if( nextFragment() === false ) {
|
||||
availableRoutes().down ? navigateDown() : navigateRight();
|
||||
}
|
||||
|
||||
// If auto-sliding is enabled we need to cue up
|
||||
// another timeout
|
||||
cueAutoSlide();
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the slide overview mode on and off.
|
||||
*/
|
||||
function toggleOverview() {
|
||||
if( overviewIsActive() ) {
|
||||
deactivateOverview();
|
||||
}
|
||||
else {
|
||||
activateOverview();
|
||||
}
|
||||
}
|
||||
|
||||
// Expose some methods publicly
|
||||
return {
|
||||
initialize: initialize,
|
||||
navigateTo: navigateTo,
|
||||
navigateLeft: navigateLeft,
|
||||
navigateRight: navigateRight,
|
||||
navigateUp: navigateUp,
|
||||
navigateDown: navigateDown,
|
||||
navigatePrev: navigatePrev,
|
||||
navigateNext: navigateNext,
|
||||
toggleOverview: toggleOverview,
|
||||
|
||||
addEventListeners: addEventListeners,
|
||||
removeEventListeners: removeEventListeners,
|
||||
|
||||
// Forward event binding to the reveal DOM element
|
||||
addEventListener: function( type, listener, useCapture ) {
|
||||
( dom.wrapper || document.querySelector( '.reveal' ) ).addEventListener( type, listener, useCapture );
|
||||
},
|
||||
removeEventListener: function( type, listener, useCapture ) {
|
||||
( dom.wrapper || document.querySelector( '.reveal' ) ).removeEventListener( type, listener, useCapture );
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
|
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 63 KiB |
After Width: | Height: | Size: 9.3 KiB |
After Width: | Height: | Size: 8.6 KiB |
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
|
||||
Zenburn style from voldmar.ru (c) Vladimir Epifanov <voldmar@voldmar.ru>
|
||||
based on dark.css by Ivan Sagalaev
|
||||
|
||||
*/
|
||||
|
||||
pre code {
|
||||
display: block; padding: 0.5em;
|
||||
background: #3F3F3F;
|
||||
color: #DCDCDC;
|
||||
}
|
||||
|
||||
pre .keyword,
|
||||
pre .tag,
|
||||
pre .django .tag,
|
||||
pre .django .keyword,
|
||||
pre .css .class,
|
||||
pre .css .id,
|
||||
pre .lisp .title {
|
||||
color: #E3CEAB;
|
||||
}
|
||||
|
||||
pre .django .template_tag,
|
||||
pre .django .variable,
|
||||
pre .django .filter .argument {
|
||||
color: #DCDCDC;
|
||||
}
|
||||
|
||||
pre .number,
|
||||
pre .date {
|
||||
color: #8CD0D3;
|
||||
}
|
||||
|
||||
pre .dos .envvar,
|
||||
pre .dos .stream,
|
||||
pre .variable,
|
||||
pre .apache .sqbracket {
|
||||
color: #EFDCBC;
|
||||
}
|
||||
|
||||
pre .dos .flow,
|
||||
pre .diff .change,
|
||||
pre .python .exception,
|
||||
pre .python .built_in,
|
||||
pre .literal,
|
||||
pre .tex .special {
|
||||
color: #EFEFAF;
|
||||
}
|
||||
|
||||
pre .diff .chunk,
|
||||
pre .ruby .subst {
|
||||
color: #8F8F8F;
|
||||
}
|
||||
|
||||
pre .dos .keyword,
|
||||
pre .python .decorator,
|
||||
pre .class .title,
|
||||
pre .haskell .label,
|
||||
pre .function .title,
|
||||
pre .ini .title,
|
||||
pre .diff .header,
|
||||
pre .ruby .class .parent,
|
||||
pre .apache .tag,
|
||||
pre .nginx .built_in,
|
||||
pre .tex .command,
|
||||
pre .input_number {
|
||||
color: #efef8f;
|
||||
}
|
||||
|
||||
pre .dos .winutils,
|
||||
pre .ruby .symbol,
|
||||
pre .ruby .symbol .string,
|
||||
pre .ruby .symbol .keyword,
|
||||
pre .ruby .symbol .keymethods,
|
||||
pre .ruby .string,
|
||||
pre .ruby .instancevar {
|
||||
color: #DCA3A3;
|
||||
}
|
||||
|
||||
pre .diff .deletion,
|
||||
pre .string,
|
||||
pre .tag .value,
|
||||
pre .preprocessor,
|
||||
pre .built_in,
|
||||
pre .sql .aggregate,
|
||||
pre .javadoc,
|
||||
pre .smalltalk .class,
|
||||
pre .smalltalk .localvars,
|
||||
pre .smalltalk .array,
|
||||
pre .css .rules .value,
|
||||
pre .attr_selector,
|
||||
pre .pseudo,
|
||||
pre .apache .cbracket,
|
||||
pre .tex .formula {
|
||||
color: #CC9393;
|
||||
}
|
||||
|
||||
pre .shebang,
|
||||
pre .diff .addition,
|
||||
pre .comment,
|
||||
pre .java .annotation,
|
||||
pre .template_comment,
|
||||
pre .pi,
|
||||
pre .doctype {
|
||||
color: #7F9F7F;
|
||||
}
|
||||
|
||||
pre .xml .css,
|
||||
pre .xml .javascript,
|
||||
pre .xml .vbscript,
|
||||
pre .tex .formula {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
SIL Open Font License (OFL)
|
||||
http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL
|
|
@ -0,0 +1,2 @@
|
|||
/*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/
|
||||
if(typeof document!=="undefined"&&!("classList" in document.createElement("a"))){(function(j){var a="classList",f="prototype",m=(j.HTMLElement||j.Element)[f],b=Object,k=String[f].trim||function(){return this.replace(/^\s+|\s+$/g,"")},c=Array[f].indexOf||function(q){var p=0,o=this.length;for(;p<o;p++){if(p in this&&this[p]===q){return p}}return -1},n=function(o,p){this.name=o;this.code=DOMException[o];this.message=p},g=function(p,o){if(o===""){throw new n("SYNTAX_ERR","An invalid or illegal string was specified")}if(/\s/.test(o)){throw new n("INVALID_CHARACTER_ERR","String contains an invalid character")}return c.call(p,o)},d=function(s){var r=k.call(s.className),q=r?r.split(/\s+/):[],p=0,o=q.length;for(;p<o;p++){this.push(q[p])}this._updateClassName=function(){s.className=this.toString()}},e=d[f]=[],i=function(){return new d(this)};n[f]=Error[f];e.item=function(o){return this[o]||null};e.contains=function(o){o+="";return g(this,o)!==-1};e.add=function(o){o+="";if(g(this,o)===-1){this.push(o);this._updateClassName()}};e.remove=function(p){p+="";var o=g(this,p);if(o!==-1){this.splice(o,1);this._updateClassName()}};e.toggle=function(o){o+="";if(g(this,o)===-1){this.add(o)}else{this.remove(o)}};e.toString=function(){return this.join(" ")};if(b.defineProperty){var l={get:i,enumerable:true,configurable:true};try{b.defineProperty(m,a,l)}catch(h){if(h.number===-2146823252){l.enumerable=false;b.defineProperty(m,a,l)}}}else{if(b[f].__defineGetter__){m.__defineGetter__(a,i)}}}(self))};
|
|
@ -0,0 +1,8 @@
|
|||
/**
|
||||
Head JS The only script in your <HEAD>
|
||||
Copyright Tero Piirainen (tipiirai)
|
||||
License MIT / http://bit.ly/mit-license
|
||||
Version 0.96
|
||||
|
||||
http://headjs.com
|
||||
*/(function(a){function z(){d||(d=!0,s(e,function(a){p(a)}))}function y(c,d){var e=a.createElement("script");e.type="text/"+(c.type||"javascript"),e.src=c.src||c,e.async=!1,e.onreadystatechange=e.onload=function(){var a=e.readyState;!d.done&&(!a||/loaded|complete/.test(a))&&(d.done=!0,d())},(a.body||b).appendChild(e)}function x(a,b){if(a.state==o)return b&&b();if(a.state==n)return k.ready(a.name,b);if(a.state==m)return a.onpreload.push(function(){x(a,b)});a.state=n,y(a.url,function(){a.state=o,b&&b(),s(g[a.name],function(a){p(a)}),u()&&d&&s(g.ALL,function(a){p(a)})})}function w(a,b){a.state===undefined&&(a.state=m,a.onpreload=[],y({src:a.url,type:"cache"},function(){v(a)}))}function v(a){a.state=l,s(a.onpreload,function(a){a.call()})}function u(a){a=a||h;var b;for(var c in a){if(a.hasOwnProperty(c)&&a[c].state!=o)return!1;b=!0}return b}function t(a){return Object.prototype.toString.call(a)=="[object Function]"}function s(a,b){if(!!a){typeof a=="object"&&(a=[].slice.call(a));for(var c=0;c<a.length;c++)b.call(a,a[c],c)}}function r(a){var b;if(typeof a=="object")for(var c in a)a[c]&&(b={name:c,url:a[c]});else b={name:q(a),url:a};var d=h[b.name];if(d&&d.url===b.url)return d;h[b.name]=b;return b}function q(a){var b=a.split("/"),c=b[b.length-1],d=c.indexOf("?");return d!=-1?c.substring(0,d):c}function p(a){a._done||(a(),a._done=1)}var b=a.documentElement,c,d,e=[],f=[],g={},h={},i=a.createElement("script").async===!0||"MozAppearance"in a.documentElement.style||window.opera,j=window.head_conf&&head_conf.head||"head",k=window[j]=window[j]||function(){k.ready.apply(null,arguments)},l=1,m=2,n=3,o=4;i?k.js=function(){var a=arguments,b=a[a.length-1],c={};t(b)||(b=null),s(a,function(d,e){d!=b&&(d=r(d),c[d.name]=d,x(d,b&&e==a.length-2?function(){u(c)&&p(b)}:null))});return k}:k.js=function(){var a=arguments,b=[].slice.call(a,1),d=b[0];if(!c){f.push(function(){k.js.apply(null,a)});return k}d?(s(b,function(a){t(a)||w(r(a))}),x(r(a[0]),t(d)?d:function(){k.js.apply(null,b)})):x(r(a[0]));return k},k.ready=function(b,c){if(b==a){d?p(c):e.push(c);return k}t(b)&&(c=b,b="ALL");if(typeof b!="string"||!t(c))return k;var f=h[b];if(f&&f.state==o||b=="ALL"&&u()&&d){p(c);return k}var i=g[b];i?i.push(c):i=g[b]=[c];return k},k.ready(a,function(){u()&&s(g.ALL,function(a){p(a)}),k.feature&&k.feature("domloaded",!0)});if(window.addEventListener)a.addEventListener("DOMContentLoaded",z,!1),window.addEventListener("load",z,!1);else if(window.attachEvent){a.attachEvent("onreadystatechange",function(){a.readyState==="complete"&&z()});var A=1;try{A=window.frameElement}catch(B){}!A&&b.doScroll&&function(){try{b.doScroll("left"),z()}catch(a){setTimeout(arguments.callee,1);return}}(),window.attachEvent("onload",z)}!a.readyState&&a.addEventListener&&(a.readyState="loading",a.addEventListener("DOMContentLoaded",handler=function(){a.removeEventListener("DOMContentLoaded",handler,!1),a.readyState="complete"},!1)),setTimeout(function(){c=!0,s(f,function(a){a()})},300)})(document)
|
After Width: | Height: | Size: 46 KiB |
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 25 KiB |
|
@ -0,0 +1,35 @@
|
|||
(function() {
|
||||
// don't emit events from inside the previews themselves
|
||||
if ( window.location.search.match( /receiver/gi ) ) { return; }
|
||||
|
||||
var socket = io.connect(window.location.origin);
|
||||
var socketId = Math.random().toString().slice(2);
|
||||
|
||||
console.log('View slide notes at ' + window.location.origin + '/notes/' + socketId);
|
||||
|
||||
Reveal.addEventListener( 'slidechanged', function( event ) {
|
||||
var nextindexh;
|
||||
var nextindexv;
|
||||
var slideElement = event.currentSlide;
|
||||
|
||||
if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') {
|
||||
nextindexh = event.indexh;
|
||||
nextindexv = event.indexv + 1;
|
||||
} else {
|
||||
nextindexh = event.indexh + 1;
|
||||
nextindexv = 0;
|
||||
}
|
||||
|
||||
var notes = slideElement.querySelector('aside.notes');
|
||||
var slideData = {
|
||||
notes : notes ? notes.innerHTML : '',
|
||||
indexh : event.indexh,
|
||||
indexv : event.indexv,
|
||||
nextindexh : nextindexh,
|
||||
nextindexv : nextindexv,
|
||||
socketId : socketId
|
||||
};
|
||||
|
||||
socket.emit('slidechanged', slideData);
|
||||
} );
|
||||
}());
|
|
@ -0,0 +1,55 @@
|
|||
var express = require('express');
|
||||
var fs = require('fs');
|
||||
var io = require('socket.io');
|
||||
var _ = require('underscore');
|
||||
var Mustache = require('mustache');
|
||||
|
||||
var app = express.createServer();
|
||||
var staticDir = express.static;
|
||||
|
||||
io = io.listen(app);
|
||||
|
||||
var opts = {
|
||||
port : 1947,
|
||||
baseDir : __dirname + '/../../'
|
||||
};
|
||||
|
||||
io.sockets.on('connection', function(socket) {
|
||||
socket.on('slidechanged', function(slideData) {
|
||||
socket.broadcast.emit('slidedata', slideData);
|
||||
});
|
||||
});
|
||||
|
||||
app.configure(function() {
|
||||
[ 'css', 'js', 'plugin', 'lib' ].forEach(function(dir) {
|
||||
app.use('/' + dir, staticDir(opts.baseDir + dir));
|
||||
});
|
||||
});
|
||||
|
||||
app.get("/", function(req, res) {
|
||||
fs.createReadStream(opts.baseDir + '/index.html').pipe(res);
|
||||
});
|
||||
|
||||
app.get("/notes/:socketId", function(req, res) {
|
||||
|
||||
fs.readFile(opts.baseDir + 'plugin/speakernotes/notes.html', function(err, data) {
|
||||
res.send(Mustache.to_html(data.toString(), {
|
||||
socketId : req.params.socketId
|
||||
}));
|
||||
});
|
||||
// fs.createReadStream(opts.baseDir + 'speakernotes/notes.html').pipe(res);
|
||||
});
|
||||
|
||||
// Actually listen
|
||||
app.listen(opts.port || null);
|
||||
|
||||
var brown = '\033[33m',
|
||||
green = '\033[32m',
|
||||
reset = '\033[0m';
|
||||
|
||||
var slidesLocation = "http://localhost" + ( opts.port ? ( ':' + opts.port ) : '' );
|
||||
|
||||
console.log( brown + "reveal.js - Speaker Notes" + reset );
|
||||
console.log( "1. Open the slides at " + green + slidesLocation + reset );
|
||||
console.log( "2. Click on the link your JS console to go to the notes page" );
|
||||
console.log( "3. Advance through your slides and your notes will advance automatically" );
|
|
@ -0,0 +1,109 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>reveal.js - Slide Notes</title>
|
||||
|
||||
<style>
|
||||
body {
|
||||
font-family: Helvetica;
|
||||
}
|
||||
|
||||
#notes {
|
||||
font-size: 24px;
|
||||
width: 640px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#wrap-current-slide {
|
||||
width: 640px;
|
||||
height: 512px;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#current-slide {
|
||||
width: 1280px;
|
||||
height: 1024px;
|
||||
border: none;
|
||||
-moz-transform: scale(0.5);
|
||||
-moz-transform-origin: 0 0;
|
||||
-o-transform: scale(0.5);
|
||||
-o-transform-origin: 0 0;
|
||||
-webkit-transform: scale(0.5);
|
||||
-webkit-transform-origin: 0 0;
|
||||
}
|
||||
|
||||
#wrap-next-slide {
|
||||
width: 320px;
|
||||
height: 256px;
|
||||
float: left;
|
||||
margin: 0 0 0 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#next-slide {
|
||||
width: 1280px;
|
||||
height: 1024px;
|
||||
border: none;
|
||||
-moz-transform: scale(0.25);
|
||||
-moz-transform-origin: 0 0;
|
||||
-o-transform: scale(0.25);
|
||||
-o-transform-origin: 0 0;
|
||||
-webkit-transform: scale(0.25);
|
||||
-webkit-transform-origin: 0 0;
|
||||
}
|
||||
|
||||
.slides {
|
||||
position: relative;
|
||||
margin-bottom: 10px;
|
||||
border: 1px solid black;
|
||||
border-radius: 2px;
|
||||
background: rgb(28, 30, 32);
|
||||
}
|
||||
|
||||
.slides span {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
left: 3px;
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
color: rgba( 255, 255, 255, 0.9 );
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="wrap-current-slide" class="slides">
|
||||
<iframe src="/?receiver" width="1280" height="1024" id="current-slide"></iframe>
|
||||
</div>
|
||||
|
||||
<div id="wrap-next-slide" class="slides">
|
||||
<iframe src="/?receiver" width="640" height="512" id="next-slide"></iframe>
|
||||
<span>UPCOMING:</span>
|
||||
</div>
|
||||
<div id="notes"></div>
|
||||
|
||||
<script src="/socket.io/socket.io.js"></script>
|
||||
|
||||
<script>
|
||||
var socketId = '{{socketId}}';
|
||||
var socket = io.connect(window.location.origin);
|
||||
var notes = document.getElementById('notes');
|
||||
var currentSlide = document.getElementById('current-slide');
|
||||
var nextSlide = document.getElementById('next-slide');
|
||||
|
||||
socket.on('slidedata', function(data) {
|
||||
// ignore data from sockets that aren't ours
|
||||
if (data.socketId !== socketId) { return; }
|
||||
|
||||
notes.innerHTML = data.notes;
|
||||
currentSlide.contentWindow.Reveal.navigateTo(data.indexh, data.indexv);
|
||||
nextSlide.contentWindow.Reveal.navigateTo(data.nextindexh, data.nextindexv);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 75 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 92 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 248 KiB |