JSFiddle - React, Tailwind, and code Playground

by Joby Rudolph

HTML

<script src="http://popcornjs.org/code/dist/popcorn-complete.min.js"></script>
<div class="content">
    <p>&nbsp;</p>
    <div id="wrapper">
        <video height="360" width="600" id="notes_video" controls>
            <source src="http://videos.mozilla.org/serv/webmademovies/popcornplug.mp4" />
            <source src="http://videos.mozilla.org/serv/webmademovies/popcornplug.ogv" />
            <source src="http://videos.mozilla.org/serv/webmademovies/popcornplug.webm" />
        </video>
        <div id="notes">
            <div class="prototype">
                 <h4 class="title"></h4>
                 <p class="text"></p>
            </div>
        </div>
    </div>
</div>

CSS

body {
    text-align:center;
    font-family:Helvetica, Arial
}
.prototype {
    display:none;
}
#wrapper {
    position:relative;
}
#notes {
    position:absolute;
    top: 0;
    left: 50%;
    width: 600px;
    height: 360px;
    margin-left:-300px;
    pointer-events: none;
}
#notes > * {
    display:none;
    position:absolute;
    color:#dedede;
    padding:5px;
}
.title {
    margin:0 auto;
    color:#efefef;
    font-weight:normal;
}
.text {
    font-size:smaller;
}

/* Text Bubble CSS - Thanks Bubbler! */
/* http://www.ilikepixels.co.uk/drop/bubbler/ */
 .bubble, .bubble-bottom, .bubble-top, .bubble-left, .bubble-right {
    background:#075698;
    /* default background for browsers without gradient support */
    /* css3 */
    background:-webkit-gradient(linear, 0 0, 0 100%, from(#2e88c4), to(#075698));
    background:-moz-linear-gradient(#2e88c4, #075698);
    background:-o-linear-gradient(#2e88c4, #075698);
    background:linear-gradient(#2e88c4, #075698);
}
.bubble {
    position: relative;
    width: 250px;
    height: 120px;
    padding: 0px;
    -webkit-border-radius: 11px;
    -moz-border-radius: 11px;
    border-radius: 11px;
}
.bubble-bottom {
    position: relative;
    width: 250px;
    height: 120px;
    padding: 0px;
    -webkit-border-radius: 11px;
    -moz-border-radius: 11px;
    border-radius: 11px;
}
.bubble-bottom:after {
    content:'';
    position: absolute;
    border-style: solid;
    border-width: 15px 15px 0;
    border-color: #075698 transparent;
    display: block;
    width: 0;
    z-index: 1;
    margin-left: -15px;
    bottom: -15px;
    left: 50%;
}
.bubble-top {
    position: relative;
    width: 250px;
    height: 120px;
    padding: 0px;
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
    border-radius: 10px;
}
.bubble-top:after {
    content:'';
    position: absolute;
    border-style: solid;
    border-width: 0 15px 15px;
    border-color: #075698 transparent;
    display: block;
    width: 0;
   ...

JavaScript

data = [{
    title: "Annotation Demo",
    text: "A Data Driven Video Annotation Demo",
    start: 0,
    end: 1.5,
    position: { top: '35%', left: '20%' },
    size: { w: '60%', h: '30%' },
    class: 'bubble'
}, {
    title: "THE LOGO!",
    text: "Logo Happens Here",
    start: 4,
    end: 6,
    position: { top: '0', left: '25%' },
    size: { w: '50%', h: '20%' },
    class: 'bubble-bottom'
}, {
    title: "THE POP!",
    text: "Pop happens there",
    start: 1.9,
    end: 3.5,
    position: { top: '55%', left: '85%' },
    size: { w: '40%', h: '25%' },
    class: 'bubble'
}];

var pop = Popcorn("#notes_video");

for (var i in data) {
    var noteData = data[i];
    var noteDiv = $('#notes .prototype').clone().removeClass('prototype');

    noteDiv.find('.title').text(noteData.title).parent()
        .find('.text').text(noteData.text).parent()
        .attr("data-note-id", i)
        .css({
            'top': noteData.position.top,
            'left': noteData.position.left
        })
        .width(noteData.size.w)
        .height(noteData.size.h)
        .addClass(noteData.class)
        .appendTo($('#notes'));

    pop.code({
        start: noteData.start,
        end: noteData.end,
        onStart: function (options) {
            options.target.show();
        },
        onEnd: function (options) {
            options.target.hide();
        },
        target: noteDiv
    });
}

pop.play();