Commit 06b9fc99 authored by Vadim Makeev's avatar Vadim Makeev

Merge commit 'f505ffab' into gh-pages

parents d509d156 f505ffab
......@@ -34,6 +34,8 @@ Please address bugs and your suggestions to [Issues](http://github.com/pepelsbey
* [Sense Coding](http://pepelsbey.net/pres/sense-coding/)
* [Special Effects Tea](http://pepelsbey.net/pres/special-effects-tea/)
* [Web In Curves](http://pepelsbey.net/pres/web-in-curves/)
* [Play Framework](http://spinscale.github.com/play-advanced-concepts.html)
* [Flash -> HTML5](http://batsuev.com/bif2011/)
Licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License), see [license page](https://github.com/pepelsbey/shower/wiki/License) for details.
......@@ -73,5 +75,7 @@ Licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License), see [lic
* [Вёрстка со смыслом](http://pepelsbey.net/pres/sense-coding/)
* [Чай со спецэффектами](http://pepelsbey.net/pres/special-effects-tea/)
* [Веб в кривых](http://pepelsbey.net/pres/web-in-curves/)
* [Play Framework](http://spinscale.github.com/play-advanced-concepts.html)
* [Flash -> HTML5](http://batsuev.com/bif2011/)
Лицензировано под [лицензией MIT](http://en.wikipedia.org/wiki/MIT_License), читайте подробнее [на странице лицензии](https://github.com/pepelsbey/shower/wiki/License).
\ No newline at end of file
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<title>Shower</title>
<title>Shower Presentation Template</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=1274, user-scalable=no">
<link rel="stylesheet" href="themes/ribbon/styles/style.css">
......@@ -87,7 +87,7 @@
<header>
<h2>In the Middle</h2>
</header>
<object data="pictures/semantics.svg" type="image/svg+xml" width="300" height="300" class="middle"></object>
<object data="pictures/shower.svg" type="image/svg+xml" width="256" height="256" class="middle"></object>
</section>
</div></div>
<div class="slide bg" id="Picture"><div>
......@@ -154,38 +154,6 @@
</blockquote>
</section>
</div></div>
<!--
This feature is under development!
Add class “inner” to any parent element
to start inner navigation section. Pressing
next button will add class “active” to every
next sibling child starting from the first one.
Actual behavior depends on styles of the current
theme: on active state you could show previously
hidden items or emphasize it for example by
color or bold font weight.
To start slide with the first active alement
add class “active” manually.
After activation of the last child pressing next
button will turn next slide.
<div class="slide" id="InnerNavigation"><div>
<section>
<header>
<h2>Inner Navigation</h2>
</header>
<ol class="inner">
<li class="active">This tool is provided</li>
<li>Without warranty, guarantee</li>
<li>Or much in the way of explanation
<li>Erase your hard drive.</li>
</ol>
</section>
</div></div> -->
<div class="slide" id="ThankYou"><div>
<section>
<header>
......
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 256.155 256.155">
<title>HTML5 Semantics Logo</title>
<polygon id="chevron" fill="#0174A7" points="128.106,0 0,64.744 0,107.32 128.106,42.577 256.155,107.32 256.155,64.744"/>
<use xlink:href="#chevron" y="74.316" />
<use xlink:href="#chevron" y="148.653" />
</svg>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="256px" height="256px" viewBox="0 0 512 512">
<path fill="#0174A7" d="M315,259l18-18l179,179v-36L351,223l18-18l143,143v-36L387,187l18-18l107,107V51.2 C512,22.923,489.077,0,460.8,0H51.2C22.923,0,0,22.923,0,51.2v409.6C0,489.077,22.923,512,51.2,512h190.501 c16.542-24.877,13.794-58.989-8.217-81l-62.994-62.994l-62.994-62.994c-55.187-55.186-55.349-144.499-0.362-199.484 c54.985-54.986,144.297-54.824,199.482,0.362l8.689,7.111h108.612L261,275.918V168.884l-8.689-8.688 c-25.084-25.084-65.682-25.158-90.674-0.165c-24.993,24.993-24.92,65.589,0.165,90.675l62.993,62.994l62.996,62.993 c36.674,36.676,49.037,88.58,37.073,135.307H460.8c28.277,0,51.2-22.923,51.2-51.2V456L315,259z"/>
</svg>
\ No newline at end of file
<!DOCTYPE HTML>
<html lang="ru-RU">
<head>
<title>Shower</title>
<title>Шаблон презентаций Shower</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=1274, user-scalable=no">
<link rel="stylesheet" href="themes/ribbon/styles/style.css">
......@@ -15,7 +15,7 @@
</head>
<body class="list">
<header class="caption">
<h1>Шаблон презентации Shower</h1>
<h1>Шаблон презентаций Shower</h1>
<p>Вадим Макеев, Opera Software</p>
</header>
<div class="slide bg" id="Cover"><div>
......@@ -87,7 +87,7 @@
<header>
<h2>Посередине</h2>
</header>
<object data="pictures/semantics.svg" type="image/svg+xml" width="300" height="300" class="middle"></object>
<object data="pictures/shower.svg" type="image/svg+xml" width="256" height="256" class="middle"></object>
</section>
</div></div>
<div class="slide bg" id="Picture"><div>
......@@ -154,44 +154,10 @@
</blockquote>
</section>
</div></div>
<!--
Эта возможность находится в разработке!
Добавьте класс «inner» к любому родительскому
элементу для того, чтобы обозначить блок
внутренней навигации. Нажатие кнопки «следующий»
добавит класс «active» каждому последующему
ребёнку, начиная с первого.
Конкретное поведение зависит от стилей
текущей темы: элемент в активном состоянии
может быть показан, будучи предварительно спрятан,
либо вы можете выделить его, к примеру, цветом
или полужирным начертанием.
Для того, чтобы начать слайд с первого активного
элемента, добавьте класс «active» вручную.
После активации последнего элемента, нажатие
кнопки «следующий» переключит следующий слайд.
<div class="slide" id="InnerNavigation"><div>
<section>
<header>
<h2>Внутренняя навигация</h2>
</header>
<ol class="inner">
<li class="active">This tool is provided</li>
<li>Without warranty, guarantee</li>
<li>Or much in the way of explanation
<li>Erase your hard drive.</li>
</ol>
</section>
</div></div> -->
<div class="slide" id="ThankYou"><div>
<section>
<header>
<h2>Шаблон презентации Shower</h2>
<h2>Шаблон презентаций Shower</h2>
</header>
<p>Вадим Макеев, Opera Software</p>
<ul>
......
......@@ -4,11 +4,13 @@
slides = document.querySelectorAll('div.slide'),
progress = document.querySelector('div.progress div'),
slideList = [],
l = slides.length,
i;
l = slides.length, i;
for (i = 0; i < l; i++) {
slideList.push(slides[i].id);
slideList.push({
id: slides[i].id,
hasInnerNavigation: null !== slides[i].querySelector('.inner')
});
}
function getTransform() {
......@@ -21,126 +23,175 @@
}
function applyTransform(transform) {
body.style.MozTransform = transform;
body.style.WebkitTransform = transform;
body.style.OTransform = transform;
body.style.MozTransform = transform;
body.style.msTransform = transform;
body.style.OTransform = transform;
body.style.transform = transform;
}
function enterSingleSlideMode() {
function enterSlideMode() {
body.className = 'full';
applyTransform(getTransform());
}
function enterSlideListMode() {
function enterListMode() {
body.className = 'list';
applyTransform('none');
}
function getCurrentSlideNumber() {
return slideList.indexOf(url.hash.substr(1));
var i, l = slideList.length,
currentSlideId = url.hash.substr(1);
for (i = 0; i < l; ++i) {
if (currentSlideId === slideList[i].id) {
return i;
}
}
return -1;
}
function scrollToCurrentSlide() {
var current_slide = document.getElementById(slideList[getCurrentSlideNumber()]);
var currentSlide = document.getElementById(
slideList[getCurrentSlideNumber()].id
);
if (null != current_slide) {
window.scrollTo(0, current_slide.offsetTop);
if (null != currentSlide) {
window.scrollTo(0, currentSlide.offsetTop);
}
}
function isSlideListMode() {
function isListMode() {
return 'full' !== url.search.substr(1);
}
function normalizeSlideNumber(slide_number) {
if (0 > slide_number) {
function normalizeSlideNumber(slideNumber) {
if (0 > slideNumber) {
return slideList.length - 1;
} else if (slideList.length <= slide_number) {
} else if (slideList.length <= slideNumber) {
return 0;
} else {
return slide_number;
return slideNumber;
}
}
function updateProgress(slideNumber) {
if (null === progress) { return; }
progress.style.width = (100 / (slideList.length - 1) * normalizeSlideNumber(slideNumber)).toFixed(2) + '%';
}
function getSlideHash(slideNumber) {
return '#' + slideList[normalizeSlideNumber(slideNumber)].id;
}
function goToSlide(slideNumber) {
url.hash = getSlideHash(slideNumber);
if (!isListMode()) {
updateProgress(slideNumber);
}
}
function getContainingSlideId(el) {
var node = el;
while ('BODY' !== node.nodeName && 'HTML' !== node.nodeName) {
if (-1 !== node.className.indexOf('slide')) {
return node.id;
} else {
node = node.parentNode;
}
}
function updateProgress(slide_number) {
if (!progress) return;
progress.style.width = (100 / (slideList.length - 1) * normalizeSlideNumber(slide_number)).toFixed(2) + '%';
return '';
}
function getSlideHashByNumber(slide_number) {
return '#' + slideList[normalizeSlideNumber(slide_number)];
function dispatchSingleSlideMode(e) {
var slideId = getContainingSlideId(e.target);
if ('' !== slideId && isListMode()) {
e.preventDefault();
// NOTE: we should update hash to get things work properly
url.hash = '#' + slideId;
history.replaceState(null, null, url.pathname + '?full#' + slideId);
enterSlideMode();
updateProgress(getCurrentSlideNumber());
}
}
function goToSlide(slide_number) {
url.hash = getSlideHashByNumber(slide_number);
// Increases inner navigation by adding 'active' class to next inactive inner navigation item
function increaseInnerNavigation(slideNumber) {
// Shortcut for slides without inner navigation
if (true !== slideList[slideNumber].hasInnerNavigation) { return -1; }
if (!isSlideListMode()) {
updateProgress(slide_number);
var activeNodes = document.querySelectorAll(getSlideHash(slideNumber) + ' .active'),
// NOTE: we assume there is no other elements in inner navigation
node = activeNodes[activeNodes.length - 1].nextElementSibling;
if (null !== node) {
node.classList.add('active');
return activeNodes.length + 1;
} else {
return -1;
}
}
// Event handlers
window.addEventListener('DOMContentLoaded', function () {
if (!isSlideListMode()) {
// "?full" is present without slide hash so we should display first
// slide
if ( -1 === getCurrentSlideNumber() ) {
history.replaceState(null, null, url.pathname + '?full' + getSlideHashByNumber( 0 ) );
if (!isListMode()) {
// "?full" is present without slide hash, so we should display first slide
if (-1 === getCurrentSlideNumber()) {
history.replaceState(null, null, url.pathname + '?full' + getSlideHash(0));
}
enterSingleSlideMode();
enterSlideMode();
updateProgress(getCurrentSlideNumber());
}
}, false);
window.addEventListener('popstate', function (e) {
if (isSlideListMode()) {
enterSlideListMode();
if (isListMode()) {
enterListMode();
scrollToCurrentSlide();
} else {
enterSingleSlideMode();
enterSlideMode();
}
}, false);
window.addEventListener('resize', function (e) {
if (!isSlideListMode()) {
if (!isListMode()) {
applyTransform(getTransform());
}
}, false);
document.addEventListener('keydown', function (e) {
if (e.altKey || e.ctrlKey || e.metaKey) return;
// Shortcut for alt, shift and meta keys
if (e.altKey || e.ctrlKey || e.metaKey) { return; }
var current_slide_number = getCurrentSlideNumber();
var currentSlideNumber = getCurrentSlideNumber();
switch (e.which) {
case 9: // Tab = +1; Shift + Tab = -1
if (isSlideListMode()) {
e.preventDefault();
current_slide_number += e.shiftKey ? -1 : 1;
url.hash = getSlideHashByNumber(current_slide_number);
}
break;
case 13: // Enter
if (isSlideListMode()) {
if (isListMode()) {
e.preventDefault();
history.pushState(null, null, url.pathname + '?full' + getSlideHashByNumber(current_slide_number));
enterSingleSlideMode();
history.pushState(null, null, url.pathname + '?full' + getSlideHash(currentSlideNumber));
enterSlideMode();
updateProgress(current_slide_number);
updateProgress(currentSlideNumber);
}
break;
case 27: // Esc
if (!isSlideListMode()) {
if (!isListMode()) {
e.preventDefault();
history.pushState(null, null, url.pathname + getSlideHashByNumber(current_slide_number));
enterSlideListMode();
history.pushState(null, null, url.pathname + getSlideHash(currentSlideNumber));
enterListMode();
scrollToCurrentSlide();
}
break;
......@@ -152,8 +203,8 @@
case 75: // k
e.preventDefault();
current_slide_number--;
goToSlide(current_slide_number);
currentSlideNumber--;
goToSlide(currentSlideNumber);
break;
case 34: // PgDown
......@@ -163,29 +214,37 @@
case 74: // j
e.preventDefault();
current_slide_number++;
goToSlide(current_slide_number);
// Only go to next slide if current slide have no inner
// navigation or inner navigation is fully shown
if (
!slideList[currentSlideNumber].hasInnerNavigation ||
-1 === increaseInnerNavigation(currentSlideNumber)
) {
currentSlideNumber++;
goToSlide(currentSlideNumber);
}
break;
case 36: // Home
e.preventDefault();
current_slide_number = 0;
goToSlide(current_slide_number);
currentSlideNumber = 0;
goToSlide(currentSlideNumber);
break;
case 35: // End
e.preventDefault();
current_slide_number = slideList.length - 1;
goToSlide(current_slide_number);
currentSlideNumber = slideList.length - 1;
goToSlide(currentSlideNumber);
break;
case 9: // Tab = +1; Shift + Tab = -1
case 32: // Space = +1; Shift + Space = -1
e.preventDefault();
current_slide_number += e.shiftKey ? -1 : 1;
goToSlide(current_slide_number);
currentSlideNumber += e.shiftKey ? -1 : 1;
goToSlide(currentSlideNumber);
break;
default:
......@@ -193,20 +252,26 @@
}
}, false);
document.addEventListener('click', function (e) {
if (
'SECTION' === e.target.nodeName &&
-1 !== e.target.parentNode.parentNode.className.indexOf('slide') &&
isSlideListMode()
) {
e.preventDefault();
document.addEventListener('click', dispatchSingleSlideMode, false);
document.addEventListener('touchend', dispatchSingleSlideMode, false);
// NOTE: we should update hash to get things work properly
url.hash = '#' + e.target.parentNode.parentNode.id;
history.replaceState(null, null, url.pathname + '?full#' + e.target.parentNode.parentNode.id);
enterSingleSlideMode();
document.addEventListener('touchstart', function (e) {
if (!isListMode()) {
var currentSlideNumber = getCurrentSlideNumber(),
x = e.touches[0].pageX;
if (x > window.innerWidth / 2) {
currentSlideNumber++;
} else {
currentSlideNumber--;
}
updateProgress(getCurrentSlideNumber());
goToSlide(currentSlideNumber);
}
}, false);
document.addEventListener('touchmove', function (e) {
if (!isListMode()) {
e.preventDefault();
}
}, false);
......
/*
Ribbon theme for Shower presentation template: http://github.com/pepelsbey/shower
Copyright © 2010–2011 Vadim Makeev, http://pepelsbey.net/
Licensed under MIT license: https://github.com/pepelsbey/shower/wiki/License
*/
@page {
margin:0;
size:1024px 640px;
}
/* List
---------------------------------------- */
.list {
float:none;
padding:0;
background:#888;
}
/* Caption */
.list .caption {
display:none;
}
/* Slide */
.list .slide {
float:none;
margin:0;
padding:0;
}
.list .slide > DIV {
width:1024px;
height:640px;
background:none;
}
.list .slide > DIV,
.list .slide > DIV:hover {
-webkit-box-shadow:none;
-moz-box-shadow:none;
box-shadow:none;
}
.list .slide SECTION {
-webkit-transform:none;
-moz-transform:none;
-ms-transform:none;
-o-transform:none;
transform:none;
}
.list .slide:after {
position:absolute;
bottom:85px;
left:120px;
color:#BBB;
line-height:1;
text-shadow:none;
}
\ No newline at end of file
......@@ -240,6 +240,14 @@ BODY {
.list .caption H1 {
font:bold 50px/1 'PT Sans Narrow', sans-serif;
}
.list .caption A {
color:#4B86C2;
text-shadow:0 -1px 1px #1F3F60;
text-decoration:none;
}
.list .caption A:hover {
color:#5ca4ed;
}
/* Slide */
.list .slide {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment