Compare commits
35 Commits
Author | SHA1 | Date | |
---|---|---|---|
e3baa43b22 | |||
7a332f29ea | |||
14c21422e7 | |||
fe411b1ede | |||
4f02e2d6e7 | |||
4719766843 | |||
85600ef685 | |||
f7edd84125 | |||
27e3583fbc | |||
12d1a03bc4 | |||
d3028b9a03 | |||
2385291886 | |||
cb0b22574a | |||
4a1adf92e2 | |||
b077bb9f5f | |||
68c4b52dfa | |||
81ad9cf6f7 | |||
024706f2ff | |||
57b3b9e3f6 | |||
6c8d118f83 | |||
e26694c322 | |||
d41249bd90 | |||
833d3ac36f | |||
fdaeecbb06 | |||
70297321c3 | |||
a02609c3e3 | |||
ffebc7b077 | |||
c7c7902769 | |||
5bb4d70cf7 | |||
67b2f2510b | |||
ba9434b6f2 | |||
26469452e1 | |||
6ae2655923 | |||
815100cff8 | |||
58342cfae8 |
2
.gitignore
vendored
@ -5,5 +5,5 @@ node_modules
|
||||
aws.json
|
||||
docs/index.dev.html
|
||||
*.mp4
|
||||
index-dev.html
|
||||
notes.txt
|
||||
npm-debug.log
|
||||
|
@ -17,7 +17,7 @@
|
||||
"dist/plyr.js",
|
||||
"dist/sprite.svg",
|
||||
"src/less/plyr.less",
|
||||
"src/sass/plyr.scss",
|
||||
"src/scss/plyr.scss",
|
||||
"src/js/plyr.js"
|
||||
],
|
||||
"ignore": [
|
||||
|
@ -3,8 +3,8 @@
|
||||
"less": {
|
||||
"plyr.css": ["src/less/plyr.less"]
|
||||
},
|
||||
"sass": {
|
||||
"plyr.css": ["src/sass/plyr.sass"]
|
||||
"scss": {
|
||||
"plyr.css": ["src/scss/plyr.scss"]
|
||||
},
|
||||
"js": {
|
||||
"plyr.js": ["src/js/plyr.js"]
|
||||
|
25
changelog.md
@ -1,9 +1,32 @@
|
||||
# Changelog
|
||||
|
||||
## v1.6.0
|
||||
- New, cleaner, UI:
|
||||
- Controls are now overlaid, maintaining the video's ratio and making sizing easier
|
||||
- A large play button can now be overlaid over videos
|
||||
- Default number of control buttons reduced
|
||||
- New play, pause, rewind and fast forward icons
|
||||
- Flexbox all the things!
|
||||
- Tidied up the LESS (and SCSS) as part of the above, variables and mixins in seprate files amking customization and upgrades easier
|
||||
- Toggle mute bug fix; if a player was muted previously and the user refreshed, unmuting would have meant volume was still zero (effectively muted), now the config default value is used. Not ideal but good for now
|
||||
- New `iconUrl` option allowing specifying a same origin SVG sprite location. Loading this way means you don't need the AJAX sprite loading JavaScript
|
||||
- `click` option renamed to `clickToPlay` to make it a bit more self explanatory. Unfortunately cross origin SVG sprites is not supported in any browser yet :-(
|
||||
- `hideControls` is now a global option, rather than being exclusive to fullscreen. Controls are now hidden after 2 seconds of no mouse movement. Controls are always shown when media is paused or stopped. This is defaulted to true.
|
||||
- `sass` folder in `src` renamed from to `scss`
|
||||
|
||||
## v1.5.21
|
||||
- Bug fix for embeds: `play` not being defined (fixes #185 and #186)
|
||||
|
||||
## v1.5.20
|
||||
- Bug fix for autoplay option
|
||||
|
||||
## v1.5.19
|
||||
- Fix for accessing `embed` property after `ready` event fired
|
||||
|
||||
## v1.5.18
|
||||
- Added 'ready' event for initial setup complete or source change occurs
|
||||
- Fixed SASS stylesheet references to transparentize
|
||||
- Added default font stack to controls
|
||||
- Added default font stack to controls
|
||||
- Docs fixes inc controls HTML (fixes #180)
|
||||
|
||||
## v1.5.17
|
||||
|
102
controls.md
@ -15,7 +15,6 @@ i18n: {
|
||||
play: "Play",
|
||||
pause: "Pause",
|
||||
forward: "Forward {seektime} secs",
|
||||
played: "played",
|
||||
buffered: "buffered",
|
||||
currentTime: "Current time",
|
||||
duration: "Duration",
|
||||
@ -47,67 +46,64 @@ This is an example `html` option with all controls.
|
||||
|
||||
```javascript
|
||||
var controls = ["<div class='plyr__controls'>",
|
||||
"<div class='plyr__progress'>",
|
||||
"<button type='button' data-plyr='restart'>",
|
||||
"<svg><use xlink:href='#icon-restart'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Restart</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-plyr='rewind'>",
|
||||
"<svg><use xlink:href='#icon-rewind'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Rewind {seektime} secs</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-plyr='play'>",
|
||||
"<svg><use xlink:href='#icon-play'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Play</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-plyr='pause'>",
|
||||
"<svg><use xlink:href='#icon-pause'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Pause</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-plyr='fast-forward'>",
|
||||
"<svg><use xlink:href='#icon-fast-forward'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Forward {seektime} secs</span>",
|
||||
"</button>",
|
||||
"<span class='plyr__progress'>",
|
||||
"<label for='seek{id}' class='plyr__sr-only'>Seek</label>",
|
||||
"<input id='seek{id}' class='plyr__progress--seek' type='range' min='0' max='100' step='0.1' value='0' data-plyr='seek'>",
|
||||
"<progress class='plyr__progress--played' max='100' value='0'>",
|
||||
"<span>0</span>% played",
|
||||
"</progress>",
|
||||
"<progress class='plyr__progress--played' max='100' value='0' role='presentation'></progress>",
|
||||
"<progress class='plyr__progress--buffer' max='100' value='0'>",
|
||||
"<span>0</span>% buffered",
|
||||
"</progress>",
|
||||
"<span class='plyr__tooltip'>00:00</span>",
|
||||
"</div>",
|
||||
"<span class='plyr__controls--left'>",
|
||||
"<button type='button' data-plyr='restart'>",
|
||||
"<svg><use xlink:href='#icon-restart'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Restart</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-plyr='rewind'>",
|
||||
"<svg><use xlink:href='#icon-rewind'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Rewind {seektime} secs</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-plyr='play'>",
|
||||
"<svg><use xlink:href='#icon-play'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Play</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-plyr='pause'>",
|
||||
"<svg><use xlink:href='#icon-pause'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Pause</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-plyr='fast-forward'>",
|
||||
"<svg><use xlink:href='#icon-fast-forward'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Forward {seektime} secs</span>",
|
||||
"</button>",
|
||||
"<span class='plyr__time'>",
|
||||
"<span class='plyr__sr-only'>Current time</span>",
|
||||
"<span class='plyr__time--curent'>00:00</span>",
|
||||
"</span>",
|
||||
"<span class='plyr__time'>",
|
||||
"<span class='plyr__sr-only'>Duration</span>",
|
||||
"<span class='plyr__time--duration'>00:00</span>",
|
||||
"</span>",
|
||||
"</span>",
|
||||
"<span class='plyr__controls--right'>",
|
||||
"<button type='button' data-plyr='mute'>",
|
||||
"<svg class='icon--muted'><use xlink:href='#icon-muted'></use></svg>",
|
||||
"<svg><use xlink:href='#icon-volume'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Toggle Mute</span>",
|
||||
"</button>",
|
||||
"<span class='plyr__time'>",
|
||||
"<span class='plyr__sr-only'>Current time</span>",
|
||||
"<span class='plyr__time--current'>00:00</span>",
|
||||
"</span>",
|
||||
"<span class='plyr__time'>",
|
||||
"<span class='plyr__sr-only'>Duration</span>",
|
||||
"<span class='plyr__time--duration'>00:00</span>",
|
||||
"</span>",
|
||||
"<button type='button' data-plyr='mute'>",
|
||||
"<svg class='icon--muted'><use xlink:href='#icon-muted'></use></svg>",
|
||||
"<svg><use xlink:href='#icon-volume'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Toggle Mute</span>",
|
||||
"</button>",
|
||||
"<span class='plyr__volume'>",
|
||||
"<label for='volume{id}' class='plyr__sr-only'>Volume</label>",
|
||||
"<input id='volume{id}' class='plyr__volume' type='range' min='0' max='10' value='5' data-plyr='volume'>",
|
||||
"<button type='button' data-plyr='captions'>",
|
||||
"<svg class='icon--captions-on'><use xlink:href='#icon-captions-on'></use></svg>",
|
||||
"<svg><use xlink:href='#icon-captions-off'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Toggle Captions</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-plyr='fullscreen'>",
|
||||
"<svg class='icon--exit-fullscreen'><use xlink:href='#icon-exit-fullscreen'></use></svg>",
|
||||
"<svg><use xlink:href='#icon-enter-fullscreen'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Toggle Fullscreen</span>",
|
||||
"</button>",
|
||||
"<input id='volume{id}' class='plyr__volume--input' type='range' min='0' max='10' value='5' data-plyr='volume'>",
|
||||
"<progress class='plyr__volume--display' max='10' value='0' role='presentation'></progress>",
|
||||
"</span>",
|
||||
"</div>"].join("\n");
|
||||
"<button type='button' data-plyr='captions'>",
|
||||
"<svg class='icon--captions-on'><use xlink:href='#icon-captions-on'></use></svg>",
|
||||
"<svg><use xlink:href='#icon-captions-off'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Toggle Captions</span>",
|
||||
"</button>",
|
||||
"<button type='button' data-plyr='fullscreen'>",
|
||||
"<svg class='icon--exit-fullscreen'><use xlink:href='#icon-exit-fullscreen'></use></svg>",
|
||||
"<svg><use xlink:href='#icon-enter-fullscreen'></use></svg>",
|
||||
"<span class='plyr__sr-only'>Toggle Fullscreen</span>",
|
||||
"</button>",
|
||||
"</div>"].join("");
|
||||
|
||||
// Setup the player
|
||||
plyr.setup('.js-player', {
|
||||
|
2
dist/plyr.css
vendored
4
dist/plyr.js
vendored
2
dist/sprite.svg
vendored
@ -1 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg"><symbol id="icon-captions-off" viewBox="0 0 18 18"><path d="M1 2c-.552 0-1 .448-1 1v12c0 .552.448 1 1 1h16c.552 0 1-.448 1-1V3c0-.552-.448-1-1-1H1zm1 12V4h14v10H2z"/></symbol><symbol id="icon-captions-on" viewBox="0 0 18 18"><path d="M1 2c-.552 0-1 .448-1 1v12c0 .552.448 1 1 1h16c.552 0 1-.448 1-1V3c0-.552-.448-1-1-1H1zm1 12V4h14v10H2z"/><path d="M3 11h3v2H3zM12 11h3v2h-3zM7 11h4v2H7z"/></symbol><symbol id="icon-enter-fullscreen" viewBox="0 0 18 18"><path d="M10.3 9.7c.7.677 1.4 0 1.4 0L16 5.4V10h2V3c0-.6-.4-1-1-1h-7v2h4.6l-4.3 4.3s-.7.723 0 1.4z"/><path d="M7 2v2H2v10h14v-1h2v2c0 .6-.4 1-1 1H1c-.6 0-1-.4-1-1V3c0-.6.4-1 1-1h6z"/></symbol><symbol id="icon-exit-fullscreen" viewBox="0 0 18 18"><path d="M7.7 8.3c-.7-.677-1.4 0-1.4 0L2 12.6V8H0v7c0 .6.4 1 1 1h7v-2H3.4l4.3-4.3s.7-.723 0-1.4z"/><path d="M11 16v-2h5V4H2v1H0V3c0-.6.4-1 1-1h16c.6 0 1 .4 1 1v12c0 .6-.4 1-1 1h-6z"/></symbol><symbol id="icon-fast-forward" viewBox="0 0 18 18"><path d="M17.57 8.246L7 2c-.552 0-1 .448-1 1v1.954L1 2c-.552 0-1 .448-1 1v12c0 .552.448 1 1 1l5-2.955V15c0 .552.448 1 1 1l10.57-6.246c.266-.158.43-.444.43-.754s-.164-.597-.43-.754zM6 10.722l-4 2.364V4.914l4 2.364v3.444zm2 2.364V4.914L14.915 9 8 13.086z"/></symbol><symbol id="icon-muted" viewBox="0 0 18 18"><path d="M9.214 2c-.11 0-.225.032-.334.1L4.832 4.91C4.75 4.97 4.65 5 4.55 5H.995C.446 5 0 5.448 0 6v6c0 .552.446 1 .996 1H4.55c.1 0 .2.03.282.09L8.88 15.9c.11.068.223.1.334.1.392 0 .747-.4.747-.95V2.95c0-.55-.354-.95-.746-.95zM7.97 12.834L5.58 11.177c-.166-.115-.364-.178-.566-.178H2.49c-.274 0-.497-.225-.497-.5v-3c0-.277.223-.5.498-.5h2.526c.202 0 .4-.063.566-.18L7.97 5.165v7.67zM14.934 8.8c-.086-1.75-1.514-2.992-2.507-3.65-.47-.312-1.094-.122-1.325.408l-.038.086c-.188.43-.045.94.336 1.194.706.473 1.586 1.247 1.624 2.065.032.676-.553 1.468-1.663 2.27-.397.288-.528.84-.284 1.275l.042.075c.266.475.866.624 1.3.312 1.74-1.25 2.586-2.606 2.516-4.037z"/><path d="M13.957 9.2c.086 1.747 1.514 2.99 2.507 3.648.47.312 1.094.122 1.325-.408l.037-.086c.188-.43.045-.94-.336-1.194-.705-.473-1.585-1.247-1.623-2.065-.032-.676.553-1.468 1.663-2.27.398-.288.53-.84.285-1.275l-.042-.075c-.266-.475-.866-.624-1.3-.312-1.74 1.25-2.586 2.606-2.516 4.037z"/></symbol><symbol id="icon-pause" viewBox="0 0 18 18"><path d="M2 4v10c0 2 2 2 2 2h2s2 0 2-2V4c0-2-2-2-2-2H4S2 2 2 4zm2 0h2v10H4V4zM10 4v10c0 2 2 2 2 2h2s2 0 2-2V4c0-2-2-2-2-2h-2s-2 0-2 2zm2 0h2v10h-2V4z"/></symbol><symbol id="icon-play" viewBox="0 0 18 18"><path d="M5 4.914L11.915 9 5 13.086V4.914zM4 2c-.552 0-1 .448-1 1v12c0 .552.448 1 1 1l10.57-6.246c.266-.158.43-.444.43-.754s-.164-.597-.43-.754L4 2z"/></symbol><symbol id="icon-restart" viewBox="0 0 16 16"><path d="M7.7 1.2l.7 6.4 2.1-2.1c1.9 1.9 1.9 5.1 0 7-.9 1-2.2 1.5-3.5 1.5-1.3 0-2.6-.5-3.5-1.5-1.9-1.9-1.9-5.1 0-7 .6-.6 1.4-1.1 2.3-1.3l-.6-1.9C4 2.6 2.9 3.2 2 4.1-.7 6.8-.7 11.2 2 14c1.3 1.3 3.1 2 4.9 2 1.9 0 3.6-.7 4.9-2 2.7-2.7 2.7-7.1 0-9.9L14 1.9l-6.3-.7z"/></symbol><symbol id="icon-rewind" viewBox="0 0 18 21"><path d="M.43 10.754L11 17c.552 0 1-.448 1-1v-1.954L17 17c.552 0 1-.448 1-1V4c0-.552-.448-1-1-1l-5 2.955V4c0-.552-.448-1-1-1L.43 9.246C.165 9.404 0 9.69 0 10s.164.597.43.754zM12 8.278l4-2.364v8.172l-4-2.364V8.278zm-2-2.364v8.172L3.085 10 10 5.914z"/></symbol><symbol id="icon-volume" viewBox="0 0 18 18"><path d="M10.214 2c-.11 0-.225.032-.334.1L5.832 4.91C5.75 4.97 5.65 5 5.55 5H1.995C1.446 5 1 5.448 1 6v6c0 .552.446 1 .996 1H5.55c.1 0 .2.03.282.09L9.88 15.9c.11.068.223.1.334.1.392 0 .747-.4.747-.95V2.95c0-.55-.354-.95-.746-.95zM8.97 12.834L6.58 11.177c-.166-.115-.364-.178-.566-.178H3.49c-.274 0-.497-.225-.497-.5v-3c0-.277.223-.5.498-.5h2.526c.202 0 .4-.063.566-.18L8.97 5.165v7.67zM16.934 8.8c-.086-1.75-1.514-2.992-2.507-3.65-.47-.312-1.094-.122-1.325.408l-.038.086c-.188.43-.045.94.336 1.194.706.473 1.586 1.247 1.624 2.065.032.676-.553 1.468-1.663 2.27-.397.288-.528.84-.284 1.275l.042.075c.266.475.866.624 1.3.312 1.74-1.25 2.586-2.606 2.516-4.037z"/></symbol></svg>
|
||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg"><symbol id="icon-captions-off" viewBox="0 0 18 18"><path d="M1 2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H1zm1 12V4h14v10H2z"/></symbol><symbol id="icon-captions-on" viewBox="0 0 18 18"><path d="M1 2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H1zm1 12V4h14v10H2z"/><path d="M3 11h3v2H3zM12 11h3v2h-3zM7 11h4v2H7z"/></symbol><symbol id="icon-enter-fullscreen" viewBox="0 0 18 18"><path d="M10.3 9.7c.7.677 1.4 0 1.4 0L16 5.4V10h2V3c0-.6-.4-1-1-1h-7v2h4.6l-4.3 4.3s-.7.723 0 1.4z"/><path d="M7 2v2H2v10h14v-1h2v2c0 .6-.4 1-1 1H1c-.6 0-1-.4-1-1V3c0-.6.4-1 1-1h6z"/></symbol><symbol id="icon-exit-fullscreen" viewBox="0 0 18 18"><path d="M7.7 8.3c-.7-.677-1.4 0-1.4 0L2 12.6V8H0v7c0 .6.4 1 1 1h7v-2H3.4l4.3-4.3s.7-.723 0-1.4z"/><path d="M11 16v-2h5V4H2v1H0V3c0-.6.4-1 1-1h16c.6 0 1 .4 1 1v12c0 .6-.4 1-1 1h-6z"/></symbol><symbol id="icon-fast-forward" viewBox="0 0 16 16"><path d="M7 6.4L0 1v14l7-5.4V15l9-7-9-7z"/></symbol><symbol id="icon-muted" viewBox="0 0 18 18"><path d="M9.214 2a.62.62 0 0 0-.334.101l-4.048 2.81A.494.494 0 0 1 4.549 5H.996A.998.998 0 0 0 0 6v6c0 .552.446 1 .996 1h3.553c.102 0 .2.031.283.089l4.048 2.81a.62.62 0 0 0 .334.101c.392 0 .747-.4.747-.949V2.95c0-.55-.355-.949-.747-.949V2zM7.969 12.834l-2.387-1.657a.996.996 0 0 0-.566-.178H2.491a.5.5 0 0 1-.498-.5v-3a.5.5 0 0 1 .498-.5h2.525c.202 0 .4-.062.566-.178l2.387-1.657v7.67zM14.934 8.799c-.086-1.748-1.514-2.991-2.507-3.649-.47-.312-1.094-.122-1.325.408l-.038.086a.973.973 0 0 0 .336 1.194c.706.473 1.586 1.247 1.624 2.065.032.676-.553 1.468-1.663 2.27a.987.987 0 0 0-.285 1.275l.042.075c.266.475.866.624 1.3.312 1.74-1.251 2.586-2.606 2.516-4.037v.001z"/><path d="M13.957 9.2c.086 1.747 1.514 2.99 2.507 3.648.47.312 1.094.122 1.325-.408l.038-.086a.973.973 0 0 0-.336-1.194c-.706-.473-1.586-1.247-1.624-2.065-.032-.676.553-1.468 1.663-2.27a.987.987 0 0 0 .285-1.275l-.042-.075c-.266-.475-.866-.624-1.3-.312-1.74 1.251-2.586 2.606-2.516 4.037z"/></symbol><symbol id="icon-pause" viewBox="0 0 16 16"><path d="M5 1H2c-.6 0-1 .4-1 1v12c0 .6.4 1 1 1h3c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1zM14 1h-3c-.6 0-1 .4-1 1v12c0 .6.4 1 1 1h3c.6 0 1-.4 1-1V2c0-.6-.4-1-1-1z"/></symbol><symbol id="icon-play" viewBox="0 0 16 16"><path d="M13.6 7.2l-10-7A1 1 0 0 0 2 1v14c0 .8.9 1.3 1.6.8l10-7c.5-.4.5-1.2 0-1.6z"/></symbol><symbol id="icon-restart" viewBox="0 0 16 16"><path d="M7.7 1.2l.7 6.4 2.1-2.1c1.9 1.9 1.9 5.1 0 7-.9 1-2.2 1.5-3.5 1.5-1.3 0-2.6-.5-3.5-1.5-1.9-1.9-1.9-5.1 0-7 .6-.6 1.4-1.1 2.3-1.3l-.6-1.9C4 2.6 2.9 3.2 2 4.1-.7 6.8-.7 11.2 2 14c1.3 1.3 3.1 2 4.9 2 1.9 0 3.6-.7 4.9-2 2.7-2.7 2.7-7.1 0-9.9L14 1.9l-6.3-.7z"/></symbol><symbol id="icon-rewind" viewBox="0 0 16 16"><path d="M9 1L0 8l9 7V9.6l7 5.4V1L9 6.4z"/></symbol><symbol id="icon-volume" viewBox="0 0 18 18"><path d="M10.214 2a.62.62 0 0 0-.334.101l-4.048 2.81A.494.494 0 0 1 5.549 5H1.996A.998.998 0 0 0 1 6v6c0 .552.446 1 .996 1h3.553c.102 0 .2.031.283.089l4.048 2.81a.62.62 0 0 0 .334.101c.392 0 .747-.4.747-.949V2.95c0-.55-.355-.949-.747-.949zM8.969 12.834l-2.387-1.657a.996.996 0 0 0-.566-.178H3.491a.5.5 0 0 1-.498-.5v-3a.5.5 0 0 1 .498-.5h2.525c.202 0 .4-.062.566-.178l2.387-1.657v7.669zM16.934 8.799c-.086-1.748-1.514-2.991-2.507-3.649-.47-.312-1.094-.122-1.325.408l-.038.086a.973.973 0 0 0 .336 1.194c.706.473 1.586 1.247 1.624 2.065.032.676-.553 1.468-1.663 2.27a.987.987 0 0 0-.285 1.275l.042.075c.266.475.866.624 1.3.312 1.74-1.251 2.586-2.606 2.516-4.037z"/></symbol></svg>
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 3.5 KiB |
2
docs/dist/docs.css
vendored
2
docs/dist/docs.js
vendored
@ -1 +1 @@
|
||||
"document"in self&&("classList"in document.createElement("_")?!function(){"use strict";var e=document.createElement("_");if(e.classList.add("c1","c2"),!e.classList.contains("c2")){var t=function(e){var t=DOMTokenList.prototype[e];DOMTokenList.prototype[e]=function(e){var i,n=arguments.length;for(i=0;n>i;i++)e=arguments[i],t.call(this,e)}};t("add"),t("remove")}if(e.classList.toggle("c3",!1),e.classList.contains("c3")){var i=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(e,t){return 1 in arguments&&!this.contains(e)==!t?t:i.call(this,e)}}e=null}():!function(e){"use strict";if("Element"in e){var t="classList",i="prototype",n=e.Element[i],s=Object,o=String[i].trim||function(){return this.replace(/^\s+|\s+$/g,"")},r=Array[i].indexOf||function(e){for(var t=0,i=this.length;i>t;t++)if(t in this&&this[t]===e)return t;return-1},a=function(e,t){this.name=e,this.code=DOMException[e],this.message=t},c=function(e,t){if(""===t)throw new a("SYNTAX_ERR","An invalid or illegal string was specified");if(/\s/.test(t))throw new a("INVALID_CHARACTER_ERR","String contains an invalid character");return r.call(e,t)},l=function(e){for(var t=o.call(e.getAttribute("class")||""),i=t?t.split(/\s+/):[],n=0,s=i.length;s>n;n++)this.push(i[n]);this._updateClassName=function(){e.setAttribute("class",this.toString())}},u=l[i]=[],d=function(){return new l(this)};if(a[i]=Error[i],u.item=function(e){return this[e]||null},u.contains=function(e){return e+="",-1!==c(this,e)},u.add=function(){var e,t=arguments,i=0,n=t.length,s=!1;do e=t[i]+"",-1===c(this,e)&&(this.push(e),s=!0);while(++i<n);s&&this._updateClassName()},u.remove=function(){var e,t,i=arguments,n=0,s=i.length,o=!1;do for(e=i[n]+"",t=c(this,e);-1!==t;)this.splice(t,1),o=!0,t=c(this,e);while(++n<s);o&&this._updateClassName()},u.toggle=function(e,t){e+="";var i=this.contains(e),n=i?t!==!0&&"remove":t!==!1&&"add";return n&&this[n](e),t===!0||t===!1?t:!i},u.toString=function(){return this.join(" ")},s.defineProperty){var p={get:d,enumerable:!0,configurable:!0};try{s.defineProperty(n,t,p)}catch(h){-2146823252===h.number&&(p.enumerable=!1,s.defineProperty(n,t,p))}}else s[i].__defineGetter__&&n.__defineGetter__(t,d)}}(self)),plyr.setup(".js-media-player",{debug:!0,title:"Video demo",tooltips:{controls:!0},captions:{defaultActive:!0}}),shr.setup({count:{classname:"btn__count"}}),function(){function e(e,t,i){if(e)if(e.classList)e.classList[i?"add":"remove"](t);else{var n=(" "+e.className+" ").replace(/\s+/g," ").replace(" "+t+" ","");e.className=n+(i?" "+t:"")}}function t(t,o){if(t in n&&(o||t!=s)&&(s.length||t!=n.video)){var r=document.querySelector(".js-media-player").plyr;switch(t){case n.video:r.source({type:"video",title:"View From A Blue Moon",sources:[{src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.mp4",type:"video/mp4"},{src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.webm",type:"video/webm"}],poster:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.jpg",tracks:[{kind:"captions",label:"English",srclang:"en",src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.en.vtt","default":!0}]});break;case n.audio:r.source({type:"audio",title:"Kishi Bashi – “It All Began With A Burst”",sources:[{src:"https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3",type:"audio/mp3"},{src:"https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg",type:"audio/ogg"}]});break;case n.youtube:r.source({type:"video",title:"View From A Blue Moon",sources:[{src:"bTqVqk7FSmY",type:"youtube"}]});break;case n.vimeo:r.source({type:"video",title:"View From A Blue Moon",sources:[{src:"143418951",type:"vimeo"}]})}s=t;for(var a=i.length-1;a>=0;a--)e(i[a].parentElement,"active",!1);e(document.querySelector('[data-source="'+t+'"]').parentElement,"active",!0)}}for(var i=document.querySelectorAll("[data-source]"),n={video:"video",audio:"audio",youtube:"youtube",vimeo:"vimeo"},s=window.location.hash.replace("#",""),o=window.history&&window.history.pushState,r=i.length-1;r>=0;r--)i[r].addEventListener("click",function(){var e=this.getAttribute("data-source");t(e),o&&history.pushState({type:e},"","#"+e)});if(window.addEventListener("popstate",function(e){e.state&&"type"in e.state&&t(e.state.type)}),o){var a=!s.length;a&&(s=n.video),s in n&&history.replaceState({type:s},"",a?"":"#"+s),s!==n.video&&t(s,!0)}}(),document.domain.indexOf("plyr.io")>-1&&(!function(e,t,i,n,s,o,r){e.GoogleAnalyticsObject=s,e[s]=e[s]||function(){(e[s].q=e[s].q||[]).push(arguments)},e[s].l=1*new Date,o=t.createElement(i),r=t.getElementsByTagName(i)[0],o.async=1,o.src=n,r.parentNode.insertBefore(o,r)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),ga("create","UA-40881672-11","auto"),ga("send","pageview"));
|
||||
"document"in self&&("classList"in document.createElement("_")?!function(){"use strict";var e=document.createElement("_");if(e.classList.add("c1","c2"),!e.classList.contains("c2")){var t=function(e){var t=DOMTokenList.prototype[e];DOMTokenList.prototype[e]=function(e){var i,n=arguments.length;for(i=0;n>i;i++)e=arguments[i],t.call(this,e)}};t("add"),t("remove")}if(e.classList.toggle("c3",!1),e.classList.contains("c3")){var i=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(e,t){return 1 in arguments&&!this.contains(e)==!t?t:i.call(this,e)}}e=null}():!function(e){"use strict";if("Element"in e){var t="classList",i="prototype",n=e.Element[i],o=Object,s=String[i].trim||function(){return this.replace(/^\s+|\s+$/g,"")},r=Array[i].indexOf||function(e){for(var t=0,i=this.length;i>t;t++)if(t in this&&this[t]===e)return t;return-1},a=function(e,t){this.name=e,this.code=DOMException[e],this.message=t},c=function(e,t){if(""===t)throw new a("SYNTAX_ERR","An invalid or illegal string was specified");if(/\s/.test(t))throw new a("INVALID_CHARACTER_ERR","String contains an invalid character");return r.call(e,t)},l=function(e){for(var t=s.call(e.getAttribute("class")||""),i=t?t.split(/\s+/):[],n=0,o=i.length;o>n;n++)this.push(i[n]);this._updateClassName=function(){e.setAttribute("class",this.toString())}},u=l[i]=[],d=function(){return new l(this)};if(a[i]=Error[i],u.item=function(e){return this[e]||null},u.contains=function(e){return e+="",-1!==c(this,e)},u.add=function(){var e,t=arguments,i=0,n=t.length,o=!1;do e=t[i]+"",-1===c(this,e)&&(this.push(e),o=!0);while(++i<n);o&&this._updateClassName()},u.remove=function(){var e,t,i=arguments,n=0,o=i.length,s=!1;do for(e=i[n]+"",t=c(this,e);-1!==t;)this.splice(t,1),s=!0,t=c(this,e);while(++n<o);s&&this._updateClassName()},u.toggle=function(e,t){e+="";var i=this.contains(e),n=i?t!==!0&&"remove":t!==!1&&"add";return n&&this[n](e),t===!0||t===!1?t:!i},u.toString=function(){return this.join(" ")},o.defineProperty){var p={get:d,enumerable:!0,configurable:!0};try{o.defineProperty(n,t,p)}catch(h){-2146823252===h.number&&(p.enumerable=!1,o.defineProperty(n,t,p))}}else o[i].__defineGetter__&&n.__defineGetter__(t,d)}}(self)),plyr.setup(".js-media-player",{debug:!0,title:"Video demo",tooltips:{controls:!0},captions:{defaultActive:!0}}),function(){function e(e,t,i){if(e)if(e.classList)e.classList[i?"add":"remove"](t);else{var n=(" "+e.className+" ").replace(/\s+/g," ").replace(" "+t+" ","");e.className=n+(i?" "+t:"")}}function t(t,s){if(t in n&&(s||t!=o)&&(o.length||t!=n.video)){var r=document.querySelector(".js-media-player").plyr;switch(t){case n.video:r.source({type:"video",title:"View From A Blue Moon",sources:[{src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.mp4",type:"video/mp4"},{src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.webm",type:"video/webm"}],poster:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.jpg",tracks:[{kind:"captions",label:"English",srclang:"en",src:"https://cdn.selz.com/plyr/1.5/View_From_A_Blue_Moon_Trailer-HD.en.vtt","default":!0}]});break;case n.audio:r.source({type:"audio",title:"Kishi Bashi – “It All Began With A Burst”",sources:[{src:"https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.mp3",type:"audio/mp3"},{src:"https://cdn.selz.com/plyr/1.5/Kishi_Bashi_-_It_All_Began_With_a_Burst.ogg",type:"audio/ogg"}]});break;case n.youtube:r.source({type:"video",title:"View From A Blue Moon",sources:[{src:"bTqVqk7FSmY",type:"youtube"}]});break;case n.vimeo:r.source({type:"video",title:"View From A Blue Moon",sources:[{src:"143418951",type:"vimeo"}]})}o=t;for(var a=i.length-1;a>=0;a--)e(i[a].parentElement,"active",!1);e(document.querySelector('[data-source="'+t+'"]').parentElement,"active",!0)}}for(var i=document.querySelectorAll("[data-source]"),n={video:"video",audio:"audio",youtube:"youtube",vimeo:"vimeo"},o=window.location.hash.replace("#",""),s=window.history&&window.history.pushState,r=i.length-1;r>=0;r--)i[r].addEventListener("click",function(){var e=this.getAttribute("data-source");t(e),s&&history.pushState({type:e},"","#"+e)});if(window.addEventListener("popstate",function(e){e.state&&"type"in e.state&&t(e.state.type)}),s){var a=!o.length;a&&(o=n.video),o in n&&history.replaceState({type:o},"",a?"":"#"+o),o!==n.video&&t(o,!0)}}(),document.domain.indexOf("plyr.io")>-1&&(!function(e,t,i,n,o,s,r){e.GoogleAnalyticsObject=o,e[o]=e[o]||function(){(e[o].q=e[o].q||[]).push(arguments)},e[o].l=1*new Date,s=t.createElement(i),r=t.getElementsByTagName(i)[0],s.async=1,s.src=n,r.parentNode.insertBefore(s,r)}(window,document,"script","//www.google-analytics.com/analytics.js","ga"),ga("create","UA-40881672-11","auto"),ga("send","pageview"));
|
@ -118,10 +118,14 @@
|
||||
<!-- Plyr core script -->
|
||||
<script src="../dist/plyr.js"></script>
|
||||
|
||||
<!-- Shr core script -->
|
||||
<script src="https://cdn.shr.one/0.1.9/shr.js"></script>
|
||||
|
||||
<!-- Docs script -->
|
||||
<script src="dist/docs.js"></script>
|
||||
|
||||
<!-- Rangetouch to fix <input type="range"> on touch devices (see https://rangetouch.com) -->
|
||||
<script src="https://cdn.rangetouch.com/0.0.9/rangetouch.js"></script>
|
||||
|
||||
<!-- Sharing libary (https://shr.one) -->
|
||||
<script src="https://cdn.shr.one/0.1.9/shr.js"></script>
|
||||
<script>if(window.shr) { window.shr.setup({ count: { classname: 'btn__count' } }); }</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -2,7 +2,7 @@
|
||||
// Docs example
|
||||
// ==========================================================================
|
||||
|
||||
/*global plyr, shr*/
|
||||
/*global plyr*/
|
||||
|
||||
// Setup the player
|
||||
plyr.setup('.js-media-player', {
|
||||
@ -16,13 +16,6 @@ plyr.setup('.js-media-player', {
|
||||
}
|
||||
});
|
||||
|
||||
// Setup shr
|
||||
shr.setup({
|
||||
count: {
|
||||
classname: 'btn__count'
|
||||
}
|
||||
});
|
||||
|
||||
// General functions
|
||||
(function() {
|
||||
var buttons = document.querySelectorAll('[data-source]'),
|
||||
|
@ -16,16 +16,11 @@
|
||||
// Base
|
||||
html {
|
||||
height: 100%;
|
||||
font-size: 100%;
|
||||
background: linear-gradient(#fff, @body-background) fixed;
|
||||
background: @body-background fixed;
|
||||
}
|
||||
body {
|
||||
font-family: "Avenir", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
text-align: center;
|
||||
color: @gray;
|
||||
.font-smoothing(on);
|
||||
padding: 0 (@padding-base / 2);
|
||||
margin: 0;
|
||||
padding: (@padding-base / 2);
|
||||
}
|
||||
|
||||
// Header
|
||||
|
@ -92,14 +92,14 @@ nav {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
border-radius: @border-radius-base;
|
||||
font-weight: 600;
|
||||
user-select: none;
|
||||
font-weight: @font-weight-bold;
|
||||
}
|
||||
|
||||
// Buttons
|
||||
.btn {
|
||||
padding: (@padding-base / 2) ((@padding-base / 2) + 2);
|
||||
background: linear-gradient(lighten(@body-background, 2%), darken(@body-background, 3%));
|
||||
background: linear-gradient(lighten(@off-white, 2%), darken(@off-white, 3%));
|
||||
border: 1px solid @gray-light;
|
||||
box-shadow: 0 1px 1px rgba(0,0,0, .05);
|
||||
text-shadow: 0 1px 1px #fff;
|
||||
|
@ -7,56 +7,30 @@ section {
|
||||
max-width: @example-width-video;
|
||||
}
|
||||
|
||||
video,
|
||||
.plyr__video-embed {
|
||||
border-radius: @border-radius-base;
|
||||
// For non supported browsers
|
||||
video {
|
||||
max-width: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.plyr__video-embed {
|
||||
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
|
||||
}
|
||||
|
||||
// Example players
|
||||
.plyr {
|
||||
margin: 0 auto;
|
||||
|
||||
&__controls {
|
||||
border-radius: 0 0 @border-radius-base @border-radius-base;
|
||||
}
|
||||
video,
|
||||
.plyr__video-embed {
|
||||
border-radius: @border-radius-base @border-radius-base 0 0;
|
||||
}
|
||||
&--fullscreen,
|
||||
&--fullscreen-active {
|
||||
max-width: none;
|
||||
|
||||
.plyr-controls,
|
||||
video,
|
||||
iframe {
|
||||
border-radius: 0;
|
||||
}
|
||||
iframe {
|
||||
-webkit-mask-image: none;
|
||||
}
|
||||
}
|
||||
border-radius: @border-radius-large;
|
||||
}
|
||||
.plyr--audio {
|
||||
max-width: @example-width-audio;
|
||||
|
||||
.plyr__controls {
|
||||
border-radius: @border-radius-base;
|
||||
}
|
||||
.plyr__progress {
|
||||
border-radius: @border-radius-base @border-radius-base 0 0;
|
||||
|
||||
progress,
|
||||
[type='range'] {
|
||||
border-radius: @border-radius-base @border-radius-base 0 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
.plyr--video::after {
|
||||
content: "";
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
border: 1px solid fade(#000, 15%);
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
// Style full supported player
|
||||
@ -69,7 +43,7 @@ video,
|
||||
}
|
||||
}
|
||||
|
||||
.plyr--video ~ ul .plyr__cite--video,
|
||||
.plyr--video:not(.plyr--youtube):not(.plyr--vimeo) ~ ul .plyr__cite--video,
|
||||
.plyr--audio ~ ul .plyr__cite--audio,
|
||||
.plyr--youtube ~ ul .plyr__cite--youtube,
|
||||
.plyr--vimeo ~ ul .plyr__cite--vimeo {
|
||||
|
@ -2,18 +2,30 @@
|
||||
// Typography
|
||||
// ==========================================================================
|
||||
|
||||
// Base
|
||||
html {
|
||||
font-size: 100%;
|
||||
}
|
||||
body {
|
||||
font-family: "Avenir", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
text-align: center;
|
||||
color: @gray;
|
||||
font-weight: @font-weight-base;
|
||||
.font-smoothing();
|
||||
}
|
||||
|
||||
// Headings
|
||||
h1,
|
||||
h2 {
|
||||
letter-spacing: -.025em;
|
||||
color: #2E3C44;
|
||||
color: @brand-primary;
|
||||
margin: 0 0 (@padding-base / 2);
|
||||
line-height: 1.2;
|
||||
.font-smoothing();
|
||||
font-weight: @font-weight-bold;
|
||||
}
|
||||
h1 {
|
||||
.font-size(@font-size-h1);
|
||||
color: #3498DB;
|
||||
}
|
||||
|
||||
// Paragraph and small
|
||||
|
@ -7,12 +7,12 @@
|
||||
src: url("//cdn.plyr.io/fonts/avenir-medium.woff2") format("woff2"),
|
||||
url("//cdn.plyr.io/fonts/avenir-medium.woff") format("woff");
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-weight: @font-weight-base;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Avenir";
|
||||
src: url("//cdn.plyr.io/fonts/avenir-bold.woff2") format("woff2"),
|
||||
url("//cdn.plyr.io/fonts/avenir-bold.woff") format("woff");
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-weight: @font-weight-bold;
|
||||
}
|
@ -3,41 +3,46 @@
|
||||
// ==========================================================================
|
||||
|
||||
// Colors
|
||||
@blue: #3498db;
|
||||
@gray-dark: #343f4a;
|
||||
@gray: #55646b;
|
||||
@gray-light: #cbd0d3;
|
||||
@gray-lighter: #dbe3e8;
|
||||
@off-white: #f2f5f7;
|
||||
|
||||
@brand-primary: #3498db;
|
||||
@brand-secondary: #02BD9B;
|
||||
|
||||
// Brands
|
||||
@color-twitter: #4BAAF4;
|
||||
@color-youtube: #cc181e;
|
||||
@color-vimeo: #19b7ed;
|
||||
|
||||
// Base
|
||||
@body-background: @off-white;
|
||||
@body-background: @off-white; //linear-gradient(to left top, @brand-secondary, @brand-primary);
|
||||
|
||||
// Type
|
||||
@font-size-base: 16;
|
||||
@font-size-small: 14;
|
||||
@font-size-h1: 64;
|
||||
@font-weight-base: 500;
|
||||
@font-weight-bold: 700;
|
||||
|
||||
// Elements
|
||||
@link-color: @blue;
|
||||
@link-color: @brand-primary;
|
||||
@padding-base: 20px;
|
||||
@arrow-size: 8px;
|
||||
|
||||
// Icons
|
||||
@icon-size: 18px;
|
||||
@icon-size: 18px;
|
||||
|
||||
// Breakpoints
|
||||
@screen-sm: 480px;
|
||||
@screen-md: 768px;
|
||||
|
||||
// Radii
|
||||
@border-radius-base: 4px;
|
||||
@border-radius-base: 4px;
|
||||
@border-radius-large: 6px;
|
||||
|
||||
// Examples
|
||||
@example-width-audio: 520px;
|
||||
@example-width-video: 1200px;
|
||||
@example-width-audio: 520px;
|
||||
@example-width-video: 1200px;
|
||||
|
26
gulpfile.js
@ -12,7 +12,7 @@ var fs = require("fs"),
|
||||
uglify = require("gulp-uglify"),
|
||||
less = require("gulp-less"),
|
||||
sass = require("gulp-sass"),
|
||||
minify = require("gulp-minify-css"),
|
||||
cleanCSS = require("gulp-clean-css"),
|
||||
run = require("run-sequence"),
|
||||
prefix = require("gulp-autoprefixer"),
|
||||
svgstore = require("gulp-svgstore"),
|
||||
@ -30,7 +30,7 @@ paths = {
|
||||
// Source paths
|
||||
src: {
|
||||
less: path.join(root, "src/less/**/*"),
|
||||
sass: path.join(root, "src/sass/**/*"),
|
||||
scss: path.join(root, "src/scss/**/*"),
|
||||
js: path.join(root, "src/js/**/*"),
|
||||
sprite: path.join(root, "src/sprite/*.svg")
|
||||
},
|
||||
@ -55,7 +55,7 @@ paths = {
|
||||
// Task arrays
|
||||
tasks = {
|
||||
less: [],
|
||||
sass: [],
|
||||
scss: [],
|
||||
js: [],
|
||||
sprite: []
|
||||
},
|
||||
@ -104,26 +104,26 @@ var build = {
|
||||
.on("error", gutil.log)
|
||||
.pipe(concat(key))
|
||||
.pipe(prefix(["last 2 versions"], { cascade: true }))
|
||||
.pipe(minify())
|
||||
.pipe(cleanCSS())
|
||||
.pipe(gulp.dest(paths[bundle].output));
|
||||
});
|
||||
})(key);
|
||||
}
|
||||
},
|
||||
sass: function(files, bundle) {
|
||||
scss: function(files, bundle) {
|
||||
for (var key in files) {
|
||||
(function (key) {
|
||||
var name = "sass-" + key;
|
||||
tasks.sass.push(name);
|
||||
var name = "scss-" + key;
|
||||
tasks.scss.push(name);
|
||||
|
||||
gulp.task(name, function () {
|
||||
return gulp
|
||||
.src(bundles[bundle].sass[key])
|
||||
.src(bundles[bundle].scss[key])
|
||||
.pipe(sass())
|
||||
.on("error", gutil.log)
|
||||
.pipe(concat(key))
|
||||
.pipe(prefix(["last 2 versions"], { cascade: true }))
|
||||
.pipe(minify())
|
||||
.pipe(cleanCSS())
|
||||
.pipe(gulp.dest(paths[bundle].output));
|
||||
});
|
||||
})(key);
|
||||
@ -152,7 +152,7 @@ var build = {
|
||||
// Plyr core files
|
||||
build.js(bundles.plyr.js, "plyr");
|
||||
build.less(bundles.plyr.less, "plyr");
|
||||
build.sass(bundles.plyr.sass, "plyr");
|
||||
build.scss(bundles.plyr.scss, "plyr");
|
||||
build.sprite("plyr");
|
||||
|
||||
// Docs files
|
||||
@ -165,9 +165,9 @@ gulp.task("js", function(){
|
||||
run(tasks.js);
|
||||
});
|
||||
|
||||
// Build SASS (for testing, default is LESS)
|
||||
gulp.task("sass", function(){
|
||||
run(tasks.sass);
|
||||
// Build SCSS (for testing, default is LESS)
|
||||
gulp.task("scss", function(){
|
||||
run(tasks.scss);
|
||||
});
|
||||
|
||||
// Watch for file changes
|
||||
|
20
package.json
@ -1,26 +1,26 @@
|
||||
{
|
||||
"name": "plyr",
|
||||
"version": "1.5.19",
|
||||
"version": "1.6.0",
|
||||
"description": "A simple, accessible and customizable HTML5, YouTube and Vimeo media player",
|
||||
"homepage": "http://plyr.io",
|
||||
"main": "src/js/plyr.js",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"gulp": "^3.9.0",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-autoprefixer": "^3.1.0",
|
||||
"gulp-concat": "^2.3.3",
|
||||
"gulp-gzip": "^1.0.0",
|
||||
"gulp-less": "^3.0.5",
|
||||
"gulp-minify-css": "^1.2.1",
|
||||
"gulp-open": "^1.0.0",
|
||||
"gulp-clean-css": "^2.0.6",
|
||||
"gulp-open": "^2.0.0",
|
||||
"gulp-rename": "^1.2.0",
|
||||
"gulp-replace": "^0.5.3",
|
||||
"gulp-s3": "^0.3.0",
|
||||
"gulp-sass": "^2.1.0",
|
||||
"gulp-size": "^2.0.0",
|
||||
"gulp-svgmin": "^1.0.0",
|
||||
"gulp-svgstore": "^5.0.0",
|
||||
"gulp-uglify": "^1.5.1",
|
||||
"gulp-sass": "^2.3.1",
|
||||
"gulp-size": "^2.1.0",
|
||||
"gulp-svgmin": "^1.2.2",
|
||||
"gulp-svgstore": "^5.0.5",
|
||||
"gulp-uglify": "^1.5.3",
|
||||
"gulp-util": "^3.0.7",
|
||||
"run-sequence": "^1.1.5"
|
||||
},
|
||||
@ -43,5 +43,5 @@
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "Sam Potts <sam@selz.com> (selz.com)"
|
||||
"author": "Sam Potts <sam@selz.com>"
|
||||
}
|
||||
|
72
readme.md
@ -3,7 +3,7 @@ A simple, accessible and customizable HTML5, YouTube and Vimeo media player.
|
||||
|
||||
[Checkout the demo](https://plyr.io)
|
||||
|
||||
[](https://plyr.io)
|
||||
[](https://plyr.io)
|
||||
|
||||
## Why?
|
||||
We wanted a lightweight, accessible and customizable media player that supports [*modern*](#browser-support) browsers. Sure, there are many other players out there but we wanted to keep things simple, using the right elements for the job.
|
||||
@ -40,7 +40,7 @@ If you have any cool ideas or features, please let me know by [creating an issue
|
||||
## Implementation
|
||||
Check `docs/index.html` and `docs/dist/docs.js` for an example setup.
|
||||
|
||||
**Heads up:** the example `index.html` file needs to be served from a webserver (such as Apache, Nginx, IIS or similar) unless you change the file sources to include http or https. e.g. change `//cdn.plyr.io/1.5.19/plyr.js` to `https://cdn.plyr.io/1.5.19/plyr.js`
|
||||
**Heads up:** the example `index.html` file needs to be served from a webserver (such as Apache, Nginx, IIS or similar) unless you change the file sources to include http or https. e.g. change `//cdn.plyr.io/1.6.0/plyr.js` to `https://cdn.plyr.io/1.6.0/plyr.js`
|
||||
|
||||
### Node Package Manager (NPM)
|
||||
[](https://badge.fury.io/js/plyr)
|
||||
@ -73,14 +73,14 @@ More info is on [npm](https://www.npmjs.com/package/ember-cli-plyr) and [GitHub]
|
||||
If you want to use our CDN, you can use the following:
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="https://cdn.plyr.io/1.5.19/plyr.css">
|
||||
<script src="https://cdn.plyr.io/1.5.19/plyr.js"></script>
|
||||
<link rel="stylesheet" href="https://cdn.plyr.io/1.6.0/plyr.css">
|
||||
<script src="https://cdn.plyr.io/1.6.0/plyr.js"></script>
|
||||
```
|
||||
|
||||
You can also access the `sprite.svg` file at `https://cdn.plyr.io/1.5.19/sprite.svg`.
|
||||
You can also access the `sprite.svg` file at `https://cdn.plyr.io/1.6.0/sprite.svg`.
|
||||
|
||||
### CSS & Styling
|
||||
If you want to use the default css, add the `plyr.css` file from `/dist` into your head, or even better use `plyr.less` or `plyr.sass` file included in `/src` in your build to save a request.
|
||||
If you want to use the default css, add the `plyr.css` file from `/dist` into your head, or even better use `plyr.less` or `plyr.scss` file included in `/src` in your build to save a request.
|
||||
|
||||
```html
|
||||
<link rel="stylesheet" href="dist/plyr.css">
|
||||
@ -89,7 +89,18 @@ If you want to use the default css, add the `plyr.css` file from `/dist` into yo
|
||||
The default setup uses the BEM methodology with `plyr` as the block, e.g. `.plyr__controls`. You can change the class hooks in the options. Check out the source for more on this.
|
||||
|
||||
### SVG
|
||||
The SVG sprite for the controls icons is loaded in by AJAX to help with performance. This is best added before the closing `</body>`, before any other scripts.
|
||||
The SVG sprite for the controls icons can be loaded two ways:
|
||||
- By passing the *relative* path to the sprite as the `iconUrl` option; or
|
||||
- Using AJAX, injecting the sprite into a hidden div.
|
||||
|
||||
#### Using the `iconUrl` option
|
||||
This method requires the SVG sprite to be hosted on the *same domain* as your page hosting the player. Currently no browser supports cross origin SVG sprites due to XSS issues. Fingers crossed this will come soon though. An example value for this option would be:
|
||||
```
|
||||
/path/to/sprite.svg
|
||||
```
|
||||
|
||||
#### Using AJAX
|
||||
Using AJAX means you can load the sprite from a different origin. Avoiding the issues above. This is an example script to load an SVG sprite best added before the closing `</body>`, before any other scripts.
|
||||
|
||||
```html
|
||||
<script>
|
||||
@ -104,7 +115,7 @@ The SVG sprite for the controls icons is loaded in by AJAX to help with performa
|
||||
c.innerHTML = a.responseText;
|
||||
b.insertBefore(c, b.childNodes[0]);
|
||||
};
|
||||
})(document, 'path/to/sprite.svg');
|
||||
})(document, 'https://cdn.plyr.io/1.6.0/sprite.svg');
|
||||
</script>
|
||||
```
|
||||
|
||||
@ -179,7 +190,7 @@ Be sure to [validate your caption files](https://quuz.org/webvtt/)
|
||||
Here's an example of a default setup:
|
||||
|
||||
```html
|
||||
<script src="https://cdn.plyr.io/1.5.19/plyr.js"></script>
|
||||
<script src="https://cdn.plyr.io/1.6.0/plyr.js"></script>
|
||||
<script>plyr.setup();</script>
|
||||
```
|
||||
|
||||
@ -207,6 +218,9 @@ Passing just the options object:
|
||||
plyr.setup(options);
|
||||
```
|
||||
|
||||
#### RangeTouch
|
||||
Some touch browsers (particularly Mobile Safari on iOS) seem to have issues with `<input type="range">` elements whereby touching the track to set the value doesn't work and sliding the thumb can be tricky. To combat this, I've created [RangeTouch](https://rangetouch.com) which I'd recommend including in your solution. It's a tiny script with a nice benefit for users on touch devices.
|
||||
|
||||
#### Options
|
||||
|
||||
Options must be passed as an object to the `setup()` method as above or as JSON in `data-plyr` attribute on each of your target elements (e.g. data-plyr='{ title: "testing" }') - note the single quotes encapsulating the JSON.
|
||||
@ -251,6 +265,12 @@ Options must be passed as an object to the `setup()` method as above or as JSON
|
||||
<td><code>icon</code></td>
|
||||
<td>Specify the id prefix for the icons used in the default controls (e.g. "icon-play" would be "icon"). This is to prevent clashes if you're using your own SVG defs file but with the default controls. Most people can ignore this option.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>iconUrl</code></td>
|
||||
<td>String</td>
|
||||
<td><code>null</code></td>
|
||||
<td>Specify a relative path to the SVG sprite, hosted on the *same domain* as the page the player is hosted on. Using this menthod means no requirement for the AJAX sprite loading script. See the <a href="#svg">SVG section</a> for more info.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>debug</code></td>
|
||||
<td>Boolean</td>
|
||||
@ -276,10 +296,16 @@ Options must be passed as an object to the `setup()` method as above or as JSON
|
||||
<td>A number, between 1 and 10, representing the initial volume of the player.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>click</code></td>
|
||||
<td><code>clickToPlay</code></td>
|
||||
<td>Boolean</td>
|
||||
<td><code>true</code></td>
|
||||
<td>Click (or tap) will toggle pause/play of a <code><video></code>.</td>
|
||||
<td>Click (or tap) of the video container will toggle pause/play.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>hideControls</code></td>
|
||||
<td>Boolean</td>
|
||||
<td><code>true</code></td>
|
||||
<td>Hide video controls automatically after 2s of no mouse or focus movement, on control element blur (tab out), on playback start or entering fullscreen. As soon as the mouse is moved, a control element is focused or playback is paused, the controls reappear instantly.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>tooltips</code></td>
|
||||
@ -366,12 +392,6 @@ Options must be passed as an object to the `setup()` method as above or as JSON
|
||||
<td><code>true</code></td>
|
||||
<td>Enable a full viewport view for older browsers.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>hideControls</code></td>
|
||||
<td>Boolean</td>
|
||||
<td><code>true</code></td>
|
||||
<td>Hide the controls when fullscreen is active and the video is playing, after 1s. The controls reappear on hover of the progress bar (mouse), focusing a child control or pausing the video (by tap/click of video if `click` is `true`).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>allowAudio</code></td>
|
||||
<td>Boolean</td>
|
||||
@ -389,7 +409,7 @@ A `plyr` object is added to any element that Plyr is initialized on. You can the
|
||||
There are two ways to access the instance, firstly you re-query the element container you used for setup (e.g. `.js-plyr`) like so:
|
||||
|
||||
```javascript
|
||||
var player = document.querySelector('.js-plyr');
|
||||
var player = document.querySelector('.js-plyr').plyr;
|
||||
```
|
||||
|
||||
Or you can use the returned object from your call to the setup method:
|
||||
@ -488,20 +508,8 @@ Here's a list of the methods supported:
|
||||
<td>
|
||||
Get/Set the media source.
|
||||
<br><br>
|
||||
<strong>array</strong><br>
|
||||
<pre><code>.source([
|
||||
{
|
||||
src: "/path/to/video.webm",
|
||||
type: "video/webm",
|
||||
...more attributes...
|
||||
},
|
||||
{
|
||||
src: "/path/to/video.mp4",
|
||||
type: "video/mp4",
|
||||
...more attributes...
|
||||
}
|
||||
])`</code></pre><br>
|
||||
This will inject a child `source` element for every element in the array with the specified attributes. `src` is the only required attribute although adding `type` is recommended as it helps the browser decide which file to download and play.
|
||||
<strong>Object</strong><br>
|
||||
See <a href="#source-method">below</a>
|
||||
<br><br>
|
||||
<strong>YouTube</strong><br>
|
||||
Currently this API method only accepts a YouTube ID when used with a YouTube player. I will add URL support soon, along with being able to swap between types (e.g. YouTube to Audio or Video and vice versa.)
|
||||
|
454
src/js/plyr.js
@ -1,13 +1,13 @@
|
||||
// ==========================================================================
|
||||
// Plyr
|
||||
// plyr.js v1.5.19
|
||||
// plyr.js v1.6.0
|
||||
// https://github.com/selz/plyr
|
||||
// License: The MIT License (MIT)
|
||||
// ==========================================================================
|
||||
// Credits: http://paypal.github.io/accessible-html5-video-player/
|
||||
// ==========================================================================
|
||||
|
||||
(function(root, factory) {
|
||||
;(function(root, factory) {
|
||||
'use strict';
|
||||
/*global define,module*/
|
||||
|
||||
@ -39,8 +39,10 @@
|
||||
duration: null,
|
||||
displayDuration: true,
|
||||
iconPrefix: 'icon',
|
||||
click: true,
|
||||
tooltips: {
|
||||
iconUrl: '',
|
||||
clickToPlay: true,
|
||||
hideControls: true,
|
||||
tooltips: {
|
||||
controls: false,
|
||||
seek: true
|
||||
},
|
||||
@ -59,10 +61,13 @@
|
||||
rewind: '[data-plyr="rewind"]',
|
||||
forward: '[data-plyr="fast-forward"]',
|
||||
mute: '[data-plyr="mute"]',
|
||||
volume: '[data-plyr="volume"]',
|
||||
captions: '[data-plyr="captions"]',
|
||||
fullscreen: '[data-plyr="fullscreen"]'
|
||||
},
|
||||
volume: {
|
||||
input: '[data-plyr="volume"]',
|
||||
display: '.plyr__volume--display'
|
||||
},
|
||||
progress: {
|
||||
container: '.plyr__progress',
|
||||
buffer: '.plyr__progress--buffer',
|
||||
@ -83,6 +88,7 @@
|
||||
hover: 'plyr--hover',
|
||||
tooltip: 'plyr__tooltip',
|
||||
hidden: 'plyr__sr-only',
|
||||
hideControls: 'plyr--hide-controls',
|
||||
isIos: 'plyr--is-ios',
|
||||
isTouch: 'plyr--is-touch',
|
||||
captions: {
|
||||
@ -91,8 +97,7 @@
|
||||
},
|
||||
fullscreen: {
|
||||
enabled: 'plyr--fullscreen-enabled',
|
||||
active: 'plyr--fullscreen-active',
|
||||
hideControls: 'plyr--fullscreen--hide-controls'
|
||||
active: 'plyr--fullscreen-active'
|
||||
},
|
||||
tabFocus: 'tab-focus'
|
||||
},
|
||||
@ -102,14 +107,13 @@
|
||||
fullscreen: {
|
||||
enabled: true,
|
||||
fallback: true,
|
||||
hideControls: true,
|
||||
allowAudio: false
|
||||
},
|
||||
storage: {
|
||||
enabled: true,
|
||||
key: 'plyr'
|
||||
},
|
||||
controls: ['restart', 'rewind', 'play', 'fast-forward', 'current-time', 'duration', 'mute', 'volume', 'captions', 'fullscreen'],
|
||||
controls: ['play-large', 'play', 'progress', 'current-time', 'mute', 'volume', 'captions', 'fullscreen'],
|
||||
i18n: {
|
||||
restart: 'Restart',
|
||||
rewind: 'Rewind {seektime} secs',
|
||||
@ -391,33 +395,39 @@
|
||||
}
|
||||
|
||||
// Bind event
|
||||
function _on(element, events, callback) {
|
||||
function _on(element, events, callback, useCapture) {
|
||||
if (element) {
|
||||
_toggleListener(element, events, callback, true);
|
||||
_toggleListener(element, events, callback, true, useCapture);
|
||||
}
|
||||
}
|
||||
|
||||
// Unbind event
|
||||
function _off(element, events, callback) {
|
||||
function _off(element, events, callback, useCapture) {
|
||||
if (element) {
|
||||
_toggleListener(element, events, callback, false);
|
||||
_toggleListener(element, events, callback, false, useCapture);
|
||||
}
|
||||
}
|
||||
|
||||
// Bind along with custom handler
|
||||
function _proxyListener(element, eventName, userListener, defaultListener) {
|
||||
function _proxyListener(element, eventName, userListener, defaultListener, useCapture) {
|
||||
_on(element, eventName, function(event) {
|
||||
if(userListener) {
|
||||
userListener.apply(element, [event]);
|
||||
}
|
||||
defaultListener.apply(element, [event]);
|
||||
});
|
||||
}, useCapture);
|
||||
}
|
||||
|
||||
// Toggle event listener
|
||||
function _toggleListener(element, events, callback, toggle) {
|
||||
function _toggleListener(element, events, callback, toggle, useCapture) {
|
||||
var eventList = events.split(' ');
|
||||
|
||||
// Whether the listener is a capturing listener or not
|
||||
// Default to false
|
||||
if(typeof useCapture !== 'boolean') {
|
||||
useCapture = false;
|
||||
}
|
||||
|
||||
// If a nodelist is passed, call itself on each node
|
||||
if (element instanceof NodeList) {
|
||||
for (var x = 0; x < element.length; x++) {
|
||||
@ -430,7 +440,7 @@
|
||||
|
||||
// If a single node is passed, bind the event listener
|
||||
for (var i = 0; i < eventList.length; i++) {
|
||||
element[toggle ? 'addEventListener' : 'removeEventListener'](eventList[i], callback, false);
|
||||
element[toggle ? 'addEventListener' : 'removeEventListener'](eventList[i], callback, useCapture);
|
||||
}
|
||||
}
|
||||
|
||||
@ -478,7 +488,7 @@
|
||||
// Removed call to arguments.callee (used explicit function name instead)
|
||||
function _extend() {
|
||||
// Get arguments
|
||||
var objects = arguments;
|
||||
var objects = arguments;
|
||||
|
||||
// Bail if nothing to merge
|
||||
if(!objects.length) {
|
||||
@ -588,14 +598,14 @@
|
||||
var storage = {
|
||||
supported: (function() {
|
||||
if(!('localStorage' in window)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to use it (it might be disabled, e.g. user is in private/porn mode)
|
||||
// Try to use it (it might be disabled, e.g. user is in private/porn mode)
|
||||
// see: https://github.com/Selz/plyr/issues/131
|
||||
try {
|
||||
try {
|
||||
// Add test item
|
||||
window.localStorage.setItem('___test', 'OK');
|
||||
window.localStorage.setItem('___test', 'OK');
|
||||
|
||||
// Get the test item
|
||||
var result = window.localStorage.getItem('___test');
|
||||
@ -605,12 +615,12 @@
|
||||
|
||||
// Check if value matches
|
||||
return (result === 'OK');
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
})()
|
||||
};
|
||||
return storage;
|
||||
@ -634,33 +644,27 @@
|
||||
|
||||
// Build the default HTML
|
||||
function _buildControls() {
|
||||
// Open and add the progress and seek elements
|
||||
var html = [
|
||||
'<div class="plyr__controls">',
|
||||
'<div class="plyr__progress">',
|
||||
'<label for="seek{id}" class="plyr__sr-only">Seek</label>',
|
||||
'<input id="seek{id}" class="plyr__progress--seek" type="range" min="0" max="100" step="0.1" value="0" data-plyr="seek">',
|
||||
'<progress class="plyr__progress--played" max="100" value="0">',
|
||||
'<span>0</span>% ' + config.i18n.played,
|
||||
'</progress>',
|
||||
'<progress class="plyr__progress--buffer" max="100" value="0">',
|
||||
'<span>0</span>% ' + config.i18n.buffered,
|
||||
'</progress>'];
|
||||
// Create html array
|
||||
var html = [],
|
||||
iconPath = config.iconUrl + '#' + config.iconPrefix;
|
||||
|
||||
// Seek tooltip
|
||||
if (config.tooltips.seek) {
|
||||
html.push('<span class="plyr__tooltip">00:00</span>');
|
||||
// Larger overlaid play button
|
||||
if (_inArray(config.controls, 'play-large')) {
|
||||
html.push(
|
||||
'<button type="button" data-plyr="play" class="plyr__play-large">',
|
||||
'<svg><use xlink:href="' + iconPath + '-play" /></svg>',
|
||||
'<span class="plyr__sr-only">' + config.i18n.play + '</span>',
|
||||
'</button>'
|
||||
);
|
||||
}
|
||||
|
||||
// Close progress
|
||||
html.push('</div>',
|
||||
'<span class="plyr__controls--left">');
|
||||
html.push('<div class="plyr__controls">');
|
||||
|
||||
// Restart button
|
||||
if (_inArray(config.controls, 'restart')) {
|
||||
html.push(
|
||||
'<button type="button" data-plyr="restart">',
|
||||
'<svg><use xlink:href="#' + config.iconPrefix + '-restart" /></svg>',
|
||||
'<svg><use xlink:href="' + iconPath + '-restart" /></svg>',
|
||||
'<span class="plyr__sr-only">' + config.i18n.restart + '</span>',
|
||||
'</button>'
|
||||
);
|
||||
@ -670,21 +674,22 @@
|
||||
if (_inArray(config.controls, 'rewind')) {
|
||||
html.push(
|
||||
'<button type="button" data-plyr="rewind">',
|
||||
'<svg><use xlink:href="#' + config.iconPrefix + '-rewind" /></svg>',
|
||||
'<svg><use xlink:href="' + iconPath + '-rewind" /></svg>',
|
||||
'<span class="plyr__sr-only">' + config.i18n.rewind + '</span>',
|
||||
'</button>'
|
||||
);
|
||||
}
|
||||
|
||||
// Play/pause button
|
||||
// Play Pause button
|
||||
// TODO: This should be a toggle button really?
|
||||
if (_inArray(config.controls, 'play')) {
|
||||
html.push(
|
||||
'<button type="button" data-plyr="play">',
|
||||
'<svg><use xlink:href="#' + config.iconPrefix + '-play" /></svg>',
|
||||
'<svg><use xlink:href="' + iconPath + '-play" /></svg>',
|
||||
'<span class="plyr__sr-only">' + config.i18n.play + '</span>',
|
||||
'</button>',
|
||||
'<button type="button" data-plyr="pause">',
|
||||
'<svg><use xlink:href="#' + config.iconPrefix + '-pause" /></svg>',
|
||||
'<svg><use xlink:href="' + iconPath + '-pause" /></svg>',
|
||||
'<span class="plyr__sr-only">' + config.i18n.pause + '</span>',
|
||||
'</button>'
|
||||
);
|
||||
@ -694,12 +699,32 @@
|
||||
if (_inArray(config.controls, 'fast-forward')) {
|
||||
html.push(
|
||||
'<button type="button" data-plyr="fast-forward">',
|
||||
'<svg><use xlink:href="#' + config.iconPrefix + '-fast-forward" /></svg>',
|
||||
'<svg><use xlink:href="' + iconPath + '-fast-forward" /></svg>',
|
||||
'<span class="plyr__sr-only">' + config.i18n.forward + '</span>',
|
||||
'</button>'
|
||||
);
|
||||
}
|
||||
|
||||
// Progress
|
||||
if (_inArray(config.controls, 'progress')) {
|
||||
// Create progress
|
||||
html.push('<span class="plyr__progress">',
|
||||
'<label for="seek{id}" class="plyr__sr-only">Seek</label>',
|
||||
'<input id="seek{id}" class="plyr__progress--seek" type="range" min="0" max="100" step="0.1" value="0" data-plyr="seek">',
|
||||
'<progress class="plyr__progress--played" max="100" value="0" role="presentation"></progress>',
|
||||
'<progress class="plyr__progress--buffer" max="100" value="0">',
|
||||
'<span>0</span>% ' + config.i18n.buffered,
|
||||
'</progress>');
|
||||
|
||||
// Seek tooltip
|
||||
if (config.tooltips.seek) {
|
||||
html.push('<span class="plyr__tooltip">00:00</span>');
|
||||
}
|
||||
|
||||
// Close
|
||||
html.push('</span>');
|
||||
}
|
||||
|
||||
// Media current time display
|
||||
if (_inArray(config.controls, 'current-time')) {
|
||||
html.push(
|
||||
@ -720,18 +745,12 @@
|
||||
);
|
||||
}
|
||||
|
||||
// Close left controls
|
||||
html.push(
|
||||
'</span>',
|
||||
'<span class="plyr__controls--right">'
|
||||
);
|
||||
|
||||
// Toggle mute button
|
||||
if (_inArray(config.controls, 'mute')) {
|
||||
html.push(
|
||||
'<button type="button" data-plyr="mute">',
|
||||
'<svg class="icon--muted"><use xlink:href="#' + config.iconPrefix + '-muted" /></svg>',
|
||||
'<svg><use xlink:href="#' + config.iconPrefix + '-volume" /></svg>',
|
||||
'<svg class="icon--muted"><use xlink:href="' + iconPath + '-muted" /></svg>',
|
||||
'<svg><use xlink:href="' + iconPath + '-volume" /></svg>',
|
||||
'<span class="plyr__sr-only">' + config.i18n.toggleMute + '</span>',
|
||||
'</button>'
|
||||
);
|
||||
@ -740,8 +759,11 @@
|
||||
// Volume range control
|
||||
if (_inArray(config.controls, 'volume')) {
|
||||
html.push(
|
||||
'<label for="volume{id}" class="plyr__sr-only">' + config.i18n.volume + '</label>',
|
||||
'<input id="volume{id}" class="plyr__volume" type="range" min="0" max="10" value="5" data-plyr="volume">'
|
||||
'<span class="plyr__volume">',
|
||||
'<label for="volume{id}" class="plyr__sr-only">' + config.i18n.volume + '</label>',
|
||||
'<input id="volume{id}" class="plyr__volume--input" type="range" min="0" max="10" value="5" data-plyr="volume">',
|
||||
'<progress class="plyr__volume--display" max="10" value="0" role="presentation"></progress>',
|
||||
'</span>'
|
||||
);
|
||||
}
|
||||
|
||||
@ -749,8 +771,8 @@
|
||||
if (_inArray(config.controls, 'captions')) {
|
||||
html.push(
|
||||
'<button type="button" data-plyr="captions">',
|
||||
'<svg class="icon--captions-on"><use xlink:href="#' + config.iconPrefix + '-captions-on" /></svg>',
|
||||
'<svg><use xlink:href="#' + config.iconPrefix + '-captions-off" /></svg>',
|
||||
'<svg class="icon--captions-on"><use xlink:href="' + iconPath + '-captions-on" /></svg>',
|
||||
'<svg><use xlink:href="' + iconPath+ '-captions-off" /></svg>',
|
||||
'<span class="plyr__sr-only">' + config.i18n.toggleCaptions + '</span>',
|
||||
'</button>'
|
||||
);
|
||||
@ -760,18 +782,15 @@
|
||||
if (_inArray(config.controls, 'fullscreen')) {
|
||||
html.push(
|
||||
'<button type="button" data-plyr="fullscreen">',
|
||||
'<svg class="icon--exit-fullscreen"><use xlink:href="#' + config.iconPrefix + '-exit-fullscreen" /></svg>',
|
||||
'<svg><use xlink:href="#' + config.iconPrefix + '-enter-fullscreen" /></svg>',
|
||||
'<svg class="icon--exit-fullscreen"><use xlink:href="' + iconPath + '-exit-fullscreen" /></svg>',
|
||||
'<svg><use xlink:href="' + iconPath + '-enter-fullscreen" /></svg>',
|
||||
'<span class="plyr__sr-only">' + config.i18n.toggleFullscreen + '</span>',
|
||||
'</button>'
|
||||
);
|
||||
}
|
||||
|
||||
// Close everything
|
||||
html.push(
|
||||
'</span>',
|
||||
'</div>'
|
||||
);
|
||||
html.push('</div>');
|
||||
|
||||
return html.join('');
|
||||
}
|
||||
@ -801,11 +820,6 @@
|
||||
|
||||
// Setup focus trap
|
||||
_focusTrap();
|
||||
|
||||
// Set control hide class hook
|
||||
if (config.fullscreen.hideControls) {
|
||||
_toggleClass(plyr.container, config.classes.fullscreen.hideControls, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1171,7 +1185,7 @@
|
||||
|
||||
// Setup tooltips
|
||||
if (config.tooltips.controls) {
|
||||
var labels = _getElements(config.selectors.labels + ' .' + config.classes.hidden);
|
||||
var labels = _getElements([config.selectors.controls.wrapper, ' ', config.selectors.labels, ' .', config.classes.hidden].join(''));
|
||||
|
||||
for (var i = labels.length - 1; i >= 0; i--) {
|
||||
var label = labels[i];
|
||||
@ -1190,7 +1204,7 @@
|
||||
// Buttons
|
||||
plyr.buttons = {};
|
||||
plyr.buttons.seek = _getElement(config.selectors.buttons.seek);
|
||||
plyr.buttons.play = _getElement(config.selectors.buttons.play);
|
||||
plyr.buttons.play = _getElements(config.selectors.buttons.play);
|
||||
plyr.buttons.pause = _getElement(config.selectors.buttons.pause);
|
||||
plyr.buttons.restart = _getElement(config.selectors.buttons.restart);
|
||||
plyr.buttons.rewind = _getElement(config.selectors.buttons.rewind);
|
||||
@ -1198,10 +1212,8 @@
|
||||
plyr.buttons.fullscreen = _getElement(config.selectors.buttons.fullscreen);
|
||||
|
||||
// Inputs
|
||||
plyr.buttons.volume = _getElement(config.selectors.buttons.volume);
|
||||
plyr.buttons.mute = _getElement(config.selectors.buttons.mute);
|
||||
plyr.buttons.captions = _getElement(config.selectors.buttons.captions);
|
||||
plyr.checkboxes = _getElements('[type="checkbox"]');
|
||||
|
||||
// Progress
|
||||
plyr.progress = {};
|
||||
@ -1213,15 +1225,15 @@
|
||||
plyr.progress.buffer.text = plyr.progress.buffer.bar && plyr.progress.buffer.bar.getElementsByTagName('span')[0];
|
||||
|
||||
// Progress - Played
|
||||
plyr.progress.played = {};
|
||||
plyr.progress.played.bar = _getElement(config.selectors.progress.played);
|
||||
plyr.progress.played.text = plyr.progress.played.bar && plyr.progress.played.bar.getElementsByTagName('span')[0];
|
||||
plyr.progress.played = _getElement(config.selectors.progress.played);
|
||||
|
||||
// Seek tooltip
|
||||
plyr.progress.tooltip = plyr.progress.container && plyr.progress.container.querySelector('.' + config.classes.tooltip);
|
||||
plyr.progress.tooltip = plyr.progress.container && plyr.progress.container.querySelector('.' + config.classes.tooltip);
|
||||
|
||||
// Volume
|
||||
plyr.volume = _getElement(config.selectors.buttons.volume);
|
||||
plyr.volume = {};
|
||||
plyr.volume.input = _getElement(config.selectors.volume.input);
|
||||
plyr.volume.display = _getElement(config.selectors.volume.display);
|
||||
|
||||
// Timing
|
||||
plyr.duration = _getElement(config.selectors.duration);
|
||||
@ -1234,7 +1246,7 @@
|
||||
_log('It looks like there is a problem with your controls html', true);
|
||||
|
||||
// Restore native video controls
|
||||
_toggleControls(true);
|
||||
_toggleNativeControls(true);
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -1246,7 +1258,7 @@
|
||||
}
|
||||
|
||||
// Toggle native controls
|
||||
function _toggleControls(toggle) {
|
||||
function _toggleNativeControls(toggle) {
|
||||
if(toggle) {
|
||||
plyr.media.setAttribute('controls', '');
|
||||
}
|
||||
@ -1267,7 +1279,9 @@
|
||||
|
||||
// If there's a play button, set label
|
||||
if (plyr.supported.full && plyr.buttons.play) {
|
||||
plyr.buttons.play.setAttribute('aria-label', label);
|
||||
for (var i = plyr.buttons.play.length - 1; i >= 0; i--) {
|
||||
plyr.buttons.play[i].setAttribute('aria-label', label);
|
||||
}
|
||||
}
|
||||
|
||||
// Set iframe title
|
||||
@ -1289,6 +1303,12 @@
|
||||
// Add type class
|
||||
_toggleClass(plyr.container, config.classes.type.replace('{0}', plyr.type), true);
|
||||
|
||||
// Add video class for embeds
|
||||
// This will require changes if audio embeds are added
|
||||
if (_inArray(config.types.embed, plyr.type)) {
|
||||
_toggleClass(plyr.container, config.classes.type.replace('{0}', 'video'), true);
|
||||
}
|
||||
|
||||
// If there's no autoplay attribute, assume the video is stopped and add state class
|
||||
_toggleClass(plyr.container, config.classes.stopped, config.autoplay);
|
||||
|
||||
@ -1319,12 +1339,6 @@
|
||||
// Clean up
|
||||
plyr.embedId = null;
|
||||
}
|
||||
else {
|
||||
// Autoplay
|
||||
if (config.autoplay) {
|
||||
_play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Setup YouTube/Vimeo
|
||||
@ -1415,14 +1429,14 @@
|
||||
|
||||
// When embeds are ready
|
||||
function _embedReady() {
|
||||
// Set title
|
||||
_setTitle(_getElement('iframe'));
|
||||
|
||||
// Store reference to API
|
||||
plyr.container.plyr.embed = plyr.embed;
|
||||
|
||||
// Setup the UI
|
||||
_setupInterface();
|
||||
|
||||
// Set title
|
||||
_setTitle(_getElement('iframe'));
|
||||
}
|
||||
|
||||
// Handle YouTube API ready
|
||||
@ -1438,7 +1452,7 @@
|
||||
plyr.embed = new YT.Player(container.id, {
|
||||
videoId: videoId,
|
||||
playerVars: {
|
||||
autoplay: plyr.autoplay ? 1 : 0,
|
||||
autoplay: (config.autoplay ? 1 : 0),
|
||||
controls: (plyr.supported.full ? 0 : 1),
|
||||
rel: 0,
|
||||
showinfo: 0,
|
||||
@ -1626,12 +1640,12 @@
|
||||
});
|
||||
|
||||
// Always seek to 0
|
||||
//plyr.embed.api('seekTo', 0);
|
||||
// plyr.embed.api('seekTo', 0);
|
||||
|
||||
// Prevent autoplay if needed (seek will play)
|
||||
//if (!config.autoplay) {
|
||||
// plyr.embed.api('pause');
|
||||
//}
|
||||
// Autoplay
|
||||
if (config.autoplay) {
|
||||
plyr.embed.api('play');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -1709,6 +1723,11 @@
|
||||
targetTime = duration;
|
||||
}
|
||||
|
||||
// Update progress
|
||||
if(plyr.progress && plyr.progress.played) {
|
||||
plyr.progress.played.value = ((100 / duration) * targetTime);
|
||||
}
|
||||
|
||||
// Set the current time
|
||||
// Try/catch incase the media isn't set and we're calling seek() from source() and IE moans
|
||||
try {
|
||||
@ -1761,6 +1780,8 @@
|
||||
function _checkPlaying() {
|
||||
_toggleClass(plyr.container, config.classes.playing, !plyr.media.paused);
|
||||
_toggleClass(plyr.container, config.classes.stopped, plyr.media.paused);
|
||||
|
||||
_toggleControls(plyr.media.paused);
|
||||
}
|
||||
|
||||
// Toggle fullscreen
|
||||
@ -1818,12 +1839,6 @@
|
||||
// Set button state
|
||||
_toggleState(plyr.buttons.fullscreen, plyr.isFullscreen);
|
||||
|
||||
// Hide on entering full screen
|
||||
if (config.fullscreen.hideControls) {
|
||||
//_toggleClass(plyr.controls, config.classes.hover, false);
|
||||
_showControls(true);
|
||||
}
|
||||
|
||||
// Trigger an event
|
||||
_triggerEvent(plyr.container, plyr.isFullscreen ? 'enterfullscreen' : 'exitfullscreen');
|
||||
}
|
||||
@ -1849,6 +1864,11 @@
|
||||
// Set mute on the player
|
||||
plyr.media.muted = muted;
|
||||
|
||||
// If volume is 0 after unmuting, set to default
|
||||
if(plyr.media.volume === 0) {
|
||||
_setVolume(config.volume);
|
||||
}
|
||||
|
||||
// Embeds
|
||||
if(_inArray(config.types.embed, plyr.type)) {
|
||||
// YouTube
|
||||
@ -1899,8 +1919,10 @@
|
||||
// Set the player volume
|
||||
plyr.media.volume = parseFloat(volume / 10);
|
||||
|
||||
// Store in config
|
||||
config.volume = volume;
|
||||
// Set the display
|
||||
if (plyr.volume.display) {
|
||||
plyr.volume.display.value = volume;
|
||||
}
|
||||
|
||||
// Embeds
|
||||
if(_inArray(config.types.embed, plyr.type)) {
|
||||
@ -1931,8 +1953,13 @@
|
||||
var volume = plyr.media.muted ? 0 : (plyr.media.volume * 10);
|
||||
|
||||
// Update the <input type="range"> if present
|
||||
if (plyr.supported.full && plyr.volume) {
|
||||
plyr.volume.value = volume;
|
||||
if (plyr.supported.full) {
|
||||
if (plyr.volume.input) {
|
||||
plyr.volume.input.value = volume;
|
||||
}
|
||||
if (plyr.volume.display) {
|
||||
plyr.volume.display.value = volume;
|
||||
}
|
||||
}
|
||||
|
||||
// Store the volume in storage
|
||||
@ -1989,8 +2016,8 @@
|
||||
|
||||
// Update <progress> elements
|
||||
function _updateProgress(event) {
|
||||
var progress = plyr.progress.played.bar,
|
||||
text = plyr.progress.played.text,
|
||||
var progress = plyr.progress.played,
|
||||
text = false,
|
||||
value = 0,
|
||||
duration = _getDuration();
|
||||
|
||||
@ -2008,32 +2035,27 @@
|
||||
|
||||
break;
|
||||
|
||||
// Events from seek range
|
||||
case 'change':
|
||||
case 'input':
|
||||
value = event.target.value;
|
||||
break;
|
||||
|
||||
|
||||
// Check buffer status
|
||||
case 'playing':
|
||||
case 'progress':
|
||||
progress = plyr.progress.buffer.bar;
|
||||
text = plyr.progress.buffer.text;
|
||||
value = (function() {
|
||||
var buffered = plyr.media.buffered;
|
||||
var buffered = plyr.media.buffered;
|
||||
|
||||
// HTML5
|
||||
if (buffered && buffered.length) {
|
||||
return _getPercentage(buffered.end(0), duration);
|
||||
}
|
||||
// YouTube returns between 0 and 1
|
||||
else if (typeof buffered === 'number') {
|
||||
return (buffered * 100);
|
||||
}
|
||||
// HTML5
|
||||
if (buffered && buffered.length) {
|
||||
return _getPercentage(buffered.end(0), duration);
|
||||
}
|
||||
// YouTube returns between 0 and 1
|
||||
else if (typeof buffered === 'number') {
|
||||
return (buffered * 100);
|
||||
}
|
||||
|
||||
return 0;
|
||||
})();
|
||||
return 0;
|
||||
})();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2113,7 +2135,7 @@
|
||||
// Update hover tooltip for seeking
|
||||
function _updateSeekTooltip(event) {
|
||||
// Bail if setting not true
|
||||
if (!config.tooltips.seek || plyr.browser.touch) {
|
||||
if (!config.tooltips.seek || plyr.browser.touch || !plyr.progress.container) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2157,24 +2179,63 @@
|
||||
}
|
||||
|
||||
// Show the player controls in fullscreen mode
|
||||
function _showControls(force) {
|
||||
// We're only worried about fullscreen
|
||||
if (!plyr.isFullscreen) {
|
||||
function _toggleControls(toggle) {
|
||||
if (!config.hideControls || plyr.type === 'audio') {
|
||||
return;
|
||||
}
|
||||
var delay = 0,
|
||||
isEnterFullscreen = false,
|
||||
show = toggle;
|
||||
|
||||
// Set shown class
|
||||
_toggleClass(plyr.container, config.classes.hover, true);
|
||||
// Default to false if no boolean
|
||||
if(typeof toggle !== "boolean") {
|
||||
if(toggle && toggle.type) {
|
||||
// Is the enter fullscreen event
|
||||
isEnterFullscreen = (toggle.type === 'enterfullscreen');
|
||||
|
||||
// Whether to show controls
|
||||
show = _inArray(['mousemove', 'mouseenter', 'focus'], toggle.type);
|
||||
|
||||
// Delay hiding on mousemove events
|
||||
if (toggle.type === 'mousemove') {
|
||||
delay = 2000;
|
||||
}
|
||||
|
||||
// Delay a little more for keyboard users
|
||||
if (toggle.type === 'focus') {
|
||||
delay = 3000;
|
||||
}
|
||||
}
|
||||
else {
|
||||
show = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Clear timer every movement
|
||||
window.clearTimeout(plyr.timers.hover);
|
||||
|
||||
// If the mouse is not over the controls, set a timeout to hide them
|
||||
plyr.timers.hover = window.setTimeout(function() {
|
||||
if (!plyr.controls.mouseover || (force === true)) {
|
||||
_toggleClass(plyr.container, config.classes.hover, false);
|
||||
if(show || plyr.media.paused) {
|
||||
_toggleClass(plyr.container, config.classes.hideControls, false);
|
||||
|
||||
// Always show controls when paused
|
||||
if(plyr.media.paused) {
|
||||
return;
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// If toggle is false or if we're playing (regardless of toggle), then
|
||||
// set the timer to hide the controls
|
||||
if(!show || !plyr.media.paused) {
|
||||
plyr.timers.hover = window.setTimeout(function() {
|
||||
// If the mouse is over the controls (and not entering fullscreen), bail
|
||||
if(plyr.controls.active && !isEnterFullscreen) {
|
||||
return;
|
||||
}
|
||||
|
||||
_toggleClass(plyr.container, config.classes.hideControls, true);
|
||||
}, delay);
|
||||
}
|
||||
}
|
||||
|
||||
// Add common function to retrieve media source
|
||||
@ -2217,6 +2278,14 @@
|
||||
// Pause playback
|
||||
_pause();
|
||||
|
||||
// Set seek input to 0
|
||||
if (plyr.buttons && plyr.buttons.seek) {
|
||||
plyr.buttons.seek.value = 0;
|
||||
}
|
||||
if (plyr.progress && plyr.progress.played) {
|
||||
plyr.progress.played.value = 0;
|
||||
}
|
||||
|
||||
// Clean up YouTube stuff
|
||||
if (plyr.type === 'youtube') {
|
||||
// Destroy the embed instance
|
||||
@ -2277,6 +2346,11 @@
|
||||
// Inject the new element
|
||||
_prependChild(plyr.container, plyr.media);
|
||||
|
||||
// Autoplay the new source?
|
||||
if (typeof source.autoplay !== 'undefined') {
|
||||
config.autoplay = source.autoplay;
|
||||
}
|
||||
|
||||
// Set attributes for audio video
|
||||
if (_inArray(config.types.html5, plyr.type)) {
|
||||
if (config.crossorigin) {
|
||||
@ -2301,9 +2375,6 @@
|
||||
_toggleClass(plyr.container, config.classes.captions.active, plyr.captionsEnabled);
|
||||
_toggleStyleHook();
|
||||
|
||||
// Autoplay the new source?
|
||||
config.autoplay = (source.autoplay || config.autoplay);
|
||||
|
||||
// Set new sources for html5
|
||||
if (_inArray(config.types.html5, plyr.type)) {
|
||||
_insertChildElements('source', source.sources);
|
||||
@ -2329,11 +2400,6 @@
|
||||
_displayDuration();
|
||||
}
|
||||
|
||||
// Play if autoplay attribute is present
|
||||
if (config.autoplay) {
|
||||
_play();
|
||||
}
|
||||
|
||||
// Set aria title and iframe title
|
||||
config.title = source.title;
|
||||
_setTitle();
|
||||
@ -2370,6 +2436,14 @@
|
||||
var trigger = plyr.buttons[play ? 'play' : 'pause'],
|
||||
target = plyr.buttons[play ? 'pause' : 'play'];
|
||||
|
||||
// Get the last play button to account for the large play button
|
||||
if(target && target.length > 1) {
|
||||
target = target[target.length - 1];
|
||||
}
|
||||
else {
|
||||
target = target[0];
|
||||
}
|
||||
|
||||
// Setup focus and tab focus
|
||||
if(target) {
|
||||
var hadTabFocus = _hasClass(trigger, config.classes.tabFocus);
|
||||
@ -2388,6 +2462,7 @@
|
||||
// Detect tab focus
|
||||
function checkFocus() {
|
||||
var focused = document.activeElement;
|
||||
|
||||
if (!focused || focused == document.body) {
|
||||
focused = null;
|
||||
}
|
||||
@ -2397,7 +2472,14 @@
|
||||
for (var button in plyr.buttons) {
|
||||
var element = plyr.buttons[button];
|
||||
|
||||
_toggleClass(element, config.classes.tabFocus, (element === focused));
|
||||
if (element instanceof NodeList) {
|
||||
for (var i = 0; i < element.length; i++) {
|
||||
_toggleClass(element[i], config.classes.tabFocus, (element[i] === focused));
|
||||
}
|
||||
}
|
||||
else {
|
||||
_toggleClass(element, config.classes.tabFocus, (element === focused));
|
||||
}
|
||||
}
|
||||
}
|
||||
_on(window, 'keyup', function(event) {
|
||||
@ -2437,8 +2519,8 @@
|
||||
_proxyListener(plyr.buttons.seek, inputEvent, config.listeners.seek, _seek);
|
||||
|
||||
// Set volume
|
||||
_proxyListener(plyr.volume, inputEvent, config.listeners.volume, function() {
|
||||
_setVolume(plyr.volume.value);
|
||||
_proxyListener(plyr.volume.input, inputEvent, config.listeners.volume, function() {
|
||||
_setVolume(plyr.volume.input.value);
|
||||
});
|
||||
|
||||
// Mute
|
||||
@ -2458,14 +2540,18 @@
|
||||
// Seek tooltip
|
||||
_on(plyr.progress.container, 'mouseenter mouseleave mousemove', _updateSeekTooltip);
|
||||
|
||||
// Toggle controls visibility based on mouse movement and location
|
||||
var hoverTimer, isMouseOver = false;
|
||||
// Toggle controls visibility based on mouse movement
|
||||
if (config.hideControls) {
|
||||
// Toggle controls on mouse events and entering fullscreen
|
||||
_on(plyr.container, 'mouseenter mouseleave mousemove enterfullscreen', _toggleControls);
|
||||
|
||||
if (config.fullscreen.hideControls) {
|
||||
// Keep an eye on the mouse location in relation to controls
|
||||
_on(plyr.controls, 'mouseenter mouseleave', function(event) {
|
||||
plyr.controls.mouseover = (event.type === 'mouseenter');
|
||||
// Watch for cursor over controls so they don't hide when trying to interact
|
||||
_on(plyr.controls, 'mouseenter mouseleave', function(event) {
|
||||
plyr.controls.active = (event.type === 'mouseenter');
|
||||
});
|
||||
|
||||
// Focus in/out on controls
|
||||
_on(plyr.controls, 'focus blur', _toggleControls, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2504,8 +2590,20 @@
|
||||
_on(plyr.media, 'waiting canplay seeked', _checkLoading);
|
||||
|
||||
// Click video
|
||||
if (config.click) {
|
||||
_on(plyr.media, 'click', function() {
|
||||
if (config.clickToPlay && plyr.type !== 'audio') {
|
||||
// Re-fetch the wrapper
|
||||
var wrapper = _getElement('.' + config.classes.videoWrapper);
|
||||
|
||||
// Bail if there's no wrapper (this should never happen)
|
||||
if(!wrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set cursor
|
||||
wrapper.style.cursor = "pointer";
|
||||
|
||||
// On click play, pause ore restart
|
||||
_on(wrapper, 'click', function() {
|
||||
if (plyr.media.paused) {
|
||||
_play();
|
||||
}
|
||||
@ -2519,12 +2617,6 @@
|
||||
});
|
||||
}
|
||||
|
||||
// Listen for mouse move to show controls
|
||||
if (config.fullscreen.hideControls) {
|
||||
// Show the controls on mouse move
|
||||
_on(plyr.media, 'mousemove', _showControls);
|
||||
}
|
||||
|
||||
// Proxy events to container
|
||||
_on(plyr.media, config.events.join(' '), function(event) {
|
||||
_triggerEvent(plyr.container, event.type);
|
||||
@ -2590,7 +2682,7 @@
|
||||
}
|
||||
|
||||
// Restore native video controls
|
||||
_toggleControls(true);
|
||||
_toggleNativeControls(true);
|
||||
|
||||
// Clone the media element to remove listeners
|
||||
// http://stackoverflow.com/questions/19469881/javascript-remove-all-event-listeners-of-specific-type
|
||||
@ -2612,7 +2704,17 @@
|
||||
plyr.browser = _browserSniff();
|
||||
|
||||
// Get the media element
|
||||
plyr.media = plyr.container.querySelectorAll('audio, video, div')[0];
|
||||
plyr.media = plyr.container.querySelectorAll('audio, video')[0];
|
||||
|
||||
// Get the div placeholder for YouTube and Vimeo
|
||||
if(!plyr.media) {
|
||||
plyr.media = plyr.container.querySelectorAll('div')[0];
|
||||
}
|
||||
|
||||
// Bail if nothing to setup
|
||||
if(!plyr.media) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get original classname
|
||||
plyr.originalClassName = plyr.container.className;
|
||||
@ -2668,6 +2770,11 @@
|
||||
|
||||
// Set title on button and frame
|
||||
_setTitle();
|
||||
|
||||
// Autoplay
|
||||
if (config.autoplay) {
|
||||
_play();
|
||||
}
|
||||
}
|
||||
|
||||
// Successful setup
|
||||
@ -2682,8 +2789,11 @@
|
||||
// Remove controls
|
||||
_remove(_getElement(config.selectors.controls.wrapper));
|
||||
|
||||
// Remove large play
|
||||
_remove(_getElement(config.selectors.buttons.play));
|
||||
|
||||
// Restore native controls
|
||||
_toggleControls(true);
|
||||
_toggleNativeControls(true);
|
||||
|
||||
// Bail
|
||||
return;
|
||||
@ -2710,7 +2820,7 @@
|
||||
_mediaListeners();
|
||||
|
||||
// Remove native controls
|
||||
_toggleControls();
|
||||
_toggleNativeControls();
|
||||
|
||||
// Setup fullscreen
|
||||
_setupFullscreen();
|
||||
@ -2834,7 +2944,7 @@
|
||||
}
|
||||
|
||||
// Create a player instance for each element
|
||||
for (var i = elements.length - 1; i >= 0; i--) {
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
// Get the current element
|
||||
var element = elements[i];
|
||||
|
||||
|
29
src/less/mixins.less
Normal file
@ -0,0 +1,29 @@
|
||||
// ==========================================================================
|
||||
// Plyr mixins
|
||||
// https://github.com/selz/plyr
|
||||
// ==========================================================================
|
||||
|
||||
// <input type="range"> styling
|
||||
.plyr-range-track() {
|
||||
height: @plyr-range-track-height;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-radius: (@plyr-range-track-height / 2);
|
||||
user-select: none;
|
||||
}
|
||||
.plyr-range-thumb() {
|
||||
position: relative;
|
||||
height: @plyr-range-thumb-height;
|
||||
width: @plyr-range-thumb-width;
|
||||
background: @plyr-range-thumb-bg;
|
||||
border: @plyr-range-thumb-border;
|
||||
border-radius: 100%;
|
||||
transition: background .2s ease, border .2s ease, transform .2s ease;
|
||||
box-shadow: @plyr-range-thumb-shadow;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.plyr-range-thumb-active() {
|
||||
background: @plyr-range-thumb-active-bg;
|
||||
border-color: @plyr-range-thumb-active-border-color;
|
||||
transform: scale(@plyr-range-thumb-active-scale);
|
||||
}
|
1269
src/less/plyr.less
66
src/less/variables.less
Normal file
@ -0,0 +1,66 @@
|
||||
// ==========================================================================
|
||||
// Plyr variables
|
||||
// https://github.com/selz/plyr
|
||||
// ==========================================================================
|
||||
|
||||
// Colors
|
||||
@plyr-color-main: #3498db;
|
||||
|
||||
// Font sizes
|
||||
@plyr-font-size-small: 14px;
|
||||
@plyr-font-size-base: 16px;
|
||||
|
||||
// Captions
|
||||
@plyr-font-size-captions-base: ceil(@plyr-font-size-base * 1.25);
|
||||
@plyr-font-size-captions-medium: ceil(@plyr-font-size-base * 1.5);
|
||||
@plyr-font-size-captions-large: (@plyr-font-size-base * 2);
|
||||
|
||||
// Controls
|
||||
@plyr-control-spacing: 10px;
|
||||
@plyr-video-controls-bg: #000;
|
||||
@plyr-video-control-color: #fff;
|
||||
@plyr-video-control-color-hover: #fff;
|
||||
@plyr-video-control-bg-hover: @plyr-color-main;
|
||||
@plyr-audio-controls-bg: #fff;
|
||||
@plyr-audio-controls-border: 1px solid #dbe3e8;
|
||||
@plyr-audio-controls-box-shadow: 0 1px 1px fade(#000, 5%);
|
||||
@plyr-audio-control-color: #565D64;
|
||||
@plyr-audio-control-color-hover: #fff;
|
||||
@plyr-audio-control-bg-hover: @plyr-color-main;
|
||||
|
||||
// Tooltips
|
||||
@plyr-tooltip-bg: @plyr-video-controls-bg;
|
||||
@plyr-tooltip-border-color: fade(darken(@plyr-video-controls-bg, 75%), 10%);
|
||||
@plyr-tooltip-arrow-border-color: fade(darken(@plyr-video-controls-bg, 75%), 20%);
|
||||
@plyr-tooltip-border-width: 1px;
|
||||
@plyr-tooltip-shadow: 0 0 5px @plyr-tooltip-border-color, 0 0 0 @plyr-tooltip-border-width @plyr-tooltip-border-color;
|
||||
@plyr-tooltip-color: @plyr-video-control-color;
|
||||
@plyr-tooltip-padding: (@plyr-control-spacing / 2);
|
||||
@plyr-tooltip-arrow-size: 4px;
|
||||
@plyr-tooltip-radius: 3px;
|
||||
|
||||
// Progress
|
||||
@plyr-progress-loading-size: 25px;
|
||||
@plyr-progress-loading-bg: fade(#000, 15%);
|
||||
@plyr-video-progress-bg: fade(#fff, 25%);
|
||||
@plyr-video-progress-buffered-bg: @plyr-video-progress-bg;
|
||||
@plyr-audio-progress-bg: fade(#C6D6DB, 66%);
|
||||
@plyr-audio-progress-buffered-bg: @plyr-audio-progress-bg;
|
||||
|
||||
// Range sliders
|
||||
@plyr-range-track-height: 8px;
|
||||
@plyr-range-thumb-height: floor(@plyr-range-track-height * 2);
|
||||
@plyr-range-thumb-width: floor(@plyr-range-track-height * 2);
|
||||
@plyr-range-thumb-bg: #fff;
|
||||
@plyr-range-thumb-border: 2px solid transparent;
|
||||
@plyr-range-thumb-shadow: 0 1px 1px fade(@plyr-video-controls-bg, 15%), 0 0 0 1px fade(#000, 15%);
|
||||
@plyr-range-thumb-active-border-color: #fff;
|
||||
@plyr-range-thumb-active-bg: @plyr-video-control-bg-hover;
|
||||
@plyr-range-thumb-active-scale: 1.25;
|
||||
@plyr-video-range-track-bg: @plyr-video-progress-buffered-bg;
|
||||
@plyr-audio-range-track-bg: @plyr-audio-progress-buffered-bg;
|
||||
@plyr-range-selected-bg: @plyr-color-main;
|
||||
|
||||
// Breakpoints
|
||||
@plyr-bp-screen-sm: 480px;
|
||||
@plyr-bp-screen-md: 768px;
|
@ -1,718 +0,0 @@
|
||||
// ==========================================================================
|
||||
// Plyr styles
|
||||
// https://github.com/selz/plyr
|
||||
// ==========================================================================
|
||||
|
||||
// Variables
|
||||
// -------------------------------
|
||||
|
||||
// Colors
|
||||
$plyr-blue: #3498DB !default;
|
||||
$plyr-gray-dark: #343F4A !default;
|
||||
$plyr-gray: #565D64 !default;
|
||||
$plyr-gray-light: #6B7D86 !default;
|
||||
$plyr-gray-lighter: #CBD0D3 !default;
|
||||
$plyr-off-white: #D6DADD !default;
|
||||
|
||||
// Font sizes
|
||||
$plyr-font-size-small: 14px !default;
|
||||
$plyr-font-size-base: 16px !default;
|
||||
|
||||
// Captions
|
||||
$plyr-font-size-captions-base: ceil($plyr-font-size-base * 1.25) !default;
|
||||
$plyr-font-size-captions-medium: ceil($plyr-font-size-base * 1.5) !default;
|
||||
$plyr-font-size-captions-large: ($plyr-font-size-base * 2) !default;
|
||||
|
||||
// Controls
|
||||
$plyr-control-spacing: 10px !default;
|
||||
$plyr-controls-bg: #fff !default;
|
||||
$plyr-control-bg-hover: $plyr-blue !default;
|
||||
|
||||
// Contrast
|
||||
@if lightness($plyr-controls-bg) >= 65% {
|
||||
$plyr-control-color: $plyr-gray-light !default;
|
||||
}
|
||||
@else {
|
||||
$plyr-control-color: $plyr-gray-lighter !default;
|
||||
}
|
||||
@if lightness($plyr-control-bg-hover) >= 65% {
|
||||
$plyr-control-color-hover: $plyr-gray !default;
|
||||
}
|
||||
@else {
|
||||
$plyr-control-color-hover: #fff !default;
|
||||
}
|
||||
|
||||
// Tooltips
|
||||
$plyr-tooltip-bg: $plyr-controls-bg !default;
|
||||
$plyr-tooltip-border-color: transparentize(darken($plyr-controls-bg, 75%), .9) !default;
|
||||
$plyr-tooltip-arrow-border-color: transparentize(darken($plyr-controls-bg, 75%), .8) !default;
|
||||
|
||||
$plyr-tooltip-border-width: 1px;
|
||||
$plyr-tooltip-shadow: 0 0 5px $plyr-tooltip-border-color, 0 0 0 $plyr-tooltip-border-width $plyr-tooltip-border-color;
|
||||
$plyr-tooltip-color: $plyr-control-color !default;
|
||||
$plyr-tooltip-padding: $plyr-control-spacing !default;
|
||||
$plyr-tooltip-arrow-size: 6px !default;
|
||||
$plyr-tooltip-radius: 3px !default;
|
||||
|
||||
// Progress
|
||||
$plyr-progress-bg: transparentize($plyr-gray, .8) !default;
|
||||
$plyr-progress-playing-bg: $plyr-blue !default;
|
||||
$plyr-progress-buffered-bg: transparentize($plyr-gray, .75) !default;
|
||||
$plyr-progress-loading-size: 40px !default;
|
||||
$plyr-progress-loading-bg: transparentize(#000, .85) !default;
|
||||
|
||||
// Volume
|
||||
$plyr-volume-track-height: 6px !default;
|
||||
$plyr-volume-track-bg: darken($plyr-controls-bg, 10%) !default;
|
||||
$plyr-volume-thumb-height: ($plyr-volume-track-height * 2) !default;
|
||||
$plyr-volume-thumb-width: ($plyr-volume-track-height * 2) !default;
|
||||
$plyr-volume-thumb-bg: $plyr-control-color !default;
|
||||
$plyr-volume-thumb-bg-focus: $plyr-control-bg-hover !default;
|
||||
|
||||
// Breakpoints
|
||||
$plyr-bp-control-split: 560px !default; // When controls split into left/right
|
||||
$plyr-bp-captions-large: 768px !default; // When captions jump to the larger font size
|
||||
|
||||
// Animation
|
||||
// ---------------------------------------
|
||||
@keyframes plyr-progress {
|
||||
to { background-position: $plyr-progress-loading-size 0; }
|
||||
}
|
||||
|
||||
// Font smoothing
|
||||
@mixin font-smoothing($mode: on)
|
||||
{
|
||||
@if ($mode == 'on') {
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
@else if ($mode == 'off') {
|
||||
-moz-osx-font-smoothing: auto;
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
}
|
||||
}
|
||||
|
||||
// <input type="range"> styling
|
||||
@mixin volume-thumb() {
|
||||
height: $plyr-volume-thumb-height;
|
||||
width: $plyr-volume-thumb-width;
|
||||
background: $plyr-volume-thumb-bg;
|
||||
border: 0;
|
||||
border-radius: 100%;
|
||||
transition: background .3s ease;
|
||||
cursor: ew-resize;
|
||||
}
|
||||
@mixin volume-track() {
|
||||
height: $plyr-volume-track-height;
|
||||
background: $plyr-volume-track-bg;
|
||||
border: 0;
|
||||
border-radius: ($plyr-volume-track-height / 2);
|
||||
}
|
||||
@mixin seek-thumb() {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
width: 1px;
|
||||
height: $plyr-control-spacing;
|
||||
}
|
||||
@mixin seek-thumb-touch() {
|
||||
width: ($plyr-control-spacing * 4);
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
@mixin seek-track() {
|
||||
background: none;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
// Styles
|
||||
// -------------------------------
|
||||
// Base
|
||||
.plyr {
|
||||
position: relative;
|
||||
max-width: 100%;
|
||||
min-width: 290px;
|
||||
font-family: Avenir, "Avenir Next", "Helvetica Neue", "Segoe UI", Helvetica, Arial, sans-serif;
|
||||
|
||||
// border-box everything
|
||||
// http://paulirish.com/2012/box-sizing-border-box-ftw/
|
||||
&,
|
||||
*,
|
||||
*::after,
|
||||
*::before {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// Fix 300ms delay
|
||||
a, button, input, label {
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
// Screen reader only
|
||||
&__sr-only {
|
||||
position: absolute !important;
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
padding: 0 !important;
|
||||
border: 0 !important;
|
||||
height: 1px !important;
|
||||
width: 1px !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// For video
|
||||
&__video-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
video,
|
||||
audio {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
// Hide default captions
|
||||
video::-webkit-media-text-track-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// For embeds
|
||||
&__video-embed {
|
||||
padding-bottom: 56.25%; /* 16:9 */
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
background: #000;
|
||||
|
||||
iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
// Vimeo hack
|
||||
> div {
|
||||
position: relative;
|
||||
padding-bottom: 200%;
|
||||
transform: translateY(-35.95%);
|
||||
}
|
||||
|
||||
// To allow mouse events to be captured if full support
|
||||
&.plyr iframe {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Captions
|
||||
&__captions {
|
||||
display: none;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
padding: ($plyr-control-spacing * 2) ($plyr-control-spacing * 2) ($plyr-control-spacing * 3);
|
||||
color: #fff;
|
||||
font-size: $plyr-font-size-captions-base;
|
||||
text-align: center;
|
||||
@include font-smoothing();
|
||||
|
||||
span {
|
||||
border-radius: 2px;
|
||||
padding: 3px 10px;
|
||||
background: transparentize(#000, .1);
|
||||
}
|
||||
span:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: $plyr-bp-captions-large) {
|
||||
font-size: $plyr-font-size-captions-medium;
|
||||
}
|
||||
}
|
||||
&--captions-active &__captions {
|
||||
display: block;
|
||||
}
|
||||
&--fullscreen-active &__captions {
|
||||
font-size: $plyr-font-size-captions-large;
|
||||
}
|
||||
|
||||
// Playback controls
|
||||
&__controls {
|
||||
@include font-smoothing();
|
||||
position: relative;
|
||||
padding: $plyr-control-spacing;
|
||||
background: $plyr-controls-bg;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
box-shadow: 0 1px 1px transparentize($plyr-gray-dark, .8);
|
||||
|
||||
// Clear floats
|
||||
&::after {
|
||||
content: '';
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
// Layout
|
||||
&--right {
|
||||
display: block;
|
||||
margin: $plyr-control-spacing auto 0;
|
||||
}
|
||||
@media (min-width: $plyr-bp-control-split) {
|
||||
&--left {
|
||||
float: left;
|
||||
}
|
||||
&--right {
|
||||
float: right;
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Buttons
|
||||
button {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin: 0 2px;
|
||||
padding: ($plyr-control-spacing / 2) $plyr-control-spacing;
|
||||
overflow: hidden;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
color: $plyr-control-color;
|
||||
transition: background .3s ease, color .3s ease, opacity .3s ease;
|
||||
|
||||
svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: block;
|
||||
fill: currentColor;
|
||||
transition: fill .3s ease;
|
||||
}
|
||||
|
||||
// Hover and tab focus
|
||||
&.tab-focus:hover,
|
||||
&:hover {
|
||||
background: $plyr-control-bg-hover;
|
||||
color: $plyr-control-color-hover;
|
||||
}
|
||||
// Default focus
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Hide toggle icons by default
|
||||
.icon--exit-fullscreen,
|
||||
.icon--muted,
|
||||
.icon--captions-on {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Time display
|
||||
.plyr__time {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-left: $plyr-control-spacing;
|
||||
color: $plyr-control-color;
|
||||
font-weight: 600;
|
||||
font-size: $plyr-font-size-small;
|
||||
}
|
||||
|
||||
// Media duration hidden on small screens
|
||||
.plyr__time + .plyr__time {
|
||||
display: none;
|
||||
|
||||
@media (min-width: $plyr-bp-control-split) {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
// Add a slash in before
|
||||
&::before {
|
||||
content: '\2044';
|
||||
margin-right: $plyr-control-spacing;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tooltips
|
||||
&__tooltip {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
bottom: 100%;
|
||||
margin-bottom: $plyr-tooltip-padding;
|
||||
padding: $plyr-tooltip-padding ($plyr-tooltip-padding * 1.5);
|
||||
|
||||
opacity: 0;
|
||||
background: $plyr-tooltip-bg;
|
||||
box-shadow: $plyr-tooltip-shadow;
|
||||
border-radius: $plyr-tooltip-radius;
|
||||
color: $plyr-tooltip-color;
|
||||
font-size: $plyr-font-size-small;
|
||||
line-height: 1.5;
|
||||
font-weight: 600;
|
||||
|
||||
transform: translate(-50%, 10px) scale(.8);
|
||||
transform-origin: 50% 100%;
|
||||
transition: transform .2s .1s ease, opacity .2s .1s ease, visibility .3s ease;
|
||||
|
||||
// Arrows
|
||||
&::after,
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
// The border triangle
|
||||
&::after {
|
||||
$plyr-border-arrow-size: ($plyr-tooltip-arrow-size + ($plyr-tooltip-border-width * 1));
|
||||
bottom: -($plyr-border-arrow-size + $plyr-tooltip-border-width);
|
||||
border-right: $plyr-border-arrow-size solid transparent;
|
||||
border-top: $plyr-border-arrow-size solid $plyr-tooltip-arrow-border-color;
|
||||
border-left: $plyr-border-arrow-size solid transparent;
|
||||
z-index: 1;
|
||||
}
|
||||
// The background triangle
|
||||
&::before {
|
||||
bottom: -$plyr-tooltip-arrow-size;
|
||||
border-right: $plyr-tooltip-arrow-size solid transparent;
|
||||
border-top: $plyr-tooltip-arrow-size solid $plyr-tooltip-bg;
|
||||
border-left: $plyr-tooltip-arrow-size solid transparent;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
button:hover .plyr__tooltip,
|
||||
button.tab-focus:focus .plyr__tooltip,
|
||||
&__tooltip--visible {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transform: translate(-50%, 0) scale(1);
|
||||
}
|
||||
button:hover .plyr__tooltip {
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
// Common range styles
|
||||
input[type='range'].tab-focus:focus {
|
||||
outline: thin dotted transparentize($plyr-gray-dark, .8);
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
// Playback progress
|
||||
// <progress> element
|
||||
&__progress {
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: $plyr-control-spacing;
|
||||
background: $plyr-progress-bg;
|
||||
|
||||
&--buffer[value],
|
||||
&--played[value],
|
||||
&--seek[type='range'] {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: $plyr-control-spacing;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
vertical-align: top;
|
||||
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
&--buffer[value],
|
||||
&--played[value] {
|
||||
&::-webkit-progress-bar {
|
||||
background: transparent;
|
||||
transition: width .2s ease;
|
||||
}
|
||||
|
||||
// Inherit from currentColor;
|
||||
&::-webkit-progress-value {
|
||||
background: currentColor;
|
||||
transition: width .2s ease;
|
||||
}
|
||||
&::-moz-progress-bar {
|
||||
background: currentColor;
|
||||
transition: width .2s ease;
|
||||
}
|
||||
}
|
||||
&--played[value] {
|
||||
z-index: 2;
|
||||
color: $plyr-progress-playing-bg;
|
||||
}
|
||||
&--buffer[value] {
|
||||
color: $plyr-progress-buffered-bg;
|
||||
}
|
||||
|
||||
// Seek control
|
||||
// <input[type='range']> element
|
||||
// Specificity is for bootstrap compatibility
|
||||
&--seek[type='range'] {
|
||||
z-index: 4;
|
||||
cursor: pointer;
|
||||
outline: 0;
|
||||
|
||||
// Webkit
|
||||
&::-webkit-slider-runnable-track {
|
||||
@include seek-track();
|
||||
}
|
||||
&::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
@include seek-thumb();
|
||||
}
|
||||
|
||||
// Mozilla
|
||||
&::-moz-range-track {
|
||||
@include seek-track();
|
||||
}
|
||||
&::-moz-range-thumb {
|
||||
-moz-appearance: none;
|
||||
@include seek-thumb();
|
||||
}
|
||||
|
||||
// Microsoft
|
||||
&::-ms-track {
|
||||
color: transparent;
|
||||
@include seek-track();
|
||||
}
|
||||
&::-ms-fill-lower,
|
||||
&::-ms-fill-upper {
|
||||
@include seek-track();
|
||||
}
|
||||
&::-ms-thumb {
|
||||
@include seek-thumb();
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
&::-moz-focus-outer {
|
||||
border: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Seek tooltip to show time
|
||||
.plyr__tooltip {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Touch seek wider handle
|
||||
&--is-touch &--seek[type='range'] {
|
||||
&::-webkit-slider-thumb {
|
||||
@include seek-thumb-touch();
|
||||
}
|
||||
// Mozilla
|
||||
&::-moz-range-thumb {
|
||||
@include seek-thumb-touch();
|
||||
}
|
||||
// Microsoft
|
||||
&::-ms-thumb {
|
||||
@include seek-thumb-touch();
|
||||
}
|
||||
}
|
||||
|
||||
// Loading state
|
||||
&--loading .plyr__progress--buffer {
|
||||
animation: plyr-progress 1s linear infinite;
|
||||
background-size: $plyr-progress-loading-size $plyr-progress-loading-size;
|
||||
background-repeat: repeat-x;
|
||||
background-color: $plyr-progress-buffered-bg;
|
||||
background-image: linear-gradient(
|
||||
-45deg,
|
||||
$plyr-progress-loading-bg 25%,
|
||||
transparent 25%,
|
||||
transparent 50%,
|
||||
$plyr-progress-loading-bg 50%,
|
||||
$plyr-progress-loading-bg 75%,
|
||||
transparent 75%,
|
||||
transparent);
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
// States
|
||||
&__controls [data-plyr='pause'],
|
||||
&--playing .plyr__controls [data-plyr='play'] {
|
||||
display: none;
|
||||
}
|
||||
&--playing .plyr__controls [data-plyr='pause'] {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
// Volume control
|
||||
// <input[type='range']> element
|
||||
// Specificity is for bootstrap compatibility
|
||||
&__volume[type='range'] {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
width: 100px;
|
||||
margin: 0 $plyr-control-spacing 0 0;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
border: none;
|
||||
|
||||
// Webkit
|
||||
&::-webkit-slider-runnable-track {
|
||||
@include volume-track();
|
||||
}
|
||||
&::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
margin-top: -(($plyr-volume-thumb-height - $plyr-volume-track-height) / 2);
|
||||
@include volume-thumb();
|
||||
}
|
||||
|
||||
// Mozilla
|
||||
&::-moz-range-track {
|
||||
@include volume-track();
|
||||
}
|
||||
&::-moz-range-thumb {
|
||||
@include volume-thumb();
|
||||
}
|
||||
|
||||
// Microsoft
|
||||
&::-ms-track {
|
||||
height: $plyr-volume-track-height;
|
||||
background: transparent;
|
||||
border-color: transparent;
|
||||
border-width: (($plyr-volume-thumb-height - $plyr-volume-track-height) / 2) 0;
|
||||
color: transparent;
|
||||
}
|
||||
&::-ms-fill-lower,
|
||||
&::-ms-fill-upper {
|
||||
@include volume-track();
|
||||
}
|
||||
&::-ms-thumb {
|
||||
@include volume-thumb();
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
|
||||
&::-webkit-slider-thumb {
|
||||
background: $plyr-volume-thumb-bg-focus;
|
||||
}
|
||||
&::-moz-range-thumb {
|
||||
background: $plyr-volume-thumb-bg-focus;
|
||||
}
|
||||
&::-ms-thumb {
|
||||
background: $plyr-volume-thumb-bg-focus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hide sound controls on iOS
|
||||
// It's not supported to change volume using JavaScript:
|
||||
// https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html
|
||||
&--is-ios &__volume,
|
||||
&--is-ios [data-plyr='mute'],
|
||||
&--is-ios.plyr--audio &__controls--right {
|
||||
display: none;
|
||||
}
|
||||
// Center buttons so it looks less odd
|
||||
&--is-ios.plyr--audio &__controls--left {
|
||||
float: none;
|
||||
}
|
||||
|
||||
// Audio specific styles
|
||||
// Position the progress within the container
|
||||
&--audio .plyr__controls {
|
||||
padding-top: ($plyr-control-spacing * 2);
|
||||
}
|
||||
&--audio .plyr__progress {
|
||||
bottom: auto;
|
||||
top: 0;
|
||||
background: $plyr-off-white;
|
||||
}
|
||||
|
||||
// Full screen mode
|
||||
&--fullscreen,
|
||||
&--fullscreen-active {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 10000000;
|
||||
background: #000;
|
||||
|
||||
video {
|
||||
height: 100%;
|
||||
}
|
||||
.plyr__video-wrapper {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
.plyr__controls {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Hide controls when playing in full screen
|
||||
&--fullscreen-active.plyr--fullscreen--hide-controls.plyr--playing,
|
||||
&.plyr--fullscreen.plyr--fullscreen--hide-controls.plyr--playing {
|
||||
.plyr__controls {
|
||||
transform: translateY(100%) translateY($plyr-control-spacing / 2);
|
||||
transition: transform .3s .2s ease;
|
||||
}
|
||||
.plyr__captions {
|
||||
bottom: ($plyr-control-spacing / 2);
|
||||
transition: bottom .3s .2s ease;
|
||||
}
|
||||
&.plyr--hover .plyr__controls {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Captions
|
||||
&.plyr--fullscreen .plyr__captions,
|
||||
&--fullscreen-active .plyr__captions,
|
||||
&--fullscreen--hide-controls.plyr--fullscreen-active.plyr--playing.plyr--hover .plyr__captions {
|
||||
top: auto;
|
||||
bottom: 90px;
|
||||
|
||||
@media (min-width: $plyr-bp-control-split) {
|
||||
bottom: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
// Change icons on state change
|
||||
&--fullscreen-active .icon--exit-fullscreen,
|
||||
&--muted .plyr__controls .icon--muted,
|
||||
&--captions-active .plyr__controls .icon--captions-on {
|
||||
display: block;
|
||||
|
||||
& + svg {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Some options are hidden by default
|
||||
[data-plyr='captions'],
|
||||
[data-plyr='fullscreen'] {
|
||||
display: none;
|
||||
}
|
||||
&--captions-enabled [data-plyr='captions'],
|
||||
&--fullscreen-enabled [data-plyr='fullscreen'] {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
29
src/scss/mixins.scss
Normal file
@ -0,0 +1,29 @@
|
||||
// ==========================================================================
|
||||
// Plyr mixins
|
||||
// https://github.com/selz/plyr
|
||||
// ==========================================================================
|
||||
|
||||
// <input type="range"> styling
|
||||
@mixin plyr-range-track() {
|
||||
height: $plyr-range-track-height;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
border-radius: ($plyr-range-track-height / 2);
|
||||
user-select: none;
|
||||
}
|
||||
@mixin plyr-range-thumb() {
|
||||
position: relative;
|
||||
height: $plyr-range-thumb-height;
|
||||
width: $plyr-range-thumb-width;
|
||||
background: $plyr-range-thumb-bg;
|
||||
border: $plyr-range-thumb-border;
|
||||
border-radius: 100%;
|
||||
transition: background .2s ease, border .2s ease, transform .2s ease;
|
||||
box-shadow: $plyr-range-thumb-shadow;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
@mixin plyr-range-thumb-active() {
|
||||
background: $plyr-range-thumb-active-bg;
|
||||
border-color: $plyr-range-thumb-active-border-color;
|
||||
transform: scale($plyr-range-thumb-active-scale);
|
||||
}
|
686
src/scss/plyr.scss
Normal file
@ -0,0 +1,686 @@
|
||||
// ==========================================================================
|
||||
// Plyr styles
|
||||
// https://github.com/selz/plyr
|
||||
// ==========================================================================
|
||||
|
||||
@import "variables";
|
||||
@import "mixins";
|
||||
|
||||
// Animation
|
||||
// ---------------------------------------
|
||||
@keyframes plyr-progress {
|
||||
to { background-position: $plyr-progress-loading-size 0; }
|
||||
}
|
||||
|
||||
// Styles
|
||||
// -------------------------------
|
||||
// Base
|
||||
.plyr {
|
||||
position: relative;
|
||||
max-width: 100%;
|
||||
min-width: 200px;
|
||||
font-family: Avenir, "Avenir Next", "Helvetica Neue", "Segoe UI", Helvetica, Arial, sans-serif;
|
||||
|
||||
// border-box everything
|
||||
// http://paulirish.com/2012/box-sizing-border-box-ftw/
|
||||
&,
|
||||
*,
|
||||
*::after,
|
||||
*::before {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
// Fix 300ms delay
|
||||
a, button, input, label {
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
// Media elements
|
||||
video,
|
||||
audio {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
vertical-align: middle;
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
// Range inputs
|
||||
// Specificity is for bootstrap compatibility
|
||||
input[type='range'] {
|
||||
display: block;
|
||||
height: ($plyr-range-thumb-height * $plyr-range-thumb-active-scale);
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
vertical-align: middle;
|
||||
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
background: transparent;
|
||||
|
||||
// WebKit
|
||||
&::-webkit-slider-runnable-track {
|
||||
@include plyr-range-track();
|
||||
}
|
||||
&::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
margin-top: -(($plyr-range-thumb-height - $plyr-range-track-height) / 2);
|
||||
@include plyr-range-thumb();
|
||||
}
|
||||
|
||||
// Mozilla
|
||||
&::-moz-range-track {
|
||||
@include plyr-range-track();
|
||||
}
|
||||
&::-moz-range-thumb {
|
||||
@include plyr-range-thumb();
|
||||
}
|
||||
&::-moz-focus-outer {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
// Microsoft
|
||||
&::-ms-track {
|
||||
height: $plyr-range-track-height;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
color: transparent;
|
||||
}
|
||||
&::-ms-fill-upper {
|
||||
@include plyr-range-track();
|
||||
}
|
||||
&::-ms-fill-lower {
|
||||
@include plyr-range-track();
|
||||
background: $plyr-range-selected-bg;
|
||||
}
|
||||
&::-ms-thumb {
|
||||
@include plyr-range-thumb();
|
||||
// For some reason, Edge uses the -webkit margin above
|
||||
margin-top: 0;
|
||||
}
|
||||
&::-ms-tooltip {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Focus styles
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
&::-moz-focus-outer {
|
||||
border: 0;
|
||||
}
|
||||
&.tab-focus:focus {
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
// Pressed styles
|
||||
&:active {
|
||||
&::-webkit-slider-thumb {
|
||||
@include plyr-range-thumb-active();
|
||||
}
|
||||
&::-moz-range-thumb {
|
||||
@include plyr-range-thumb-active();
|
||||
}
|
||||
&::-ms-thumb {
|
||||
@include plyr-range-thumb-active();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Video range inputs
|
||||
.plyr--video input[type='range'].tab-focus:focus {
|
||||
outline: 1px dotted transparentize($plyr-video-control-color, .5);
|
||||
}
|
||||
|
||||
// Audio range inputs
|
||||
.plyr--audio input[type='range'].tab-focus:focus {
|
||||
outline: 1px dotted transparentize($plyr-audio-control-color, .5);
|
||||
}
|
||||
|
||||
// Screen reader only elements
|
||||
.plyr__sr-only {
|
||||
position: absolute !important;
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
padding: 0 !important;
|
||||
border: 0 !important;
|
||||
height: 1px !important;
|
||||
width: 1px !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
// Video
|
||||
.plyr__video-wrapper {
|
||||
position: relative;
|
||||
background: #000;
|
||||
border-radius: inherit;
|
||||
|
||||
// Cleaner radius, also forces iframe radius
|
||||
-webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC);
|
||||
}
|
||||
|
||||
// Container for embeds
|
||||
.plyr__video-embed {
|
||||
padding-bottom: 56.25%; /* 16:9 */
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
border-radius: inherit;
|
||||
|
||||
iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
// Vimeo hack
|
||||
> div {
|
||||
position: relative;
|
||||
padding-bottom: 200%;
|
||||
transform: translateY(-35.95%);
|
||||
}
|
||||
}
|
||||
// To allow mouse events to be captured if full support
|
||||
.plyr .plyr__video-embed iframe {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
// Captions
|
||||
// --------------------------------------------------------------
|
||||
// Hide default captions
|
||||
.plyr video::-webkit-media-text-track-container {
|
||||
display: none;
|
||||
}
|
||||
.plyr__captions {
|
||||
display: none;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
padding: ($plyr-control-spacing * 2) ($plyr-control-spacing * 2) ($plyr-control-spacing * 8);
|
||||
color: #fff;
|
||||
font-size: $plyr-font-size-captions-base;
|
||||
text-align: center;
|
||||
font-weight: 400;
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
|
||||
span {
|
||||
border-radius: 2px;
|
||||
padding: floor($plyr-control-spacing / 3) $plyr-control-spacing;
|
||||
background: transparentize(#000, .15);
|
||||
}
|
||||
span:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: $plyr-bp-screen-md) {
|
||||
font-size: $plyr-font-size-captions-medium;
|
||||
}
|
||||
}
|
||||
.plyr--captions-active .plyr__captions {
|
||||
display: block;
|
||||
}
|
||||
.plyr--fullscreen-active .plyr__captions {
|
||||
font-size: $plyr-font-size-captions-large;
|
||||
}
|
||||
|
||||
// Controls
|
||||
// --------------------------------------------------------------
|
||||
// Playback controls
|
||||
.plyr__controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
|
||||
transition: opacity .3s ease;
|
||||
|
||||
// Spacing
|
||||
> button,
|
||||
.plyr__progress,
|
||||
.plyr__time {
|
||||
margin-left: ($plyr-control-spacing / 2);
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
.plyr__volume {
|
||||
margin-left: ($plyr-control-spacing / 2);
|
||||
}
|
||||
[data-plyr="pause"] {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
// Buttons
|
||||
button {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
flex-shrink: 0;
|
||||
vertical-align: middle;
|
||||
padding: ($plyr-control-spacing / 2);
|
||||
border: 0;
|
||||
background: transparent;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
transition: background .3s ease, color .3s ease, opacity .3s ease;
|
||||
color: inherit;
|
||||
|
||||
svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: block;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
// Default focus
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Hide toggle icons by default
|
||||
.icon--exit-fullscreen,
|
||||
.icon--muted,
|
||||
.icon--captions-on {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: $plyr-bp-screen-sm) {
|
||||
> button,
|
||||
.plyr__progress,
|
||||
.plyr__time {
|
||||
margin-left: $plyr-control-spacing;
|
||||
}
|
||||
button {
|
||||
padding: ($plyr-control-spacing / 2) $plyr-control-spacing;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Hide controls
|
||||
.plyr--hide-controls .plyr__controls {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
// Video controls
|
||||
.plyr--video .plyr__controls {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: ($plyr-control-spacing * 5) $plyr-control-spacing $plyr-control-spacing;
|
||||
background: linear-gradient(transparentize($plyr-video-controls-bg, 1), transparentize($plyr-video-controls-bg, .5));
|
||||
border-bottom-left-radius: inherit;
|
||||
border-bottom-right-radius: inherit;
|
||||
color: $plyr-video-control-color;
|
||||
|
||||
button {
|
||||
// Hover and tab focus
|
||||
&.tab-focus:focus,
|
||||
&:hover {
|
||||
background: $plyr-video-control-bg-hover;
|
||||
color: $plyr-video-control-color-hover;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: $plyr-bp-screen-sm) {
|
||||
padding-left: ($plyr-control-spacing * 1.5);
|
||||
padding-right: ($plyr-control-spacing * 1.5);
|
||||
}
|
||||
}
|
||||
|
||||
// Audio controls
|
||||
.plyr--audio .plyr__controls {
|
||||
padding: $plyr-control-spacing;
|
||||
border-radius: inherit;
|
||||
background: $plyr-audio-controls-bg;
|
||||
border: $plyr-audio-controls-border;
|
||||
box-shadow: $plyr-audio-controls-box-shadow;
|
||||
color: $plyr-audio-control-color;
|
||||
|
||||
button {
|
||||
// Hover and tab focus
|
||||
&.tab-focus:focus,
|
||||
&:hover {
|
||||
background: $plyr-audio-control-bg-hover;
|
||||
color: $plyr-audio-control-color-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Large play button (video only)
|
||||
.plyr__play-large {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
padding: $plyr-control-spacing;
|
||||
background: $plyr-video-control-bg-hover;
|
||||
border: 4px solid currentColor;
|
||||
border-radius: 100%;
|
||||
box-shadow: 0 1px 1px transparentize($plyr-video-controls-bg, .85);
|
||||
color: $plyr-video-control-color;
|
||||
transition: opacity .3s ease, visibility .3s ease;
|
||||
|
||||
svg {
|
||||
position: relative;
|
||||
left: 2px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: block;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 1px dotted transparentize($plyr-video-control-color, .5);
|
||||
}
|
||||
}
|
||||
.plyr--audio .plyr__play-large {
|
||||
display: none;
|
||||
}
|
||||
.plyr--playing .plyr__play-large {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
// States
|
||||
.plyr__controls [data-plyr='pause'],
|
||||
.plyr--playing .plyr__controls [data-plyr='play'] {
|
||||
display: none;
|
||||
}
|
||||
.plyr--playing .plyr__controls [data-plyr='pause'] {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
// Change icons on state change
|
||||
.plyr--fullscreen-active .icon--exit-fullscreen,
|
||||
.plyr--muted .plyr__controls .icon--muted,
|
||||
.plyr--captions-active .plyr__controls .icon--captions-on {
|
||||
display: block;
|
||||
|
||||
& + svg {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Some options are hidden by default
|
||||
.plyr [data-plyr='captions'],
|
||||
.plyr [data-plyr='fullscreen'] {
|
||||
display: none;
|
||||
}
|
||||
.plyr--captions-enabled [data-plyr='captions'],
|
||||
.plyr--fullscreen-enabled [data-plyr='fullscreen'] {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
// Tooltips
|
||||
// --------------------------------------------------------------
|
||||
.plyr__tooltip {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
bottom: 100%;
|
||||
margin-bottom: ($plyr-tooltip-padding * 2);
|
||||
padding: $plyr-tooltip-padding ($plyr-tooltip-padding * 1.5);
|
||||
pointer-events: none;
|
||||
|
||||
opacity: 0;
|
||||
background: $plyr-tooltip-bg;
|
||||
box-shadow: $plyr-tooltip-shadow;
|
||||
border-radius: $plyr-tooltip-radius;
|
||||
|
||||
color: $plyr-tooltip-color;
|
||||
font-size: $plyr-font-size-small;
|
||||
line-height: 1.3;
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
|
||||
transform: translate(-50%, 10px) scale(.8);
|
||||
transform-origin: 50% 100%;
|
||||
transition: transform .2s .1s ease, opacity .2s .1s ease, visibility .3s ease;
|
||||
|
||||
// Arrows
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
// The background triangle
|
||||
&::before {
|
||||
bottom: -$plyr-tooltip-arrow-size;
|
||||
border-right: $plyr-tooltip-arrow-size solid transparent;
|
||||
border-top: $plyr-tooltip-arrow-size solid $plyr-tooltip-bg;
|
||||
border-left: $plyr-tooltip-arrow-size solid transparent;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
.plyr button:hover .plyr__tooltip,
|
||||
.plyr button.tab-focus:focus .plyr__tooltip,
|
||||
.plyr__tooltip--visible {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transform: translate(-50%, 0) scale(1);
|
||||
}
|
||||
.plyr button:hover .plyr__tooltip {
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
// Playback progress
|
||||
// --------------------------------------------------------------
|
||||
// <progress> element
|
||||
.plyr__progress {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
|
||||
input[type="range"] {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
&::-webkit-slider-runnable-track {
|
||||
background: transparent;
|
||||
}
|
||||
&::-moz-range-track {
|
||||
background: transparent;
|
||||
}
|
||||
&::-ms-fill-upper {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
// Seek tooltip to show time
|
||||
.plyr__tooltip {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.plyr__progress--buffer[value],
|
||||
.plyr__progress--played[value],
|
||||
.plyr__volume--display[value] {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
width: 100%;
|
||||
height: $plyr-range-track-height;
|
||||
margin: -($plyr-range-track-height / 2) 0 0;
|
||||
padding: 0;
|
||||
vertical-align: top;
|
||||
appearance: none;
|
||||
border: none;
|
||||
border-radius: 100px;
|
||||
|
||||
&::-webkit-progress-bar {
|
||||
background: transparent;
|
||||
}
|
||||
&::-webkit-progress-value {
|
||||
background: currentColor;
|
||||
border-radius: 100px;
|
||||
min-width: $plyr-range-track-height;
|
||||
}
|
||||
&::-moz-progress-bar {
|
||||
background: currentColor;
|
||||
border-radius: 100px;
|
||||
min-width: $plyr-range-track-height;
|
||||
}
|
||||
&::-ms-fill {
|
||||
border-radius: 100px;
|
||||
}
|
||||
}
|
||||
.plyr__progress--played[value],
|
||||
.plyr__volume--display[value] {
|
||||
z-index: 1;
|
||||
color: $plyr-range-selected-bg;
|
||||
background: transparent;
|
||||
transition: none;
|
||||
|
||||
&::-webkit-progress-value {
|
||||
min-width: $plyr-range-track-height;
|
||||
max-width: 99%;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
&::-moz-progress-bar {
|
||||
min-width: $plyr-range-track-height;
|
||||
max-width: 99%;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
&::-ms-fill {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.plyr__progress--buffer[value] {
|
||||
&::-webkit-progress-value {
|
||||
transition: width .2s ease;
|
||||
}
|
||||
&::-moz-progress-bar {
|
||||
transition: width .2s ease;
|
||||
}
|
||||
&::-ms-fill {
|
||||
transition: width .2s ease;
|
||||
}
|
||||
}
|
||||
.plyr--video .plyr__progress--buffer[value],
|
||||
.plyr--video .plyr__volume--display[value] {
|
||||
background: $plyr-video-range-track-bg;
|
||||
}
|
||||
.plyr--video .plyr__progress--buffer[value] {
|
||||
color: $plyr-video-progress-buffered-bg;
|
||||
}
|
||||
.plyr--audio .plyr__progress--buffer[value],
|
||||
.plyr--audio .plyr__volume--display[value] {
|
||||
background: $plyr-audio-range-track-bg;
|
||||
}
|
||||
.plyr--audio .plyr__progress--buffer[value] {
|
||||
color: $plyr-audio-progress-buffered-bg;
|
||||
}
|
||||
|
||||
// Loading state
|
||||
.plyr--loading .plyr__progress--buffer {
|
||||
animation: plyr-progress 1s linear infinite;
|
||||
background-size: $plyr-progress-loading-size $plyr-progress-loading-size;
|
||||
background-repeat: repeat-x;
|
||||
background-image: linear-gradient(
|
||||
-45deg,
|
||||
$plyr-progress-loading-bg 25%,
|
||||
transparent 25%,
|
||||
transparent 50%,
|
||||
$plyr-progress-loading-bg 50%,
|
||||
$plyr-progress-loading-bg 75%,
|
||||
transparent 75%,
|
||||
transparent);
|
||||
color: transparent;
|
||||
}
|
||||
.plyr--video.plyr--loading .plyr__progress--buffer {
|
||||
background-color: $plyr-video-progress-buffered-bg;
|
||||
}
|
||||
.plyr--audio.plyr--loading .plyr__progress--buffer {
|
||||
background-color: $plyr-audio-progress-buffered-bg;
|
||||
}
|
||||
|
||||
// Time
|
||||
// --------------------------------------------------------------
|
||||
.plyr__time {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
font-size: $plyr-font-size-small;
|
||||
line-height: .95;
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
}
|
||||
// Media duration hidden on small screens
|
||||
.plyr__time + .plyr__time {
|
||||
display: none;
|
||||
|
||||
@media (min-width: $plyr-bp-screen-md) {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
// Add a slash in before
|
||||
&::before {
|
||||
content: '\2044';
|
||||
margin-right: $plyr-control-spacing;
|
||||
}
|
||||
}
|
||||
|
||||
// Volume
|
||||
// --------------------------------------------------------------
|
||||
.plyr .plyr__volume {
|
||||
display: none;
|
||||
position: relative;
|
||||
|
||||
input[type="range"] {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
@media (min-width: $plyr-bp-screen-sm) {
|
||||
display: block;
|
||||
max-width: 60px;
|
||||
}
|
||||
@media (min-width: $plyr-bp-screen-md) {
|
||||
max-width: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
// Hide sound controls on iOS
|
||||
// It's not supported to change volume using JavaScript:
|
||||
// https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html
|
||||
.plyr--is-ios .plyr__volume,
|
||||
.plyr--is-ios [data-plyr='mute'] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
// Fullscreen
|
||||
// --------------------------------------------------------------
|
||||
.plyr--fullscreen,
|
||||
.plyr--fullscreen-active {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 10000000;
|
||||
background: #000;
|
||||
border-radius: 0;
|
||||
|
||||
video {
|
||||
height: 100%;
|
||||
}
|
||||
.plyr__video-wrapper {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
.plyr__controls {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
67
src/scss/variables.scss
Normal file
@ -0,0 +1,67 @@
|
||||
// ==========================================================================
|
||||
// Plyr variables
|
||||
// https://github.com/selz/plyr
|
||||
// https://robots.thoughtbot.com/sass-default
|
||||
// ==========================================================================
|
||||
|
||||
// Colors
|
||||
$plyr-color-main: #3498db !default;
|
||||
|
||||
// Font sizes
|
||||
$plyr-font-size-small: 14px !default;
|
||||
$plyr-font-size-base: 16px !default;
|
||||
|
||||
// Captions
|
||||
$plyr-font-size-captions-base: ceil($plyr-font-size-base * 1.25) !default;
|
||||
$plyr-font-size-captions-medium: ceil($plyr-font-size-base * 1.5) !default;
|
||||
$plyr-font-size-captions-large: ($plyr-font-size-base * 2) !default;
|
||||
|
||||
// Controls
|
||||
$plyr-control-spacing: 10px !default;
|
||||
$plyr-video-controls-bg: #000 !default;
|
||||
$plyr-video-control-color: #fff !default;
|
||||
$plyr-video-control-color-hover: #fff !default;
|
||||
$plyr-video-control-bg-hover: $plyr-color-main !default;
|
||||
$plyr-audio-controls-bg: #fff !default;
|
||||
$plyr-audio-controls-border: 1px solid #dbe3e8 !default;
|
||||
$plyr-audio-controls-box-shadow: 0 1px 1px transparentize(#000, .95) !default;
|
||||
$plyr-audio-control-color: #565D64 !default;
|
||||
$plyr-audio-control-color-hover: #fff !default;
|
||||
$plyr-audio-control-bg-hover: $plyr-color-main;
|
||||
|
||||
// Tooltips
|
||||
$plyr-tooltip-bg: $plyr-video-controls-bg !default;
|
||||
$plyr-tooltip-border-color: transparentize(darken($plyr-video-controls-bg, 75%), .9) !default;
|
||||
$plyr-tooltip-arrow-border-color: transparentize(darken($plyr-video-controls-bg, 75%), .8) !default;
|
||||
$plyr-tooltip-border-width: 1px !default;
|
||||
$plyr-tooltip-shadow: 0 0 5px $plyr-tooltip-border-color, 0 0 0 $plyr-tooltip-border-width $plyr-tooltip-border-color !default;
|
||||
$plyr-tooltip-color: $plyr-video-control-color !default;
|
||||
$plyr-tooltip-padding: ($plyr-control-spacing / 2) !default;
|
||||
$plyr-tooltip-arrow-size: 4px !default;
|
||||
$plyr-tooltip-radius: 3px !default;
|
||||
|
||||
// Progress
|
||||
$plyr-progress-loading-size: 25px !default;
|
||||
$plyr-progress-loading-bg: transparentize(#000, .85) !default;
|
||||
$plyr-video-progress-bg: transparentize(#fff, .75) !default;
|
||||
$plyr-video-progress-buffered-bg: $plyr-video-progress-bg !default;
|
||||
$plyr-audio-progress-bg: transparentize(#C6D6DB, .33) !default;
|
||||
$plyr-audio-progress-buffered-bg: $plyr-audio-progress-bg !default;
|
||||
|
||||
// Range sliders
|
||||
$plyr-range-track-height: 8px !default;
|
||||
$plyr-range-thumb-height: floor($plyr-range-track-height * 2) !default;
|
||||
$plyr-range-thumb-width: floor($plyr-range-track-height * 2) !default;
|
||||
$plyr-range-thumb-bg: #fff !default;
|
||||
$plyr-range-thumb-border: 2px solid transparent !default;
|
||||
$plyr-range-thumb-shadow: 0 1px 1px transparentize($plyr-video-controls-bg, .85), 0 0 0 1px transparentize(#000, .85) !default;
|
||||
$plyr-range-thumb-active-border-color: #fff !default;
|
||||
$plyr-range-thumb-active-bg: $plyr-video-control-bg-hover !default;
|
||||
$plyr-range-thumb-active-scale: 1.25 !default;
|
||||
$plyr-video-range-track-bg: $plyr-video-progress-buffered-bg !default;
|
||||
$plyr-audio-range-track-bg: $plyr-audio-progress-buffered-bg !default;
|
||||
$plyr-range-selected-bg: $plyr-color-main !default;
|
||||
|
||||
// Breakpoints
|
||||
$plyr-bp-screen-sm: 480px !default;
|
||||
$plyr-bp-screen-md: 768px !default;
|
11
src/sprite/icon-fast-forward.svg
Executable file → Normal file
@ -1,4 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<path d="M17.569 8.246l-10.569-6.246c-0.552 0-1 0.448-1 1v1.954l-5-2.954c-0.552 0-1 0.448-1 1v12c0 0.552 0.448 1 1 1l5-2.955v1.955c0 0.552 0.448 1 1 1l10.569-6.246c0.267-0.158 0.431-0.444 0.431-0.754s-0.164-0.597-0.431-0.754zM6 10.722l-4 2.364v-8.172l4 2.364v3.444zM8 13.086v-8.172l6.915 4.086-6.915 4.086z"></path>
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<polygon points="7,6.4 0,1 0,15 7,9.6 7,15 16,8 7,1 "/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 481 B After Width: | Height: | Size: 534 B |
@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g transform="translate(2.000000, 2.000000)">
|
||||
<path d="M0,2 L0,12 C5.24848613e-17,14 2,14 2,14 L4,14 C4,14 6,14 6,12 C6,11.786438 6,11.572876 6,11 L6,2 C6,3.17446247e-09 4,0 4,0 L2,0 C2,0 0,0 0,2 Z M2,2 L4,2 L4,12 L2,12 L2,2 Z"></path>
|
||||
<path d="M8,2 L8,12 C8,14 10,14 10,14 L12,14 C12,14 14,14 14,12 C14,11.786438 14,11.572876 14,11 L14,2 C14,3.17446247e-09 12,0 12,0 L10,0 C10,0 8,0 8,2 Z M10,2 L12,2 L12,12 L10,12 L10,2 Z"></path>
|
||||
</g>
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<path d="M5,1H2C1.4,1,1,1.4,1,2v12c0,0.6,0.4,1,1,1h3c0.6,0,1-0.4,1-1V2C6,1.4,5.6,1,5,1z"/>
|
||||
<path d="M14,1h-3c-0.6,0-1,0.4-1,1v12c0,0.6,0.4,1,1,1h3c0.6,0,1-0.4,1-1V2C15,1.4,14.6,1,14,1z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 642 B After Width: | Height: | Size: 667 B |
11
src/sprite/icon-play.svg
Executable file → Normal file
@ -1,4 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<path d="M5 4.914l6.915 4.086-6.915 4.086v-8.172zM4 2c-0.552 0-1 0.448-1 1v12c0 0.552 0.448 1 1 1l10.569-6.246c0.267-0.158 0.431-0.444 0.431-0.754s-0.164-0.597-0.431-0.754l-10.569-6.246z"></path>
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<path d="M13.6,7.2l-10-7C2.9-0.3,2,0.2,2,1v14c0,0.8,0.9,1.3,1.6,0.8l10-7C14.1,8.4,14.1,7.6,13.6,7.2z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 361 B After Width: | Height: | Size: 582 B |
@ -1,4 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg viewBox="0 0 18 21" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<path d="M17.569,9.246 L7,3 C6.448,3 6,3.448 6,4 L6,5.954 L1,3 C0.448,3 0,3.448 0,4 L0,16 C0,16.552 0.448,17 1,17 L6,14.045 L6,16 C6,16.552 6.448,17 7,17 L17.569,10.754 C17.836,10.596 18,10.31 18,10 C18,9.69 17.836,9.403 17.569,9.246 L17.569,9.246 Z M6,11.722 L2,14.086 L2,5.914 L6,8.278 L6,11.722 L6,11.722 Z M8,14.086 L8,5.914 L14.915,10 L8,14.086 L8,14.086 Z" transform="translate(9.000000, 10.000000) rotate(-180.000000) translate(-9.000000, -10.000000) "></path>
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<polygon points="9,1 0,8 9,15 9,9.6 16,15 16,1 9,6.4 "/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 704 B After Width: | Height: | Size: 535 B |