Published
Edited
Oct 25, 2018
Importers
12 stars
Insert cell
Insert cell
pitch.fade`# Pitch!
Slideshows in observable.

<small><small>click me, then click or page down</small></small>`
Insert cell
first = pitch.fade.js`
// Import the pitch function and styles:
import {pitch} from "@enkimute/pitch"

// Load the styles:
pitch.styles

// Create a slide:
pitch\`Hello, *world*!\`
`
Insert cell
pitch.inplace(first).fade.js`//specify transitions
pitch.fade\`this slide will fade\`
`
Insert cell
pitch.inplace(first).fade.blur.code`pitch.blur\`this slide will blur\``

Insert cell
second = pitch.fade.left.js`
// There are a bunch of transitions available :
pitch.left\`move from left\`
pitch.right\`move from right\`
pitch.blur\`blur\`
pitch.fade\`fade\`
pitch.sepia\`sepia\`
`
Insert cell
pitch.inplace(second).fade.right.js`
// And a few slide output styles :
pitch\`plain markdown\`
pitch(HTML_element)
pitch.full\`no borders\`
pitch.full(HTML_element)
pitch.code\`code\`
pitch.js\`javascript code\`
pitch.img\`http://image_url.jpg\`
`
Insert cell
pitch.inplace(second).fade.left.blur.sepia.js`
// All styles can be combined ..
pitch.fade.left.blur.sepia.js\`combined!\`
`
Insert cell
pitch.inplace(second).right.fade.js`
// And they can be stacked ..

// Store a reference to a slide.
first = pitch.fade\`first slide\`;

// To append more slides to it.
pitch.inplace(first).fade\`second slide\`
`
Insert cell
pitch.inplace(second).auto(3).fade.js`// They can be automatically timed ..
pitch.auto(3)\`next after 3 seconds.\``
Insert cell
pitch.inplace(second).speak('and they can talk ..').fade.js`// and they can talk ..
pitch.speak('and they can talk ..')\`..really..\``
Insert cell
imgslide = pitch.fade.sepia.img`https://gist.githubusercontent.com/mbostock/9511ae067889eefa5537eedcbbf87dab/raw/944b6e5fe8dd535d6381b93d88bf4a854dac53d4/mona-lisa.jpg`
Insert cell
pitch.fade.full(Algebra(3,0,1,()=>{
var n = 360, s = 60;
var roots = [...Array(n)].map((x,k)=>1e123 + Math.cos(2*Math.PI*k/n)*2e012 + Math.sin(2*Math.PI*k/n)*2e013)
return this.graph(()=>{
s=s+0.005;
var lines = [...Array(n)].map((x,k)=>[roots[k],roots[Math.floor((k*s)%n)]]);
lines.unshift("s = "+s.toFixed(2),0x888888)
return lines
},{width:800,height:600, gl:1, animate:true})
}))
Insert cell
Insert cell
pitch`
Pitch!
* supports full-screen

* has keyboard (pgup/pgdn/home)

* is reactive (${new Date(now).toLocaleString().split(' ')[1]})
`
Insert cell
pitch.styles
Insert cell
Insert cell
pitch = {
// Current collection of transitions and classes, current slide
var transition = "", extra="", curslide = -1, parent=undefined, timer=undefined, autonext=0, speak='';
// String template (or html element). Calls through to Markdown.
var pitch = function(a,...r) {
const div = Object.assign(html`<div>`,{className:'slide '+extra,transition,extra,autonext,speak});
div.appendChild(a instanceof Array?md.apply(this, arguments):a); speak=transition=extra=""; autonext=0; div._parent = parent; parent=undefined;
var container = (this instanceof HTMLElement)?this:Object.assign(html`<DIV></DIV>`,{position:'relative',className:'_slide',onclick:()=>pitch.present(++curslide)}); while(container.firstChild) container.removeChild(container.firstChild); container.appendChild(div); container._div = div;
return container;
};
// Some convenience markdown wrappers, and a borderless mode.
pitch.img = function(a,...r){extra='img'; return pitch.apply(this,[Object.assign(new Image(),{src:a})]);}
pitch.js = function(a,...r){extra='code'; return pitch.apply(this,[["```javasript\n",...a,"\n```"],"",...r,""]);}
pitch.code = function(a,...r){extra='code'; return pitch.apply(this,[["```\n",...a,"\n```"],"",...r,""]);}
pitch.full = function(){extra='full'; return pitch.apply(this,arguments); };
pitch.inplace = function(x){ parent=x; return pitch; };
pitch.auto = function(x){ autonext=x*1000; return pitch; };
pitch.speak = function(x){ speak=x; return pitch; };
// Chainable effects.
["fade","left","right","blur","sepia"].forEach(x=>pitch.__defineGetter__(x,()=>{transition+=x+" "; return pitch; }));
// Shows the requested slide.
pitch.present = (x,fast)=>{
if (timer) clearTimeout(timer);
var els = [...document.querySelectorAll("._slide")].map(x=>x._div), el = els[x%els.length]; if (!el) return;
els.forEach(x=>{if(x._parent && x.parentElement != x._parent) { x._parent.insertBefore(x,x._parent.firstChild); x.style.position="absolute"; x.style.top="0px"; x.style.left="0px"; x.style.zIndex=-10;}});
el.scrollIntoView({block:'start',behavior:fast?'instant':'smooth'}); el.parentElement.scrollLeft=0;
[...els].forEach(e=>e.className=(e==el)?'slide '+e.extra:('slide '+e.extra+' '+e.transition));
if (el.autonext) timer = setTimeout(()=>{ pitch.present(++curslide); },el.autonext);
if (el.speak) speechSynthesis.speak(Object.assign(new SpeechSynthesisUtterance(el.speak),{lang:'en-US'}));
}
// Keyboard handler.
window.onkeydown = (e)=>{
if (e.keyCode==36) { curslide=0; e.preventDefault(); pitch.present(curslide,true); }
if (~[33,34].indexOf(e.keyCode)) { curslide+=2*(e.keyCode-33.5); e.preventDefault(); pitch.present(curslide) }
}
// CSS styles
pitch.styles = html`
<style>
.slide { width: calc(100% + 28px); margin: 0 -14px; padding: 10%;
background: #333; color: #eee; min-height: 65vw; font-size: 5vw; overflow:hidden;
line-height: 1.15; display: flex; align-items: center; box-sizing:border-box;
transition: opacity 1s ease-in-out, margin 1s ease-in-out, padding 1s ease-in-out, filter 1.5s ease-in-out;
}
.slide.fade { opacity: 0; }
.slide.left { margin-left: calc(-100% - 42px); }
.slide.right { padding-left: calc(100% + 42px); overflow:hidden; }
.slide.blur { filter: blur(20px); }
.slide.sepia { filter: sepia(100%); }
.slide.blur.sepia { filter: blur(20px) sepia(100%);}
.slide h1, .slide h2, .slide h3 { color:#eee }
.slide p, .slide pre, .slide img { max-width: 100%; }
.slide blockquote, .slide ol, .slide ul { max-width: none; }
.slide code { font-size: 3vw; }
.slide.code { background: #eee; color: #444; padding-top:0; }
.slide.img { max-height:80vw; overflow:hidden; }
.slide.full { padding:0; background:transparent; }
_slide { overflow:hidden; position:relative; min-height: 65vw; }
</style>`;
return pitch;
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more