Instantly share code, notes, and snippets.
Created
September 30, 2015 19:50
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save maxxcrawford/2ae447829d174ef959b8 to your computer and use it in GitHub Desktop.
Morph Button
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>Video Player</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<style type="text/css"> | |
*, *:before, *:after { | |
box-sizing: border-box; | |
} | |
html, body { | |
height: 100%; | |
} | |
body { | |
margin: 0; | |
} | |
section { | |
height: 300px; | |
text-align: center; | |
line-height: 300px; | |
background: #eee; | |
outline: 1px solid #e0e0e0; | |
} | |
section button { | |
display: inline-block; | |
font: normal 18px "adobe-caslon-pro-n4","adobe-caslon-pro",Georgia,Palatino,"Palatino Linotype",Times,"Times New Roman",serif; | |
color: #f8f8f5; | |
text-align: center; | |
text-transform: uppercase; | |
transition: background 0.1s ease-in-out 0s, border 0.1s ease-in-out 0s; | |
white-space: nowrap; | |
border: 1px solid #f8f8f5; | |
background: rgba(71,71,71,0.15); | |
cursor: pointer; | |
} | |
.morph-video-button { | |
position: relative; | |
display: inline-block; | |
min-width: 150px; | |
margin: 0 auto; | |
line-height: 1; | |
} | |
.morph-video-button > button { | |
position: relative; | |
z-index: 1000; | |
padding: 0.75em 1.5em; | |
width: 100%; | |
height: 100%; | |
} | |
.morph-video-button > button:hover { | |
color: #f8f8f5; | |
border-color: #c1311d; | |
background-color: #c1311d; | |
} | |
#video-container { | |
position: fixed; | |
opacity: 0; | |
overflow: hidden; | |
background-color: #c1311d; | |
-webkit-transition: opacity 0.3s 0.5s, width 0.4s 0.1s, height 0.4s 0.1s, top 0.4s 0.1s, left 0.4s 0.1s, background-color 0.4s 0.1s; | |
transition: opacity 0.3s 0.5s, width 0.4s 0.1s, height 0.4s 0.1s, top 0.4s 0.1s, left 0.4s 0.1s, background-color 0.4s 0.1s; | |
} | |
#video-container.open { | |
top: 0 !important; | |
left: 0 !important; | |
width: 100% !important; | |
height: 100% !important; | |
opacity: 1; | |
background-color: #000; | |
-webkit-transition: opacity 0.3s, width 0.4s 0.1s, height 0.4s 0.1s, top 0.4s 0.1s, left 0.4s 0.1s, background-color 0.4s 0.1s; | |
transition: opacity 0.3s, width 0.4s 0.1s, height 0.4s 0.1s, top 0.4s 0.1s, left 0.4s 0.1s, background-color 0.4s 0.1s; | |
} | |
#video-container.active { | |
z-index: 2000; | |
} | |
#video-container .video-btn-close { | |
position: absolute; | |
z-index: 5; | |
top: 0; | |
right: 0; | |
width: 50px; | |
height: 50px; | |
opacity: 0; | |
background: url("close.png") no-repeat center center; | |
cursor: pointer; | |
-webkit-transition: opacity 0.3s 0.2s; | |
transition: opacity 0.3s 0.2s; | |
} | |
#video-container.open .video-btn-close { | |
opacity: 1; | |
} | |
.no-transition { | |
-webkit-transition: none !important; | |
transition: none !important; | |
} | |
.noscroll { | |
overflow: hidden; | |
} | |
.hide { | |
display: none; | |
} | |
.invisible { | |
visibility: hidden; | |
} | |
</style> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script> | |
<!--[if lt IE 9]> | |
<script src="http://cdn.jsdelivr.net/html5shiv/3.7.2/html5shiv.min.js"></script> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script> | |
<![endif]--> | |
</head> | |
<body> | |
<main class="foundation"> | |
<section> | |
<div class="morph-video-button"> | |
<button type="button" class="video-btn" data-vimeo="106299509">Play</button> | |
</div> | |
</section> | |
<section> | |
<div class="morph-video-button"> | |
<button type="button" class="video-btn" data-vimeo="106299507">Play</button> | |
</div> | |
</section> | |
<section> | |
<div class="morph-video-button"> | |
<button type="button" class="video-btn" data-vimeo="106301490">Play</button> | |
</div> | |
</section> | |
<section> | |
<div class="morph-video-button"> | |
<button type="button" class="video-btn" data-vimeo="106301494">Play</button> | |
</div> | |
</section> | |
</main> | |
<script src="//code.jquery.com/jquery.min.js"></script> | |
<script src="//f.vimeocdn.com/js/froogaloop2.min.js"></script> | |
<script> | |
(function($) { | |
/* | |
1. check for video player buttons (length) | |
2. if found, add single video container | |
3. add click event to video player buttons | |
4. open video container | |
5. remove scrollbars; save scroll position | |
6. inject vimeo video <iframe> | |
7. on video completion, remove <iframe>, add scrollbars | |
8. close video container | |
*/ | |
$.videoPlayer = function(element, options) { | |
// ~~~~~ options ~~~~~ | |
var defaults = { | |
onBeforeOpen : function() { return false; }, | |
onAfterOpen : function() { return false; }, | |
onBeforeClose : function() { return false; }, | |
onAfterClose : function() { return false; } | |
}; | |
var $element = $(element), | |
plugin = this; | |
plugin.settings = {}; | |
plugin.isAnimating = false; | |
var transEndEventNames = { | |
'WebkitTransition': 'webkitTransitionEnd', | |
'MozTransition': 'transitionend', | |
'OTransition': 'oTransitionEnd', | |
'msTransition': 'MSTransitionEnd', | |
'transition': 'transitionend' | |
}; | |
var transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ]; | |
var support = { transitions : Modernizr.csstransitions }; | |
var docElem = window.document.documentElement; | |
var video = { | |
player: [], // vimeo iframe container | |
$container: [], // the video.container DOM element, once injected on the page | |
container: '<div id="video-container"><div class="video-btn-close"></div></div>', | |
iframe: '<iframe id="video1" width="100%" height="100%" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen>', | |
url: '//player.vimeo.com/video/{id}?api=1&player_id=video1&autoplay=1&badge=0&byline=0&portrait=0&title=0', | |
activeBtn: [] // which button was clicked to trigger the video player? | |
} | |
plugin.init = function() { | |
plugin.settings = $.extend({}, defaults, options); | |
if(!plugin.settings.trigger.length){ return; } | |
// add video container | |
if(!video.$container.length){ | |
video.$container = $(video.container).appendTo('body'); | |
} | |
plugin.settings.trigger.on('touchstart click', toggle); | |
video.$container.on('touchstart click', '.video-btn-close', toggle); | |
} | |
/* PUBLIC | |
--------------------------------------------------------------------------- */ | |
plugin.open = function() { | |
plugin.settings.onBeforeOpen(); | |
}; | |
plugin.close = function() { | |
plugin.settings.onBeforeClose(); | |
player.remove(); | |
toggle(); | |
}; | |
/* PRIVATE | |
--------------------------------------------------------------------------- */ | |
// ~~~~~ Video Player ~~~~~~ | |
var player = { | |
add: function(){ | |
var id = video.activeBtn.find('.video-btn').data('vimeo'); | |
$video_player = $(video.iframe).attr('src', video.url.replace('{id}', id)).appendTo(video.$container); | |
// Remove white flash when iframe loads | |
$video_player.addClass('invisible').on('load', function(){ | |
$(this).removeClass('invisible'); | |
}); | |
// Vimeo API event listeners | |
video.player = $f($video_player.get(0)); | |
video.player.addEvent('ready', function() { | |
$video_player.removeClass('invisible'); | |
video.player.addEvent('finish', plugin.close); | |
}); | |
}, | |
remove: function(){ | |
video.$container.find('iframe').remove(); | |
} | |
} | |
// ~~~~~ Enable / Disable Scrolling ~~~~~ | |
// trick to prevent scrolling when opening / closing button | |
var scroll = { | |
didScroll: false, | |
position: {}, | |
lock: function() { | |
window.scrollTo( scroll.position ? scroll.position.x : 0, scroll.position ? scroll.position.y : 0 ); | |
}, | |
unlock: function() { | |
$(window).on('scroll', scroll.scrollHandler); | |
}, | |
enable: function() { | |
$(window).off('scroll', scroll.lock); | |
scroll.unlock(); | |
}, | |
disable: function() { | |
$(window).off('scroll', scroll.scrollHandler); | |
$(window).on('scroll', scroll.lock); | |
}, | |
scrollHandler: function() { | |
if( !scroll.didScroll ) { | |
scroll.didScroll = true; | |
setTimeout( function() { scroll.page(); }, 60 ); | |
} | |
}, | |
page: function() { | |
scroll.position = { x : window.pageXOffset || docElem.scrollLeft, y : window.pageYOffset || docElem.scrollTop }; | |
scroll.didScroll = false; | |
} | |
}; | |
scroll.unlock(); | |
// ~~~~~ Overlay Transition ~~~~~ | |
var onEndTransition = function(event){ | |
if( support.transitions ) { | |
video.$container.off(transEndEventName); | |
} | |
plugin.isAnimating = false; | |
// ~~~~ callback ~~~~~ | |
if(video.$container.is('.open')) { | |
plugin.settings.onAfterOpen(); | |
player.add(); | |
$('body').addClass('noscroll'); | |
scroll.enable(); | |
} | |
else { | |
plugin.settings.onAfterClose(); | |
video.$container.removeClass('active').addClass('invisible').removeAttr('style'); | |
scroll.enable(); | |
} | |
} | |
// ~~~~~ Open / Close the Overlay ~~~~~ | |
var toggle = function() { | |
var _this = this; | |
if( plugin.isAnimating ){ return false; } | |
// ~~~~ callback ~~~~~ | |
if(video.$container.is('.open')) { | |
plugin.settings.onBeforeClose(); | |
player.remove(); | |
$('body').removeClass('noscroll'); | |
scroll.disable(); | |
} | |
else { | |
plugin.settings.onBeforeOpen(); | |
// don't allow to scroll | |
scroll.disable(); | |
} | |
plugin.isAnimating = true; | |
if(support.transitions) { | |
video.$container.on(transEndEventName, onEndTransition); | |
} else { | |
setTimeout(onEndTransition, 75); | |
} | |
var isVideoBtn = $(_this).is('.morph-video-button'); | |
if(isVideoBtn){ | |
video.activeBtn = $(_this); | |
video.$container.addClass('no-transition').css({ top: 'auto', left: 'auto', width: 'auto', height: 'auto' }); | |
} | |
// add/remove class "open" to the video.container | |
setTimeout(function() { | |
if(isVideoBtn){ | |
var offset = _this.getBoundingClientRect(); | |
video.$container.css({ top: offset.top+'px', left: offset.left+'px', width:offset.width+'px', height: offset.height+'px' }); | |
} | |
if(video.$container.is('.open')) { | |
video.$container.removeClass('open no-transition invisible'); | |
} | |
else { | |
setTimeout( function() { | |
video.$container.addClass('open active').removeClass('no-transition invisible'); | |
}, 25); | |
} | |
}, 25); | |
}; | |
plugin.init(); | |
}; | |
// add the plugin to the jQuery.fn object | |
$.fn.videoPlayer = function(options) { | |
return this.each(function() { | |
if (undefined == $(this).data('videoPlayer')) { | |
var plugin = new $.videoPlayer(this, options); | |
$(this).data('videoPlayer', plugin); | |
} | |
}); | |
} | |
})(jQuery); | |
$('.foundation').videoPlayer({ | |
trigger: $('.morph-video-button') | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment