1
0
mirror of https://github.com/webslides/WebSlides.git synced 2025-09-20 18:02:46 +02:00

Compare commits

...

90 Commits
0.2 ... 1.2.0

Author SHA1 Message Date
Antonio Laguna
8f7707b996 Adding missing key 2017-03-02 10:45:01 +01:00
Antonio Laguna
dc0386cb49 1.2.0 2017-03-02 10:43:57 +01:00
Antonio Laguna
21f7ba37ca Updating the docs 2017-03-02 10:35:14 +01:00
Antonio Laguna
9bbbd7362b Merge branch 'dev' of github.com:jlantunez/webslides into dev 2017-03-02 09:45:25 +01:00
Antonio Laguna
6818e4c99c Allowing options to be configured
Fixes #47 #44
2017-03-02 09:45:21 +01:00
Antonio Laguna
23ad0338cb Preventing navigation with keys if user using inputs
Fixes #50
2017-03-02 09:43:08 +01:00
Antonio Laguna
440e1bf37e Allowing navigation with Home and End keys
Fixes #49
2017-03-02 09:41:59 +01:00
José Luis Antúnez
f086aefe71 2 new animations: .slideInLeft and .slideInRight
Mobile transitions between the slides
2017-03-01 20:09:43 +01:00
Antonio Laguna
8ae6954e5f Allowing to navigate with re/av page
Fixes #48
2017-03-01 13:56:11 +01:00
Antonio Laguna
09bdc31b64 Updating README 2017-02-28 11:13:04 +01:00
Antonio Laguna
5c4d2f8769 Updating the dist 2017-02-28 11:12:54 +01:00
Antonio Laguna
d03e0cad41 Update package.json 2017-02-28 11:11:03 +01:00
Antonio Laguna
be0e498b2b Update CHANGELOG.md 2017-02-28 11:10:37 +01:00
Antonio Laguna
12bac7afc5 Merge pull request #45 from jlantunez/scroll-fix
Adding a few changes
2017-02-28 11:09:08 +01:00
Antonio Laguna
78b6e74b82 Adding contributors 2017-02-28 08:16:06 +01:00
Antonio Laguna
91c00a2fe3 Linking to issues 2017-02-27 22:28:30 +01:00
Antonio Laguna
e65826dbb6 Updating the CHANGELOG 2017-02-27 22:26:49 +01:00
Antonio Laguna
508cdafea5 Fixing scroll bug 2017-02-27 22:15:33 +01:00
José Luis Antúnez
50af5fe3df Disable elastic scrolling/bounce, hide scrollbar 2017-02-27 20:40:39 +01:00
Antonio Laguna
ebe42090ac Fixing issue with scrolling 2017-02-27 20:24:56 +01:00
Antonio Laguna
14e1b5b7b8 Disting 2017-02-27 20:16:37 +01:00
Antonio Laguna
2e6471e2ee Increasing timeout 2017-02-27 20:16:26 +01:00
Antonio Laguna
bc64fcef7e Adding more docs 2017-02-27 20:14:41 +01:00
Antonio Laguna
e50193ebb1 Normalising var 2017-02-27 20:14:35 +01:00
Antonio Laguna
b04f15f696 Adding more docs 2017-02-27 20:14:24 +01:00
Antonio Laguna
3d6fcef762 Adding option 2017-02-27 20:14:18 +01:00
Antonio Laguna
32ff8afa88 Disting 2017-02-27 20:10:26 +01:00
Antonio Laguna
f082ff12ac Adding new features 2017-02-27 19:58:42 +01:00
Antonio Laguna
62c6aba478 Disting 2017-02-27 12:50:30 +01:00
Antonio Laguna
5a262f5460 Avoiding scroll transition on mobile 2017-02-27 12:50:19 +01:00
Antonio Laguna
4379122d1d Updating references 2017-02-27 12:45:26 +01:00
Antonio Laguna
83f1110947 Preventing default if moving to avoid stutter 2017-02-27 12:45:14 +01:00
Antonio Laguna
b7503b1e9e Using the scrollable container 2017-02-27 12:44:47 +01:00
Antonio Laguna
521d708c22 No need for this anymore 2017-02-27 12:44:29 +01:00
Antonio Laguna
33b1f3ad7a Scrollable container is now defined 2017-02-27 12:44:16 +01:00
Antonio Laguna
f6ccd39158 Changing scrollable container
To avoid elastic scroll on OSX
2017-02-27 12:43:59 +01:00
Antonio Laguna
6674a4f203 Linting CSS 2017-02-27 12:43:38 +01:00
José Luis Antúnez
f80106a4ab 1.0
Download latest version
2017-02-23 17:19:09 +01:00
José Luis Antúnez
4fb151c886 1.0
download latest version
2017-02-23 17:13:41 +01:00
José Luis Antúnez
b7a01c4319 1.0
download latest version (zip)
2017-02-23 17:12:35 +01:00
José Luis Antúnez
28c08541e5 1.0
Download latest version (zip)
2017-02-23 17:11:16 +01:00
Antonio Laguna
6bc8ab582d Ensuring dev server is reachable over the network 2017-02-23 16:18:19 +01:00
Antonio Laguna
19cd5bdbc7 Avoid usage of isInteger
#29
2017-02-23 16:18:19 +01:00
Antonio Laguna
bb5ae82995 Avoiding to use Array.from 2017-02-23 16:18:19 +01:00
José Luis Antúnez
36c1f1997b 1.0
Download release
2017-02-23 15:36:59 +01:00
Antonio Laguna
5687d61a83 Adding generated source 2017-02-23 15:30:50 +01:00
José Luis Antúnez
0d2c8c09d1 1.0 2017-02-23 14:55:47 +01:00
José Luis Antúnez
9e5a127590 1.0 2017-02-23 13:51:36 +01:00
José Luis Antúnez
7b86354ad4 1.0
download zip
2017-02-23 13:51:00 +01:00
José Luis Antúnez
a67f7d9d0b 1.0
Download zip
2017-02-23 13:50:00 +01:00
José Luis Antúnez
2234a02252 1.0 2017-02-23 13:48:53 +01:00
José Luis Antúnez
02834a3b4d 1.0
download zip
2017-02-23 13:47:46 +01:00
José Luis Antúnez
3e13eb4025 1.0
Credits
2017-02-23 13:43:33 +01:00
José Luis Antúnez
28756b308f 1.0
Download zip
2017-02-23 13:39:33 +01:00
Antonio Laguna
acd3eed1b7 Fixing leftover for changes 2017-02-23 13:10:49 +01:00
José Luis Antúnez
8ac52b4936 Merge pull request #41 from Belelros/master
WebSlides 1.0 - Architecture change
2017-02-23 12:53:46 +01:00
Antonio Laguna
130c5d2321 Merge remote-tracking branch 'webslides/master'
# Conflicts:
#	CHANGELOG.md
#	README.md
#	demos/classes.html
#	demos/components.html
#	demos/index.html
#	demos/keynote.html
#	demos/landings.html
#	demos/portfolios.html
#	demos/why-webslides.html
#	index.html
#	static/css/base.css
#	static/js/webslides.js
2017-02-23 12:47:46 +01:00
Antonio Laguna
0055ecd7d8 Updating the README too 2017-02-23 12:36:10 +01:00
Antonio Laguna
4ba77ba3fc JavaScript highlighting 2017-02-23 10:22:57 +01:00
Antonio Laguna
25be14fbd4 Final touches 2017-02-23 10:20:56 +01:00
Antonio Laguna
2c21b8f5d9 More updates 2017-02-23 08:34:18 +01:00
Antonio Laguna
2ef3f986ed Updating CSS to catch up with Master 2017-02-23 08:30:57 +01:00
Antonio Laguna
76ea07d8db Adding autoslide feature 2017-02-23 08:25:24 +01:00
Antonio Laguna
9bfab33676 Final push 2017-02-22 11:50:15 +01:00
Antonio Laguna
3251b1b7d8 Re-updating docs 2017-01-31 08:39:21 +01:00
Antonio Laguna
3782a40a8a Updating README 2017-01-30 20:52:12 +01:00
Antonio Laguna
585ab60b43 Updating templates and releasing the dist 2017-01-30 15:59:20 +01:00
Antonio Laguna
62ffaf95d6 Removing webslides 2017-01-30 15:57:31 +01:00
Antonio Laguna
4ca297f8ae Moving stuff around 2017-01-30 15:56:47 +01:00
Antonio Laguna
0ce1d02d8b Baseline to plugin 2017-01-30 15:55:30 +01:00
Antonio Laguna
c5133158ad Adding scroll to plugin 2017-01-30 15:47:17 +01:00
Antonio Laguna
ff3c2d066a Adding touch plugin 2017-01-29 11:06:22 +01:00
Antonio Laguna
8e47ffead4 Fixing issue with normal transition 2017-01-29 11:06:04 +01:00
Antonio Laguna
2a46012a58 Fix build script 2017-01-29 11:05:30 +01:00
Antonio Laguna
c1777f593f Finishing docs 2017-01-28 18:06:13 +01:00
Antonio Laguna
b99fdc8c47 Moving plugins, adding Keyboard integration 2017-01-28 17:17:10 +01:00
Antonio Laguna
0e02056ca7 Hash to plugin 2017-01-28 16:40:30 +01:00
Antonio Laguna
72d057293e Adding to detail instead of needing to add a full object 2017-01-28 16:27:38 +01:00
Antonio Laguna
75de8a46ac Reworking the plugins 2017-01-28 16:27:15 +01:00
Antonio Laguna
ae36e15588 Finishing navigation 2017-01-28 16:26:55 +01:00
Antonio Laguna
6e7ce46ebc Fixing the scroll function and adding docs 2017-01-28 15:38:49 +01:00
Antonio Laguna
ea164b6d69 Adding custom event support 2017-01-28 15:38:33 +01:00
Antonio Laguna
7b495cccf1 Navigation to plugins 2017-01-28 15:38:21 +01:00
Antonio Laguna
049d083744 Easing’s JSDoc 2017-01-27 15:34:34 +01:00
Antonio Laguna
86cc1f494f More JSDocs for the slides 2017-01-27 15:32:50 +01:00
Antonio Laguna
d4e6662ab6 Starting to add comments and JSDoc 2017-01-27 15:28:40 +01:00
Antonio Laguna
01fa93d50e Finishing the core bits 2017-01-27 12:28:45 +01:00
Antonio Laguna
70bde2f4ae Entry point 2017-01-25 22:48:35 +01:00
Antonio Laguna
2e93754ba1 Adding package.json 2017-01-24 15:04:15 +01:00
Antonio Laguna
4e562e2978 Common gitignore file 2017-01-24 15:04:05 +01:00
37 changed files with 3908 additions and 818 deletions

20
.editorconfig Normal file
View File

@@ -0,0 +1,20 @@
root = true
[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 233
[*.json]
indent_style = space
indent_size = 2
[*.yml]
indent_style = space
indent_size = 2
[*.md]
trim_trailing_whitespace = false

17
.gitignore vendored Normal file
View File

@@ -0,0 +1,17 @@
# IDE files #
#############
.idea/
# Third Party #
###############
node_modules/
# OS generated files #
######################
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

View File

@@ -1,13 +1,77 @@
## 0.2 (2017-02-22)
# 1.2.0 (2017-03-02)
- Auto slide (Demo: why-webslides.html)
## New Features
## 0.1.1 (2017-02-11)
- [[#48](https://github.com/jlantunez/webslides/issues/48)] Allows to navigate with AvPag & RePag to allow presentation devices to work.
- [[#49](https://github.com/jlantunez/webslides/issues/49)] Allowing to go to first and last slides by using home and end keys respectively.
- [[#50](https://github.com/jlantunez/webslides/issues/50)] Using the keyboard on inputs and editable content won't trigger any events that might cause navigation.
- [[#47](https://github.com/jlantunez/webslides/issues/47)] Allowing options to be configured. [Read More](/docs/technical.md#options).
# 1.1.0 (2017-02-28)
## Bugfixes
- Fixed a bug which caused Chrome on OSX to stutter a lot on vertical transitioning due to elastic scroll bounce.
- [[#28](https://github.com/jlantunez/webslides/issues/28)] Fixed scroll on Firefox.
- [[#38](https://github.com/jlantunez/webslides/issues/38)] Fixed a bug in Safari which lead to unexpected behaviour using any form of movements.
- [[#10](https://github.com/jlantunez/webslides/issues/10)] Fixed animation flash on Safari.
## New Features
- [[#1](https://github.com/jlantunez/webslides/issues/1)] Adding option to click to go to the next slide. Read more [here](https://github.com/jlantunez/webslides/blob/master/docs/click-to-nav.md).
- [[#1](https://github.com/jlantunez/webslides/issues/1)] Improved sliding with mouse scroll and touchpad. It's now possible to use scroll to move an horizontal presentation.
It's also possible to scroll horizontally on horizontal presentations to move forward/backwards the presentation.
## Regression
- Introduced a minor bug on iOS Safari which leads to the bottom part of the page not being visible on the first scroll. This is likely a browser bug but it has been unearthed in this version due to a much needed improvement on scrolling behaviour bugs. We're trying to investigate a bit more and will provide a fix ASAP.
# 1.0.0 (2017-02-23)
This release is a special one since it sets up in the path of a better development environment. Although it's far from
perfect, it's a solid beginning.
All the code has been migrated from **jQuery** with ES5 to **vanilla JavaScript with ES2015 (or ES6) and is fully modular**.
This means that WebSlides is a (base module)[src/js/modules/webslides.js] with a solid API (few public methods) and
it's extended by (plugins)[src/js/plugins]. This leads to more granularity and less code to dive through while fixing a
bug.
**The benefit from this approach is that now it's really easy to extend WebSlides** to achieve what you need. You can also
overwrite current plugins. Say you don't like the current navigation with arrows and want to create a menu instead, you
can just write that for yourself with your custom needs and register it as `nav` and it will overwrite our nav with
your code.
We hope this leads to a better environment in which WebSlides can grow better.
All the technical specs live now in [this document](docs/technical.md).
## Bugfixes
- Fixed a bug with back/next buttons on the browser which lead the nav bar to not work.
## New Features
- Linking to slides without window open.
- Added custom events to listen for. `ws:init` whenever webslides is ready and `ws:slide-change` whenever a slide changes.
- Added play/stop methods.
## Breaking Changes
- This "stable" release drops the jQuery requirement and leans on ES2015 for the architecture. Hence, it's no longer possible
to use the library as before.
# 0.2.0 (2017-02-22)
## New Features
- Adding autoslide option.
# 0.1.1 (2017-02-11)
- Transform the library into an object.
- .tabs removed.
- webslides-lite.js removed.
- `.tabs` removed.
- `webslides-lite.js` removed.
## 0.1 (2017-01-08)
# 0.1.0 (2017-01-08)
- Initial release.

109
README.md
View File

@@ -1,71 +1,74 @@
# WebSlides = Good Karma
Finally, everything you need to make HTML presentations in a beautiful way. Just the essentials. You can create your own presentation instantly. Simply choose a demo and customize it in minutes — [https://webslides.tv/demos](https://webslides.tv/demos).
A new release (at least) every 8th day of the month. Version 0.1: Jan 8, 2017.
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](http://opensource.org/licenses/MIT)
[![Twitter](https://img.shields.io/twitter/url/https/github.com/jlantunez/webslides.svg?style=social)](https://twitter.com/webslides)
Finally, everything you need to make HTML presentations in a beautiful way. Just the essentials. You can create your own presentation instantly. A new release (at least) every 8th day of the month — [https://webslides.tv/demos](https://webslides.tv/demos).
* * *
### Download
Simply choose a demo and customize it in minutes. Latest version: [webslides.tv/webslides-latest.zip](https://webslides.tv/webslides-latest.zip).
* * *
### Why WebSlides?
Good karma and productivity. Just a basic knowledge of HTML and CSS is required. Designers, marketers, and journalists can now focus on the content.
### Features
## Features
- Navigation (horizontal and vertical sliding): touchpad, keyboard shortcuts, and swipe.
- Slide counter.
- Permalinks: go to a specific slide.
- Autoslide
- Autoslide.
- Click to nav. [Read more](docs/click-to-nav.md)!
- Simple CSS alignments. Put content wherever you want (vertical centering...)
- 40+ components: background images/videos, quotes, cards, covers...
- Flexible blocks with auto-fill and equal height.
- Fonts: Roboto, Maitree (Serif), and San Francisco.
- Vertical rhythm (use multiples of 8).
### Markup
### Key Navigation
There's a handful of keys that can be used to achieve navigation within WebSlides. Here's the list:
* `←`: If WebSlides is not vertical, it will go to the previous slide.
* `→`: If WebSlides is not vertical, it will go to the next slide.
* `↑`: If WebSlides is vertical, it will go to the previous slide.
* `↓`: If WebSlides is vertical, it will go to the next slide.
* `Page Up`: Go to the previous slide.
* `Page Down`: Go to the next slide.
* `Space`: Go to the next slide.
* `Home`: Go to the first slide.
* `End`: Go to the last slide.
## Markup
- Code is clean and scalable. It uses intuitive markup with popular naming conventions. There's no need to overuse classes or nesting.
- Each parent <code>&lt;section&gt;</code> in the #webslides element is an individual slide.
- Each parent `<section>` in the `#webslides` element is an individual slide.
<pre>&lt;article id="webslides"&gt;
&lt;section&gt;
&lt;h1&gt;Slide 1&lt;/h1&gt;
&lt;/section&gt;
&lt;section class="bg-black aligncenter"&gt;
<span class="code-comment">&lt;!-- .wrap = container 1200px --&gt;</span>
&lt;div class="wrap"&gt;
&lt;h1&gt;Slide 2&lt;/h1&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/article&gt;</pre>
#### Vertical Sliding
<pre>&lt;article id="webslides" class="vertical"&gt;</pre>
### How it works
You need to add the follow javascript to initialize the webslides object.
```javascript
var slide = jQuery('#webslides').webslides();
```html
<article id="webslides">
<section>
<h1>Slide 1</h1>
</section>
<section class="bg-black aligncenter">
<!-- .wrap = container 1200px -->
<div class="wrap">
<h1>Slide 2</h1>
</div>
</section>
</article>
```
#### Auto slide
### Vertical Sliding
```javascript
var slide = jQuery('#webslides').webslides({interval: 5000});
```
Now you can use the slide with these functions:
```javascript
// Moving to next slide
slide.nextSlide();
// Moving to previous slide
slide.previousSlide();
// Moving to a specific slide
slide.goToSlide(n);
```html
<article id="webslides" class="vertical">
```
### What's in the download?
The download includes demos and images (devices and logos).
The download includes demos and images (devices and logos).
All content is for demo purposes only. Images are property of their respective owners.
```
@@ -84,16 +87,17 @@ webslides/
### CSS Syntax (classes)
- Typography: .text-landing, .text-data, .text-intro...
- Background Colors: .bg-primary, .bg-apple, .bg-blue...
- Background Images: .background,.background-center-bottom...
- Cards: .card-50, .card-40...
- Flexible Blocks: .flexblock.clients, .flexblock.metrics...
- Typography: `.text-landing`, `.text-data`, `.text-intro`...
- Background Colors: `.bg-primary`, `.bg-apple`, `.bg-blue`...
- Background Images: `.background`,`.background-center-bottom`...
- Cards: `.card-50`, `.card-40`...
- Flexible Blocks: `.flexblock.clients`, `.flexblock.metrics`...
### Extensions
You can add:
- [Unsplash](https://unsplash.com) photos
- [animate.css](https://daneden.github.io/animate.css)
- [particles.js](https://github.com/VincentGarreau/particles.js)
@@ -101,11 +105,18 @@ You can add:
### License
WebSlides is licensed under the [MIT License](https://opensource.org/licenses/MIT).
WebSlides is licensed under the [MIT License](https://opensource.org/licenses/MIT).
Use it to make something cool.
### Dive In!
Please check out:
- Want to get techie? Read [our technical docs](docs/technical.md)
- Do not miss [our demos](https://webslides.tv/)
### Credits
- WebSlides was created by [@jlantunez](https://twitter.com/jlantunez) using [Cactus](https://github.com/eudicots/Cactus).
- Thanks [@LuisSacristan](https://twitter.com/luissacristan) for the javascript code :)
- Javascript: [@Belelros](https://twitter.com/Belelros) and [@LuisSacristan](https://twitter.com/luissacristan).
- Based on [SimpleSlides](https://github.com/jennschiffer/SimpleSlides), by [@JennSchiffer](https://twitter.com/jennschiffer).

View File

@@ -1933,16 +1933,13 @@
</main>
<!--main-->
<!-- jQuery (required for slides to work) -->
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="../static/js/svg-icons.js"></script>
<script src="../static/js/webslides.js"></script>
<script type="text/javascript">
var slide = jQuery('#webslides').webslides();
<script>
window.ws = new WebSlides();
</script>
<!-- OPTIONAL - svg-icons.js (fontastic.me - Font Awesome as svg icons) -->
<script defer src="../static/js/svg-icons.js"></script>
</body>
</html>

View File

@@ -319,7 +319,11 @@
<section>
<div class="wrap">
<h1>Navigation</h1>
<ul class="tabs">
<li class="tab current" data-tab="tab-1">ul.tabs</li>
<li class="tab" data-tab="tab-2">columns</li>
</ul>
<div id="tab-1" class="tab-content current">
<nav role="navigation">
<ul>
<li><a href="">About</a></li>
@@ -368,8 +372,9 @@
</ul>
</nav>
<p>nav.navbar</p>
<hr>
</div>
<!-- end .tab-content -->
<div id="tab-2" class="tab-content">
<div class="grid">
<div class="column">
<h3>Company</h3>
@@ -430,6 +435,8 @@
<!-- .end .column -->
</div>
<!-- .end .grid -->
</div>
<!-- end .tab-content -->
</div>
<!-- .end .wrap -->
</section>
@@ -1796,8 +1803,49 @@
<section class="aligncenter">
<!--.wrap = container 1200px -->
<div class="wrap">
<h1 class="text-landing">Tell a Story</h1>
<p class="text-intro"><strong>Hi, this is WebSlides</strong>. HTML presentations made simple. <br>I'm a cute solution with clean markup and <strong>lovely CSS</strong>.</p>
<div id="tab-3" class="tab-content current">
<h1 class="text-landing">Tell a Story</h1>
<p class="text-intro"><strong>Hi, this is WebSlides</strong>. HTML presentations made simple. <br>I'm a cute solution with clean markup and <strong>lovely CSS</strong>.</p>
</div>
<div id="tab-4" class="tab-content">
<ul class="flexblock features">
<li>
<div>
<svg class="fa-heart-o">
<use xlink:href="#fa-heart-o"></use>
</svg>
<h2>Indexed content</h2>
Sharing is caring.
</div>
</li>
<li>
<div>
<h2>
<svg class="fa-magic">
<use xlink:href="#fa-magic"></use>
</svg>
Just essential features
</h2>
Keyboard navigation...
</div>
</li>
<li>
<div>
<svg class="fa-bolt">
<use xlink:href="#fa-bolt"></use>
</svg>
<h2>
Prototype faster
</h2>
with clean code
</div>
</li>
</ul>
</div>
<ul class="tabs">
<li class="tab current" data-tab="tab-3">Purpose</li>
<li class="tab" data-tab="tab-4">Benefits</li>
</ul>
</div>
</section>
<section class="bg-black aligncenter">
@@ -3078,16 +3126,14 @@
</main>
<!--main-->
<!-- jQuery (required for slides to work) -->
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="../static/js/svg-icons.js"></script>
<script src="../static/js/webslides.js"></script>
<script type="text/javascript">
var slide = jQuery('#webslides').webslides();
<script>
window.ws = new WebSlides();
</script>
<!-- OPTIONAL - svg-icons.js (fontastic.me - Font Awesome as svg icons) -->
<script defer src="../static/js/svg-icons.js"></script>
</body>
</html>

View File

@@ -92,7 +92,7 @@
</header>
<main role="main">
<article id="webslides" class="vertical">
<article> <!-- Slideshow? id="webslides" -->
<!-- Quick Guide
- Each parent <section> in the <article id="webslides"> element is an individual slide.
@@ -107,7 +107,7 @@
<h1><strong>WebSlides Demos</strong></h1>
<p class="text-intro">All of these presentations are free and responsive.<br>
40+ <a href="../demos/components.html" title="WebSlides Components">components</a> with a solid <a href="../demos/classes.html" title="WebSlides Classes">CSS architecture</a>.</p>
<p>Share your slides using <a target="_blank" href="https://twitter.com/search?f=tweets&q=%23webslides&src=typd" title="#WebSlides on Twitter">#WebSlides</a>.</p>
<p>Share your slides using <a href="https://twitter.com/search?q=%23webslides&amp;src=typd" title="#WebSlides on Twitter">#WebSlides</a>.</p>
</div>
<!-- .end .wrap -->
</section>
@@ -222,16 +222,14 @@
</main>
<!-- end main -->
<!-- jQuery (required for slides to work) -->
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="../static/js/svg-icons.js"></script>
<script src="../static/js/webslides.js"></script>
<script type="text/javascript">
var slide = jQuery('#webslides').webslides();
<script>
window.ws = new WebSlides();
</script>
<!-- OPTIONAL - svg-icons.js (fontastic.me - Font Awesome as svg icons) -->
<script defer src="../static/js/svg-icons.js"></script>
</body>
</html>

View File

@@ -843,16 +843,14 @@
</main>
<!--main-->
<!-- jQuery (required for slides to work) -->
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="../static/js/svg-icons.js"></script>
<script src="../static/js/webslides.js"></script>
<script type="text/javascript">
var slide = jQuery('#webslides').webslides();
<script>
window.ws = new WebSlides();
</script>
<!-- OPTIONAL - svg-icons.js (fontastic.me - Font Awesome as svg icons) -->
<script defer src="../static/js/svg-icons.js"></script>
</body>
</html>

View File

@@ -1918,16 +1918,13 @@
</main>
<!--main-->
<!-- jQuery (required for slides to work) -->
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="../static/js/svg-icons.js"></script>
<script src="../static/js/webslides.js"></script>
<script type="text/javascript">
var slide = jQuery('#webslides').webslides();
<script>
window.ws = new WebSlides();
</script>
<!-- OPTIONAL - svg-icons.js (fontastic.me - Font Awesome as svg icons) -->
<script defer src="../static/js/svg-icons.js"></script>
</body>
</html>

View File

@@ -1858,16 +1858,14 @@
</main>
<!--main-->
<!-- jQuery (required for slides to work) -->
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="../static/js/svg-icons.js"></script>
<script src="../static/js/webslides.js"></script>
<script type="text/javascript">
var slide = jQuery('#webslides').webslides();
<script>
window.ws = new WebSlides();
</script>
<!-- OPTIONAL - svg-icons.js (fontastic.me - Font Awesome as svg icons) -->
<script defer src="../static/js/svg-icons.js"></script>
</body>
</html>

View File

@@ -66,7 +66,6 @@
<!-- Android -->
<meta name="mobile-web-app-capable" content="yes">
<meta name="theme-color" content="#333333">
</head>
<body>
<header role="banner">
@@ -339,13 +338,11 @@
</main>
<!--main-->
<!-- jQuery (required for slides to work) -->
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="../static/js/svg-icons.js"></script>
<script src="../static/js/webslides.js"></script>
<!-- Autoslide 5 seconds. If you don't want autoslide, remove: {interval: 5000} -->
<script type="text/javascript">
var slide = jQuery('#webslides').webslides({interval: 5000});
<!-- Autoslide 5 seconds. If you don't want autoslide, remove: {autoslide: 5000} -->
<script>
window.ws = new WebSlides({ autoslide: 5000 });
</script>
<!-- OPTIONAL - svg-icons.js (fontastic.me - Font Awesome as svg icons) -->

16
docs/click-to-nav.md Normal file
View File

@@ -0,0 +1,16 @@
## Click To Nav plugin
This plugin is included by default but disabled. In order to enable it, the option `changeOnClick` must be passed as
`true`.
```javascript
const ws = new WebSlides({ changeOnClick: true });
```
This will make every click to navigate to the next slide except for clicks that happens on the following elements:
* `input`.
* `select` or `option`.
* `button`.
* `a`.
* Any element with the attribute `data-prevent-nav`.

147
docs/technical.md Normal file
View File

@@ -0,0 +1,147 @@
## Project Setup
This project assumes you have NodeJS. You should also have npm installed as well (this usually comes packaged with Node). Once you have it cloned, you should run `npm install` to get all the dependencies.
Finally, run one of the following commands in the cloned directory:
- `npm run dev`: This starts a dev server with autoreload on the port `8080`.
- `npm run build`: This creates the `dist` files.
## JavaScript
In order to bootstrap the WebSlides you'll need to create a instance of it:
```javascript
const ws = new WebSlides();
```
That'll make everything run without any hassle.
### Options
WebSlides constructor accepts an object with options.
| Param | Type | Default | Description |
|-----------|----------------|-----------|-------------------------------------------------------------------------------|
| `autoslide` | `number` or `boolean` | `false` | Amount of milliseconds to wait to go to next slide automatically. |
| `changeOnClick` | `boolean` | `false` | If true, clicking on the page will go to the next slide unless it's a clickable element. See [ClickToNav docs](./click-to-nav.md) for more info. |
| `minWheelDelta` | `number` | `40` | Controls the amount of scroll needed to trigger a navigation. Lower this number to decrease the scroll resistance. |
| `scrollWait` | `number` | `450` | Controls the amount of time needed to wait for a scroll transition to happen again. |
| `slideOffset` | `number` | `50` | Amount of sliding needed to trigger a new navigation. |
```javascript
const ws = new WebSlides({
autoslide = false,
changeOnClick = false,
minWheelDelta = 40,
scrollWait = 450,
slideOffset = 50
});
```
### API
Do you want to get your hands dirty? This is the API for the WebSlides module:
<dl>
<dt><a href="#goToSlide">goToSlide(slideIndex, opt_forward)</a></dt>
<dd><p>Goes to a given slide.</p></dd>
<dt><a href="#goNext">goNext()</a></dt>
<dd><p>Goes to the next slide.</p></dd>
<dt><a href="#goPrev">goPrev()</a></dt>
<dd><p>Goes to the previous slide.</p>
<dt><a href="#play">play()</a></dt>
<dd><p>Starts autosliding.</p>
<dt><a href="#stop">stop()</a></dt>
<dd><p>Stops autosliding.</p>
</dd>
<dt><a href="#registerPlugin">registerPlugin(key, cto)</a></dt>
<dd><p>Registers a plugin to be loaded when the instance is created. It allows
(on purpose) to replace default plugins.
Those being:</p>
<ul>
<li>Navigation</li>
<li>Hash</li>
<li>Keyboard</li>
</ul>
</dd>
</dl>
<a name="goToSlide"></a>
### `goToSlide(slideI, forward)`
Goes to a given slide.
| Param | Type | Description |
| --- | --- | --- | --- |
| slideIndex | <code>number</code> | The slide index. |
| forward | <code>boolean</code> | Whether we're forcing moving forward/backwards. This parameter is used only from the `goNext`, `goPrev` functions to adjust the scroll animations. |
<a name="goNext"></a>
### `goNext()`
Goes to the next slide. If the page is vertical, it will animate the scroll down.
<a name="goPrev"></a>
### `goPrev()`
Goes to the previous slide. If the page is vertical, it will animate the scroll up
<a name="play"></a>
### `play(time)`
Autoplays slides. If time is omitted, it will use the default time passed to the constructor. This is useful if you don't want to autoslide from the beginning but you want to add a button to do it.
| Param | Type | Description |
| --- | --- | --- | --- |
| time | <code>number</code> | Amount of milliseconds to wait to go to next slide automatically. |
<a name="stop"></a>
### `stop()`
Stops autosliding.
<a name="registerPlugin"></a>
### `registerPlugin(key, cto)`
Registers a plugin to be loaded when the instance is created. It allows
(on purpose) to replace default plugins.
Those being:
- ClickNav
- Grid
- Hash
- Keyboard
- Navigation
- Scroll
- Touch
| Param | Type | Description |
| --- | --- | --- |
| key | <code>string</code> | They key under which it'll be stored inside of the instance, inside the plugins dict. |
| cto | <code>function</code> | Plugin constructor. |
### Plugin development
Almost every single feature of WebSlides is a plugin that can be overwritten and you are able to create your custom plugins. Just call `registerPlugin` (as seen above) **before creating** the instance:
```javascript
// Adding the constructor to WebSlides
WebSlides.registerPlugin('myPlugin', MyPlugin);
// Starting WebSlides
// Your plugin will be constructed at this time and it will receive the webslides instance as the only parameter.
const ws = new WebSlides();
// You can also access ws.plugins.myPlugin now
```
This allows you to rewrite the navigation to use a menu (for example) or add that missing piece of functionality you'd like to see. See [this part of the code](../src/js/modules/webslides.js#L11) to see all the plugins we're using and the name they're using.
Make sure to let us know so it could get added to the repo!
### Roadmap
* Fix crossbrowser issues. Safari mostly.
* Write tests

View File

@@ -94,7 +94,6 @@
<main role="main">
<article id="webslides" class="vertical">
<!-- Quick Guide
- Each parent <section> in the <article id="webslides"> element is an individual slide.
- Vertical sliding = <article id="webslides" class="vertical">
@@ -384,17 +383,14 @@
</div>
</footer> -->
<!-- jQuery (required for slides to work) -->
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="static/js/svg-icons.js"></script>
<script src="static/js/webslides.js"></script>
<script type="text/javascript">
var slide = jQuery('#webslides').webslides();
<script>
window.ws = new WebSlides();
</script>
<!-- OPTIONAL - svg-icons.js (fontastic.me - Font Awesome as svg icons) -->
<script defer src="static/js/svg-icons.js"></script>
</body>
</html>

58
package.json Normal file
View File

@@ -0,0 +1,58 @@
{
"name": "webslides",
"version": "1.2.0",
"description": "Making HTML presentations easy",
"main": "index.js",
"repository": {
"type": "git",
"url": "git+https://github.com/jlantunez/webslides.git"
},
"keywords": [
"webslides",
"presentation",
"css"
],
"author": "Jose Luís Antúnez <jlantunez@gmail.com>",
"contributors": [
{
"name": "Luís Sacristán"
},
{
"name": "Antonio Laguna",
"email": "a.laguna@funcion13.com"
}
],
"license": "MIT",
"bugs": {
"url": "https://github.com/jlantunez/webslides/issues"
},
"homepage": "https://github.com/jlantunez/webslides#readme",
"devDependencies": {
"babel-cli": "^6.23.0",
"babel-core": "^6.23.1",
"babel-loader": "^6.3.2",
"babel-preset-es2015": "^6.22.0",
"npm-run-all": "^4.0.2",
"rimraf": "^2.6.0",
"smart-banner-webpack-plugin": "^3.0.1",
"webpack": "^2.2.1",
"webpack-dev-server": "^2.4.1"
},
"scripts": {
"prebuild": "rimraf static/js/webslide*",
"build": "npm-run-all --parallel build:*",
"build:main": "webpack",
"build:main.min": "webpack --output-filename [name].min.js -p",
"dev": "webpack-dev-server"
},
"babel": {
"presets": [
[
"es2015",
{
"modules": false
}
]
]
}
}

3
src/js/full.js Normal file
View File

@@ -0,0 +1,3 @@
import WebSlides from './modules/webslides';
window.WebSlides = WebSlides;

82
src/js/modules/slide.js Normal file
View File

@@ -0,0 +1,82 @@
import DOM from '../utils/dom';
const CLASSES = {
SLIDE: 'slide',
CURRENT: 'current'
};
/**
* Wrapper for the Slide section.
*/
export default class Slide {
/**
* Bootstraps the slide by saving some data, adding a class and hiding it.
* @param {Element} el Section element.
* @param {number} i Zero based index of the slide.
*/
constructor(el, i) {
/**
* @type {Element}
*/
this.el = el;
/**
* The section's parent.
* @type {Node}
*/
this.parent = el.parentNode;
/**
* @type {number}
*/
this.i = i;
this.el.id = 'section-' + (i + 1);
this.el.classList.add(CLASSES.SLIDE);
// Hide slides by default
this.hide();
}
/**
* Hides the node and removes the class that makes it "active".
*/
hide() {
DOM.hide(this.el);
this.el.classList.remove(CLASSES.CURRENT);
}
/**
* Shows the node and adds the class that makes it "active".
*/
show() {
DOM.show(this.el);
this.el.classList.add(CLASSES.CURRENT);
}
/**
* Moves the section to the bottom of the section's list.
*/
moveAfterLast() {
const last = this.parent.childNodes[this.parent.childElementCount - 1];
this.parent.insertBefore(this.el, last.nextSibling);
}
/**
* Moves the section to the top of the section's list.
*/
moveBeforeFirst() {
const first = this.parent.childNodes[0];
this.parent.insertBefore(this.el, first);
}
/**
* Checks whether an element is a valid candidate to be a slide by ensuring
* it's a "section" element.
* @param {Element} el Element to be checked.
* @return {boolean} Whether is candidate or not.
*/
static isCandidate(el) {
return el.nodeType === 1 && el.tagName === 'SECTION';
}
}

381
src/js/modules/webslides.js Normal file
View File

@@ -0,0 +1,381 @@
import Plugins from '../plugins/plugins';
import Slide from './slide';
import DOM from '../utils/dom';
import scrollTo from '../utils/scroll-to';
const CLASSES = {
VERTICAL: 'vertical'
};
// Default plugins
const PLUGINS = {
'clickNav': Plugins.ClickNav,
'grid': Plugins.Grid,
'hash': Plugins.Hash,
'keyboard': Plugins.Keyboard,
'nav': Plugins.Navigation,
'scroll': Plugins.Scroll,
'touch': Plugins.Touch
};
export default class WebSlides {
/**
* Options for WebSlides
* @param {number|boolean} autoslide If a number is provided, it will allow
* autosliding by said amount of miliseconds.
* @param {boolean} changeOnClick If true, it will allow
* clicking on any place to change the slide.
* @param {number} minWheelDelta Controls the amount of needed scroll to
* trigger navigation.
* @param {number} scrollWait Controls the amount of time to wait till
* navigation can occur again with scroll.
* @param {number} slideOffset Controls the amount of needed touch delta to
* trigger navigation.
*/
constructor({
autoslide = false,
changeOnClick = false,
minWheelDelta = 40,
scrollWait = 450,
slideOffset = 50
} = {}) {
/**
* WebSlide element.
* @type {Element}
*/
this.el = document.getElementById('webslides');
/**
* Moving flag.
* @type {boolean}
*/
this.isMoving = false;
/**
* Slide's array.
* @type {?Array<Slide>}
*/
this.slides = null;
/**
* Current slide's index.
* @type {number}
* @private
*/
this.currentSlideI_ = -1;
/**
* Current slide reference.
* @type {?Slide}
* @private
*/
this.currentSlide_ = null;
/**
* Max slide index.
* @type {number}
* @private
*/
this.maxSlide_ = 0;
/**
* Whether the layout is going to be vertical or horizontal.
* @type {boolean}
*/
this.isVertical = this.el.classList.contains(CLASSES.VERTICAL);
/**
* Plugin's dictionary.
* @type {Object}
*/
this.plugins = {};
/**
* Interval ID reference for the autoslide.
* @type {?number}
* @private
*/
this.interval_ = null;
/**
* Options dictionary.
* @type {Object}
*/
this.options = {
autoslide,
changeOnClick,
minWheelDelta,
scrollWait,
slideOffset
};
if (!this.el) {
throw new Error('Couldn\'t find the webslides container!');
}
// Bootstrapping
this.removeChildren_();
this.grabSlides_();
this.createPlugins_();
this.initSlides_();
this.play();
// Finished
this.onInit_();
}
/**
* Removes all children elements inside of the main container that are not
* eligible to be a Slide Element.
* @private
*/
removeChildren_() {
const nodes = this.el.childNodes;
let i = nodes.length;
while (i--) {
const node = nodes[i];
if (!Slide.isCandidate(node)) {
this.el.removeChild(node);
}
}
}
/**
* Creates all the registered plugins and store the instances inside of the
* the webslide instance.
* @private
*/
createPlugins_() {
Object.keys(PLUGINS).forEach(pluginName => {
const pluginCto = PLUGINS[pluginName];
this.plugins[pluginName] = new pluginCto(this);
});
}
/**
* Called once the WebSlide instance has finished initialising.
* @private
* @fires WebSlide#ws:init
*/
onInit_() {
DOM.fireEvent(this.el, 'ws:init');
}
/**
* Grabs the slides from the DOM and creates all the Slides modules.
* @private
*/
grabSlides_() {
this.slides = DOM.toArray(this.el.childNodes)
.map((slide, i) => new Slide(slide, i));
this.maxSlide_ = this.slides.length;
}
/**
* Goes to a given slide.
* @param {!number} slideI The slide index.
* @param {?boolean} forward Whether we're forcing moving forward/backwards.
* This parameter is used only from the goNext, goPrev functions to adjust the
* scroll animations.
*/
goToSlide(slideI, forward = null) {
if (this.isValidIndexSlide_(slideI) &&
!this.isMoving &&
this.currentSlideI_ !== slideI) {
this.isMoving = true;
let isMovingForward = false;
if (forward !== null) {
isMovingForward = forward;
} else {
if (this.currentSlideI_ >= 0) {
isMovingForward = slideI > this.currentSlideI_;
}
}
const nextSlide = this.slides[slideI];
if (this.currentSlide_ !== null && this.isVertical &&
(!this.plugins.touch || !this.plugins.touch.isEnabled)) {
this.scrollTransitionToSlide_(
isMovingForward, nextSlide, this.onSlideChange_);
} else {
this.transitionToSlide_(
isMovingForward, nextSlide, this.onSlideChange_);
}
}
}
/**
* Transitions to a slide, doing the scroll animation.
* @param {boolean} isMovingForward Whether we're going forward or backwards.
* @param {Slide} nextSlide Next slide.
* @param {Function} callback Callback to be called upon finishing. This is an
* async function so it'll happen once the scroll animation finishes.
* @private
* @see scrollTo
*/
scrollTransitionToSlide_(isMovingForward, nextSlide, callback) {
this.el.style.overflow = 'none';
if (!isMovingForward) {
nextSlide.moveBeforeFirst();
nextSlide.show();
scrollTo(this.currentSlide_.el.offsetTop, 0);
} else {
nextSlide.show();
}
scrollTo(nextSlide.el.offsetTop, 500, () => {
this.currentSlide_.hide();
if (isMovingForward) {
this.currentSlide_.moveAfterLast();
}
this.el.style.overflow = 'auto';
setTimeout(() => { callback.call(this, nextSlide); }, 150);
});
}
/**
* Transitions to a slide, without doing the scroll animation.
* @param {boolean} isMovingForward Whether we're going forward or backwards.
* @param {Slide} nextSlide Next slide.
* @param {Function} callback Callback to be called upon finishing. This is a
* sync function so it'll happen on run time.
* @private
*/
transitionToSlide_(isMovingForward, nextSlide, callback) {
scrollTo(0, 0);
if (!isMovingForward) {
nextSlide.moveBeforeFirst();
}
if (this.currentSlide_) {
if (isMovingForward) {
this.currentSlide_.moveAfterLast();
}
this.currentSlide_.hide();
}
nextSlide.show();
callback.call(this, nextSlide);
}
/**
* Whenever a slide is changed, this function gets called. It updates the
* references to the current slide, disables the moving flag and fires
* a custom event.
* @param {Slide} slide The slide we're transitioning to.
* @fires WebSlide#ws:slide-change
* @private
*/
onSlideChange_(slide) {
this.currentSlide_ = slide;
this.currentSlideI_ = slide.i;
this.isMoving = false;
DOM.fireEvent(this.el, 'ws:slide-change', {
slides: this.maxSlide_,
currentSlide0: this.currentSlideI_,
currentSlide: this.currentSlideI_ + 1
});
}
/**
* Goes to the next slide.
*/
goNext() {
let nextIndex = this.currentSlideI_ + 1;
if (nextIndex >= this.maxSlide_) {
nextIndex = 0;
}
this.goToSlide(nextIndex, true);
}
/**
* Goes to the previous slide.
*/
goPrev() {
let prevIndex = this.currentSlideI_ - 1;
if (prevIndex < 0) {
prevIndex = this.maxSlide_ - 1;
}
this.goToSlide(prevIndex, false);
}
/**
* Check if the given number is a valid index to go to.
* @param {number} i The index to check.
* @return {boolean} Whether you can move to that slide or not.
* @private
*/
isValidIndexSlide_(i) {
return i >= 0 && i < this.maxSlide_;
}
/**
* Init the shown slide on load. It'll fetch it from the Hash if present
* and, otherwise, it'll default to the first one.
* @private
* @see Hash.getSlideNumber
*/
initSlides_() {
let slideNumber = this.plugins.hash.constructor.getSlideNumber();
// Not valid
if (slideNumber === null ||
slideNumber >= this.maxSlide_) {
slideNumber = 0;
}
// Keeping the order
if (slideNumber !== 0) {
let i = 0;
while(i < slideNumber) {
this.slides[i].moveAfterLast();
i++;
}
}
this.goToSlide(slideNumber);
}
/**
* Registers a plugin to be loaded when the instance is created. It allows
* (on purpose) to replace default plugins.
* Those being:
* - Navigation
* - Hash
* - Keyboard
* @param {!string} key They key under which it'll be stored inside of the
* instance, inside the plugins dict.
* @param {!Function} cto Plugin constructor.
*/
static registerPlugin(key, cto) {
PLUGINS[key] = cto;
}
/**
* Starts autosliding all the slides if it's not currently doing it and the
* autoslide option was a number greater than 0.
* @param {?number} time Amount of milliseconds to wait to go to next slide
* automatically.
*/
play(time) {
time = time || this.options.autoslide;
if (!this.interval_ && typeof time === 'number' && time > 0) {
this.interval_ = setInterval(this.goNext.bind(this), time);
}
}
/**
* Stops autosliding all the slides.
*/
stop() {
if (this.interval_) {
clearInterval(this.interval_);
this.interval_ = null;
}
}
}

View File

@@ -0,0 +1,39 @@
const CLICKABLE_ELS = [
'INPUT',
'SELECT',
'OPTION',
'BUTTON',
'A',
'TEXTAREA'
];
export default class ClickNav {
/**
* ClickNav plugin that allows to click on the page to get to the next slide.
* @param {WebSlides} wsInstance The WebSlides instance
*/
constructor(wsInstance) {
/**
* @type {WebSlides}
* @private
*/
this.ws_ = wsInstance;
if (wsInstance.options.changeOnClick) {
this.ws_.el.addEventListener('click', this.onClick_.bind(this));
}
}
/**
* Reacts to the click event. It will go to the next slide unless the element
* has a data-prevent-nav attribute or is on the list of CLICKABLE_ELS.
* @param {MouseEvent} event The click event.
* @private
*/
onClick_(event) {
if (CLICKABLE_ELS.indexOf(event.target.tagName) < 0 &&
typeof event.target.dataset.preventNav === 'undefined') {
this.ws_.goNext();
}
}
}

44
src/js/plugins/grid.js Normal file
View File

@@ -0,0 +1,44 @@
import Keys from '../utils/keys';
export default class Grid {
/**
* Grid plugin that shows a grid on top of the WebSlides for easy prototyping.
* @param {WebSlides} wsInstance The WebSlides instance
*/
constructor(wsInstance) {
/**
* @type {WebSlides}
* @private
*/
this.ws_ = wsInstance;
const CSS = `body.baseline {
background: url(../images/baseline.png) left top .8rem/.8rem;
}`;
const head = document.head || document.getElementsByTagName('head')[0];
const style = document.createElement('style');
style.type = 'text/css';
if (style.styleSheet){
style.styleSheet.cssText = CSS;
} else {
style.appendChild(document.createTextNode(CSS));
}
head.appendChild(style);
document.addEventListener('keydown', this.onKeyPress_.bind(this), false);
}
/**
* Reacts to the keydown event. It reacts to ENTER key to toggle the class.
* @param {KeyboardEvent} event The key event.
* @private
*/
onKeyPress_(event) {
if (event.which === Keys.ENTER) {
document.body.toggleClass('baseline');
}
}
}

71
src/js/plugins/hash.js Normal file
View File

@@ -0,0 +1,71 @@
const HASH = '#slide';
const slideRegex = /#slide=(\d+)/;
/**
* Static class with methods to manipulate and extract info from the hash of
* the URL.
*/
export default class Hash {
/**
* Listens to the slide change event and the hash change events.
* @param wsInstance
*/
constructor(wsInstance) {
this.ws_ = wsInstance;
wsInstance.el.addEventListener('ws:slide-change', Hash.onSlideChange_);
window.addEventListener('hashchange', this.onHashChange_.bind(this), false);
}
/**
* hashchange event handler, makes the WebSlide instance navigate to the
* needed slide.
*/
onHashChange_() {
const newSlideIndex = Hash.getSlideNumber();
if (newSlideIndex !== null) {
this.ws_.goToSlide(newSlideIndex);
}
}
static onSlideChange_(event) {
Hash.setSlideNumber(event.detail.currentSlide);
}
/**
* Gets the slide number from the hash by a regex matching `#slide=` and gets
* the number after it. If the number is invalid or less than 0, it will
* return null as an invalid value.
* @return {?number}
*/
static getSlideNumber() {
let results = document.location.hash.match(slideRegex);
let slide = 0;
if (Array.isArray(results)) {
slide = parseInt(results[1], 10);
}
if (typeof slide !== 'number' || slide < 0 || !Array.isArray(results)) {
slide = null;
} else {
slide--; // Convert to 0 index
}
return slide;
}
/**
* It will update the hash (if it's different) so it reflects the slide
* number being visible.
* @param {number} number The number of the slide we're transitioning to.
*/
static setSlideNumber(number) {
if (Hash.getSlideNumber() !== (number - 1)) {
history.pushState({
slideI: number - 1
}, `Slide ${number}`, `${HASH}=${number}`);
}
}
}

View File

@@ -0,0 +1,74 @@
import Keys from '../utils/keys';
export default class Keyboard {
/**
* Keyboard interaction plugin.
* @param {WebSlides} wsInstance The WebSlides instance
*/
constructor(wsInstance) {
/**
* @type {WebSlides}
* @private
*/
this.ws_ = wsInstance;
document.addEventListener('keydown', this.onKeyPress_.bind(this), false);
}
/**
* Reacts to the keydown event. It reacts to the arrows and space key
* depending on the layout of the page.
* @param {KeyboardEvent} event The key event.
* @private
*/
onKeyPress_(event) {
let method;
let argument;
// Check if there's a focused element that might use the keyboard.
if (document.activeElement) {
const isContentEditable = document.activeElement
.contentEditable !== 'inherit';
const isInput = ['INPUT', 'SELECT', 'OPTION', 'TEXTAREA']
.indexOf(document.activeElement.tagName) > -1;
if (isInput || isContentEditable) {
return;
}
}
switch (event.which) {
case Keys.AV_PAGE:
case Keys.SPACE:
method = this.ws_.goNext;
break;
case Keys.RE_PAGE:
method = this.ws_.goPrev;
break;
case Keys.HOME:
method = this.ws_.goToSlide;
argument = 0;
break;
case Keys.END:
method = this.ws_.goToSlide;
argument = this.ws_.maxSlide_ - 1;
break;
case Keys.DOWN:
method = this.ws_.isVertical ? this.ws_.goNext : null;
break;
case Keys.UP:
method = this.ws_.isVertical ? this.ws_.goPrev : null;
break;
case Keys.LEFT:
method = !this.ws_.isVertical ? this.ws_.goPrev : null;
break;
case Keys.RIGHT:
method = !this.ws_.isVertical ? this.ws_.goNext : null;
break;
}
if (method) {
method.call(this.ws_, argument);
}
}
}

View File

@@ -0,0 +1,120 @@
import DOM from '../utils/dom';
const ELEMENT_ID = {
NAV: 'navigation',
NEXT: 'next',
PREV: 'previous',
COUNTER: 'counter'
};
const LABELS = {
VERTICAL: {
NEXT: '↓',
PREV: '↑'
},
HORIZONTAL: {
NEXT: '→',
PREV: '←'
}
};
export default class Navigation {
/**
* The Navigation constructor. It'll create all the nodes needed for the
* navigation such as the arrows and the counter.
* @param {WebSlides} wsInstance The WebSlides instance
*/
constructor(wsInstance) {
const arrowLabels = wsInstance.isVertical ?
LABELS.VERTICAL : LABELS.HORIZONTAL;
/**
* Navigation element.
* @type {Element}
*/
this.el = DOM.createNode('div', 'navigation');
/**
* Next button.
* @type {Element}
*/
this.next = Navigation.createArrow(ELEMENT_ID.NEXT, arrowLabels.NEXT);
/**
* Prev button.
* @type {Element}
*/
this.prev = Navigation.createArrow(ELEMENT_ID.PREV, arrowLabels.PREV);
/**
* Counter Element.
* @type {Element}
*/
this.counter = DOM.createNode('span', ELEMENT_ID.COUNTER);
/**
* @type {WebSlides}
* @private
*/
this.ws_ = wsInstance;
this.el.appendChild(this.next);
this.el.appendChild(this.prev);
this.el.appendChild(this.counter);
this.ws_.el.appendChild(this.el);
this.bindEvents_();
}
/**
* Bind all events for the navigation.
* @private
*/
bindEvents_() {
this.ws_.el.addEventListener(
'ws:slide-change', this.onSlideChanged_.bind(this));
this.next.addEventListener('click', this.onButtonClicked_.bind(this));
this.prev.addEventListener('click', this.onButtonClicked_.bind(this));
}
/**
* Updates the counter inside the navigation.
* @param {string|number} current Current slide number.
* @param {string|number} max Max slide number.
*/
updateCounter(current, max) {
this.counter.textContent = `${current} / ${max}`;
}
/**
* Creates an arrow to navigate.
* @param {!String} id Desired ID for the arrow.
* @param {!String} text Desired text for the arrow.
* @return {Element} The arrow element.
*/
static createArrow(id, text) {
const arrow = DOM.createNode('a', id, text);
arrow.href = '#';
arrow.title = 'Arrow Keys';
return arrow;
}
/**
* Slide Change event handler. Will update the text on the navigation.
* @param {CustomEvent} event
* @private
*/
onSlideChanged_(event) {
this.updateCounter(event.detail.currentSlide, event.detail.slides);
}
/**
* Handles clicks on the next/prev buttons.
* @param {MouseEvent} event
* @private
*/
onButtonClicked_(event) {
event.preventDefault();
if (event.target === this.next) {
this.ws_.goNext();
} else {
this.ws_.goPrev();
}
}
}

17
src/js/plugins/plugins.js Normal file
View File

@@ -0,0 +1,17 @@
import ClickNav from './click-nav';
import Grid from './grid';
import Hash from './hash';
import Keyboard from './keyboard';
import Navigation from './navigation';
import Scroll from './scroll';
import Touch from './touch';
export default {
ClickNav,
Grid,
Hash,
Keyboard,
Navigation,
Scroll,
Touch
};

103
src/js/plugins/scroll.js Normal file
View File

@@ -0,0 +1,103 @@
import MobileDetector from '../utils/mobile-detector';
export default class Scroll {
/**
* Scroll handler for the WebSlides.
* @param {WebSlides} wsInstance The WebSlides instance
*/
constructor(wsInstance) {
/**
* @type {WebSlides}
* @private
*/
this.ws_ = wsInstance;
/**
* Where the scroll is going to happen. The WebSlides element.
* @type {Element}
* @private
*/
this.scrollContainer_ = wsInstance.el;
/**
* Whether movement is happening up or down.
* @type {boolean}
* @private
*/
this.isGoingUp_ = false;
/**
* Whether movement is happening left or right.
* @type {boolean}
* @private
*/
this.isGoingLeft_ = false;
/**
* Timeout id holder.
* @type {?number}
* @private
*/
this.timeout_ = null;
if (!MobileDetector.isAny()) {
this.scrollContainer_.addEventListener(
'wheel', this.onMouseWheel_.bind(this));
if (!wsInstance.isVertical) {
wsInstance.el.addEventListener(
'ws:slide-change', this.onSlideChange_.bind(this));
}
}
}
/**
* When the slides change, set an inner timeout to avoid prematurely
* changing to the next slide again.
* @private
*/
onSlideChange_() {
this.timeout_ = setTimeout(
() => { this.timeout_ = null; },
this.ws_.options.scrollWait);
}
/**
* Reacts to the wheel event. Detects whether is going up or down and decides
* if it needs to move the slide based on the amount of delta.
* @param {WheelEvent} event The Wheel Event.
* @private
*/
onMouseWheel_(event) {
if (this.ws_.isMoving || this.timeout_) {
event.preventDefault();
return;
}
const { deltaY: wheelDeltaY, deltaX: wheelDeltaX } = event;
const isVertical = this.ws_.isVertical;
const isHorizontalMovement = Math.abs(wheelDeltaX) > Math.abs(wheelDeltaY);
this.isGoingUp_ = wheelDeltaY < 0;
this.isGoingLeft_ = wheelDeltaX < 0;
// If we're mainly moving horizontally, prevent default
if (isHorizontalMovement) {
if (!isVertical) {
event.preventDefault();
} else {
// If we're moving horizontally but this is vertical, return to avoid
// unwanted navigation.
return;
}
}
if (Math.abs(wheelDeltaY) >= this.ws_.options.minWheelDelta ||
Math.abs(wheelDeltaX) >= this.ws_.options.minWheelDelta) {
if ((isHorizontalMovement && this.isGoingLeft_) ||
(!isHorizontalMovement && this.isGoingUp_)) {
this.ws_.goPrev();
} else {
this.ws_.goNext();
}
event.preventDefault();
}
}
};

149
src/js/plugins/touch.js Normal file
View File

@@ -0,0 +1,149 @@
import MobileDetector from '../utils/mobile-detector';
const EVENTS = {
touch: {
START: 'touchstart',
MOVE: 'touchmove',
END: 'touchend'
},
pointer: {
START: 'pointerdown',
MOVE: 'pointermove',
END: 'pointerup'
}
};
export default class Touch {
/**
* @param {WebSlides} wsInstance The WebSlides instance
*/
constructor(wsInstance) {
/**
* @type {WebSlides}
* @private
*/
this.ws_ = wsInstance;
/**
* Start position for the X coord.
* @type {number}
* @private
*/
this.startX_ = 0;
/**
* Start position for the Y coord.
* @type {number}
* @private
*/
this.startY_ = 0;
/**
* Start position for the X coord.
* @type {number}
* @private
*/
this.endX_ = 0;
/**
* Start position for the Y coord.
* @type {number}
* @private
*/
this.endY_ = 0;
/**
* Whether is enabled or not. Only enabled for touch devices.
* @type {boolean}
* @private
*/
this.isEnabled = false;
let events;
if (MobileDetector.isAny()) {
// Likely IE
if (window.PointerEvent && (
MobileDetector.isWindows() || MobileDetector.isWindowsPhone())) {
events = EVENTS.pointer;
} else {
events = EVENTS.touch;
}
this.isEnabled = true;
document.addEventListener(events.START, this.onStart_.bind(this), false);
document.addEventListener(events.MOVE, this.onMove_.bind(this), false);
document.addEventListener(events.MOVE, this.onMove_.bind(this), false);
document.addEventListener(events.END, this.onStop_.bind(this), false);
}
}
/**
* Start touch handler. Saves starting points.
* @param event
* @private
*/
onStart_(event) {
const info = Touch.normalizeEventInfo(event);
this.startX_ = info.x;
this.startY_ = info.y;
this.endX_ = info.x;
this.endY_ = info.y;
}
/**
* Move touch handler. Saves end points.
* @param event
* @private
*/
onMove_(event) {
const info = Touch.normalizeEventInfo(event);
this.endX_ = info.x;
this.endY_ = info.y;
}
/**
* Stop touch handler. Checks if it needs to make any actions.
* @private
*/
onStop_() {
const diffX = this.startX_ - this.endX_;
const diffY = this.startY_ - this.endY_;
// It's an horizontal drag
if (Math.abs(diffX) > Math.abs(diffY)) {
if (diffX < -this.ws_.options.slideOffset) {
this.ws_.goPrev();
} else if(diffX > this.ws_.options.slideOffset) {
this.ws_.goNext();
}
}
}
/**
* Normalizes an event to deal with differences between PointerEvent and
* TouchEvent.
* @param event
* @return {*}
*/
static normalizeEventInfo(event) {
let x;
let y;
let touchEvent = { pageX : 0, pageY : 0};
if (typeof event.changedTouches !== 'undefined'){
touchEvent = event.changedTouches[0];
}
else if (typeof event.originalEvent !== 'undefined' &&
typeof event.originalEvent.changedTouches !== 'undefined'){
touchEvent = event.originalEvent.changedTouches[0];
}
x = event.offsetX || event.layerX || touchEvent.pageX;
y = event.offsetY || event.layerY || touchEvent.pageY;
return { x, y };
}
};

View File

@@ -0,0 +1,38 @@
const NativeCustomEvent = window.CustomEvent;
/**
* Check for the usage of native support for CustomEvents which is lacking
* completely on IE.
* @return {boolean} Whether it can be used or not.
*/
function canIuseNativeCustom () {
try {
const p = new NativeCustomEvent('t', { detail: { a: 'b' } });
return 't' === p.type && 'b' === p.detail.a;
} catch (e) {
}
return false;
}
/**
* Lousy polyfill for the Custom Event constructor for IE.
* @param {!string} type The type of the event.
* @param {?Object} params Additional information for the event.
* @return {Event}
* @constructor
*/
const IECustomEvent = function CustomEvent(type, params) {
const e = document.createEvent('CustomEvent');
if (params) {
e.initCustomEvent(type, params.bubbles, params.cancelable, params.detail);
} else {
e.initCustomEvent(type, false, false, undefined);
}
return e;
};
const WSCustomEvent = canIuseNativeCustom() ? NativeCustomEvent : IECustomEvent;
export default WSCustomEvent;

68
src/js/utils/dom.js Normal file
View File

@@ -0,0 +1,68 @@
import WSCustomEvent from './custom-event';
/**
* Static class for DOM helper.
*/
export default class DOM {
/**
* Creates a node with optional parameters.
* @param {string} tag The name of the tag of the needed element.
* @param {string} id The desired id for the element. It defaults to an
* empty string.
* @param {string} text The desired text to go inside of the element. It defaults
* to an empty string.
* @return {Element}
*/
static createNode(tag, id = '', text = '') {
const node = document.createElement(tag);
node.id = id;
if (text) {
node.textContent = text;
}
return node;
}
/**
* Hides an element setting the display to none.
* @param {Element} el Element to be hidden.
*/
static hide(el) {
el.style.display = 'none';
}
/**
* Shows an element by removing the display property. This is only intended
* to be used in conjunction with DOM.hide.
* @param {Element} el Element to be shown.
*/
static show(el) {
el.style.display = '';
}
/**
* Fires a custom event on the given target.
* @param {Element} target The target of the event.
* @param {string} eventType The event type.
* @param {Object} eventInfo Optional parameter to provide additional data
* to the event.
*/
static fireEvent(target, eventType, eventInfo = {}) {
const event = new WSCustomEvent(eventType, {
detail: eventInfo
});
target.dispatchEvent(event);
}
/**
* Converts an iterable to an array.
* @param {*} iterable Element to convert to array
* @return {Array} the element casted to an array.
*/
static toArray(iterable) {
return [].slice.call(iterable);
}
}

19
src/js/utils/easing.js Normal file
View File

@@ -0,0 +1,19 @@
/**
* Swing easing function.
* @param {number} p The percentage of time that has passed.
* @return {number}
*/
function swing (p) {
return 0.5 - Math.cos(p * Math.PI) / 2;
}
/**
* Linear easing function.
* @param {number} p The percentage of time that has passed.
* @return {number}
*/
function linear(p) {
return p;
}
export default { swing, linear };

14
src/js/utils/keys.js Normal file
View File

@@ -0,0 +1,14 @@
const Keys = {
ENTER: 13,
SPACE: 32,
RE_PAGE: 33,
AV_PAGE: 34,
END: 35,
HOME: 36,
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40
};
export default Keys;

View File

@@ -0,0 +1,64 @@
const UA = window.navigator.userAgent;
export default class MobileDetector {
/**
* Whether the device is Android or not.
* @return {Boolean}
*/
static isAndroid() {
return !!UA.match(/Android/i);
}
/**
* Whether the device is BlackBerry or not.
* @return {Boolean}
*/
static isBlackBerry() {
return !!UA.match(/BlackBerry/i);
}
/**
* Whether the device is iOS or not.
* @return {Boolean}
*/
static isiOS() {
return !!UA.match(/iPhone/i);
}
/**
* Whether the device is Opera or not.
* @return {Boolean}
*/
static isOpera() {
return !!UA.match(/Opera Mini/i);
}
/**
* Whether the device is Windows or not.
* @return {Boolean}
*/
static isWindows() {
return !!UA.match(/IEMobile/i);
}
/**
* Whether the device is Windows Phone or not.
* @return {Boolean}
*/
static isWindowsPhone() {
return !!UA.match(/Windows Phone/i);
}
/**
* Whether the device is any mobile device or not.
* @return {Boolean}
*/
static isAny() {
return MobileDetector.isAndroid() ||
MobileDetector.isBlackBerry() ||
MobileDetector.isiOS() ||
MobileDetector.isOpera() ||
MobileDetector.isWindows() ||
MobileDetector.isWindowsPhone();
}
}

44
src/js/utils/scroll-to.js Normal file
View File

@@ -0,0 +1,44 @@
import Easings from './easing';
let SCROLLABLE_CONTAINER = document.getElementById('webslides');
/**
* Smoothly scrolls to a given Y position using Easing.Swing. It'll run a
* callback upon finishing.
* @param {number} y Offset of the page to scroll to.
* @param {number} duration Duration of the animation. 500ms by default.
* @param {function} cb Callback function to call upon completion.
*/
export default function scrollTo(y, duration = 500, cb = () => {}) {
const delta = y - SCROLLABLE_CONTAINER.scrollTop;
const startLocation = SCROLLABLE_CONTAINER.scrollTop;
const increment = 16;
if (!duration) {
SCROLLABLE_CONTAINER.scrollTop = y;
cb();
return;
}
const animateScroll = elapsedTime => {
elapsedTime += increment;
const percent = Math.min(1, elapsedTime / duration);
const easingP = Easings.swing(
percent,
elapsedTime * percent,
y,
delta,
duration);
SCROLLABLE_CONTAINER.scrollTop = Math.floor(startLocation +
(easingP * delta));
if (elapsedTime < duration) {
setTimeout(() => animateScroll(elapsedTime), increment);
} else {
cb();
}
};
animateScroll(0);
}

File diff suppressed because it is too large Load Diff

View File

@@ -81,27 +81,27 @@ hr:after {
color: #333;
}
bbbr,
abbr,
acronym {
border-bottom: 1px dotted #333;
}
mark,
ins {
background-color: rgba(221,238,255, 0.8);
color: inherit;
background-color: rgba(221,238,255, 0.8);
color: inherit;
}
::-moz-selection {
background-color: rgba(221,238,255, 0.8);
background-color: rgba(221,238,255, 0.8);
}
::-webkit-selection {
background-color: rgba(221,238,255, 0.8);
background-color: rgba(221,238,255, 0.8);
}
::selection {
background-color: rgba(221,238,255, 0.8);
background-color: rgba(221,238,255, 0.8);
}
pre {
@@ -119,7 +119,7 @@ code,[class*="bg-"] pre {
}
.bg-white code{
background: rgba(0, 20, 80, 0.03);
background: rgba(0, 20, 80, 0.03);
}
/*================================================
Slides - Backgrounds <section class="bg-primary">
@@ -218,7 +218,7 @@ Slides - Backgrounds <section class="bg-primary">
/*Covers/Longforms...*/
.bg-trans-gradient{
background: linear-gradient(to top, rgba(0,0,0,0.8) 0%,rgba(0,0,0,0) 100%);
background: linear-gradient(to top, rgba(0,0,0,0.8) 0%,rgba(0,0,0,0) 100%);
}
/*Horizontal Gradient*/
@@ -250,9 +250,9 @@ background: linear-gradient(to top, rgba(0,0,0,0.8) 0%,rgba(0,0,0,0) 100%);
/*Gray Gradient (horizontal)*/
.bg-gradient-gray{
background: linear-gradient(90deg,#f7f9fb 0,#dee2e6 100%);
color: #333;
text-shadow: none;
background: linear-gradient(90deg,#f7f9fb 0,#dee2e6 100%);
color: #333;
text-shadow: none;
}
/*Border/Frame*/
.frame {
@@ -261,7 +261,7 @@ text-shadow: none;
/*Layer/Box Shadow*/
.shadow,.pre {
position: relative;
position: relative;
}
.shadow:before,.shadow:after {
box-shadow: 0 16px 24px rgba(0, 20, 80, 0.3);
@@ -274,13 +274,13 @@ TYPOGRAPHY
/* -- Horizontal separator -- */
.text-separator:before {
background-color: rgba(170, 0, 0, 0.8);
background-color: rgba(170, 0, 0, 0.8);
}
/* -- Pull Quote (Right/Left) -- */
[class*="text-pull-"] {
border-top: 4px solid rgba(0, 0, 0, 0.5);
border-top: 4px solid rgba(0, 0, 0, 0.5);
}
/* -- Context -- */
@@ -374,7 +374,7 @@ nav li.email a:hover {
}
/*=========================================
Features & Clients List
Features & Clients List
=========================================== */
.features li,.clients li {
@@ -387,7 +387,7 @@ Features & Clients List
}
.features li:hover,.clients li:hover {
box-shadow: 0 8px 16px rgba(0,20,80,.02),0 4px 16px rgba(0,0,0,.08);
box-shadow: 0 8px 16px rgba(0,20,80,.02),0 4px 16px rgba(0,0,0,.08);
}
/*.features li span,.features li svg{color: #44d;}*/
@@ -410,7 +410,7 @@ box-shadow: 0 8px 16px rgba(0,20,80,.02),0 4px 16px rgba(0,0,0,.08);
}
/*===========================================
flexblock.steps
flexblock.steps
============================================= */
.steps li:nth-child(1) {
@@ -519,7 +519,7 @@ Gallery li+.overlay+image
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 4px 8px rgba(0, 0, 0, 0.08);
}
.gallery li footer {
border-top:1px solid rgba(0,20,80,0.1);
border-top:1px solid rgba(0,20,80,0.1);
}
.gallery li a {
@@ -684,7 +684,7 @@ Cards
/*== Figure Background === */
[class*="card-"][class*="bg-"] figure {
background-color: rgba(0, 20, 80, 0.06);
background-color: rgba(0, 20, 80, 0.06);
}
/*== Ficaption Cards === */
@@ -703,7 +703,7 @@ background-color: rgba(0, 20, 80, 0.06);
border-image: linear-gradient(90deg, transparent, rgba(0, 0, 0, 0.4) 50%, transparent) 1 100%;
-webkit-border-image: -webkit-linear-gradient(90deg, transparent, rgba(0, 0, 0, 0.4) 50%, transparent) 1 100%;
-moz-border-image: -moz-linear-gradient(90deg, transparent, rgba(0, 0, 0, 0.4) 50%, transparent) 1 100%;
}
}
@@ -737,7 +737,7 @@ tr:nth-child(even)>td:hover {
/*============================
Browser (Screenshots)
Browser (Screenshots)
============================== */
.browser {
@@ -783,10 +783,10 @@ input:focus::-moz-placeholder {
input:focus::-webkit-input-placeholder {
color: #ddd;
}
a.button,[class*="badge-"]
a.button,[class*="badge-"],
button[type="submit"],
input {
box-shadow: 0px 10px 16px -8px rgba(0, 20, 80, 0.3);
box-shadow: 0 10px 16px -8px rgba(0, 20, 80, 0.3);
}
button,
@@ -797,7 +797,7 @@ button[type="submit"],
input[type="submit"],
.button,.button:hover,
button[type="submit"]:hover,
input[type="submit"]:hover
input[type="submit"]:hover
{
border: 1px solid #44d;
}
@@ -810,7 +810,7 @@ input[type="submit"],
text-shadow: 0 1px 0 #123;
}
.button:active,button[type="submit"]:active,input[type="submit"]:active {
background-color: #17d;
background-color: #17d;
}
.ghost,.ghost:hover {background: none;color: inherit;text-shadow: none;}
.bg-primary select,
@@ -818,7 +818,7 @@ background-color: #17d;
.bg-primary .button,
.bg-primary button,.bg-primary button:hover,
.bg-primary input,
[class*="bg-gradient-"] .button,[class*="bg-"] a.button.ghost
[class*="bg-gradient-"] .button,[class*="bg-"] a.button.ghost
{
border-color: #fff;
}

File diff suppressed because it is too large Load Diff

9
static/js/webslides.min.js vendored Normal file

File diff suppressed because one or more lines are too long

37
webpack.config.babel.js Normal file
View File

@@ -0,0 +1,37 @@
const SmartBannerPlugin = require('smart-banner-webpack-plugin');
const path = require('path');
const src = path.join(__dirname, 'src');
const pkg = require('./package.json');
module.exports = {
context: src,
entry: {
webslides: './js/full.js'
},
output: {
filename: '[name].js',
path: path.join(__dirname, 'static/js'),
publicPath: '/static/js/'
},
devServer: {
contentBase: __dirname,
host: '0.0.0.0'
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
include: src
}
]
},
plugins: [
new SmartBannerPlugin({
banner: `Name: WebSlides\nVersion: ${pkg.version}\nDate: ${new Date().toISOString().slice(0,10)}\nDescription: ${pkg.description}\nURL: ${pkg.homepage}\nCredits: @jlantunez, @LuisSacristan, @Belelros`,
raw: false,
entryOnly: true
})
],
};