centering videojs vertically on a page? - javascript

Context: Electron desktop app using Timeline.js which is embedding Video.js through an iFrame. The iFrame source is below.
I've been struggling with this for a few hours now: I need to vertically center the Video.js instance in the iFrame it is within. I can't hardcode values because the app (not only videojs) can go full screen.
Using the "brute force" CSS below, it "works" but obviously the black bars are not acceptable. I removed that an added a ref to the vjs vjs-16-9 CSS and it works great: sets up size based on content, resizes in full screen mode – all good except that I haven't been able to figure out how to center the vjs instance vertically in the iFrame.
Probably something simple but I'm new at all this.
.video-js {
position: absolute;
top: 0;
left: 0;
width: 100%!important;
height: 100%!important;
}
Using vjs-16-9 CSS
iFrame source
<!DOCTYPE html>
<html lang="en">
<head>
<title>Video.JS Example</title>
<link href="../node_modules/video.js/dist/video-js.min.css" rel="stylesheet">
<script src="../node_modules/video.js/dist/video.min.js"></script>
<style>
html, body {
height:100%;
width:100%;
padding: 0px;
margin: 0px;
}
</style>
</head>
<body>
<div>
<video id="videoPlayer" class="video-js vjs-default-skin vjs-16-9" controls preload="auto">
</video>
</div>
<script>
function getParamValue(paramName) {
var url = window.location.search.substring(1);
var qArray = url.split('&');
for (var i = 0; i < qArray.length; i++) {
var pArr = qArray[i].split('=');
if (pArr[0] == paramName)
return pArr[1];
}
}
// grap the video & poster frame refs from url
var videoSrc = getParamValue('videoSrc');
videoSrc = "assets/videos/" + videoSrc;
var poster = getParamValue('poster');
poster = "assets/images/" + poster;
videojs("videoPlayer", {}, function () {
this.src(videoSrc);
this.poster(poster);
this.load();
});
</script>
</body>
</html>

Finally found a solution which doesn't seem fragile: Vertical align anything with just 3 lines of CSS.
Assigned to the div containing the videojs instance
.centerVertically {
position: relative;
top: 50%;
transform: translateY(-50%);
}
<div class="centerVertically">
<video id="videoPlayer" class="video-js vjs-default-skin vjs-16-9" controls preload="auto">
</video>
</div>

Most likely , iframe has its own styling by its own. Hence , brute force Css is needed. But to answer your question regarding aligning center for your iframe. You might want to explore more on using flex , justify content, justify center.
There are also other alternative such as using float but float is not a good practice to use unless you really have no choice of using it. The reason is. Float might react differently and mess up the alignment at certain occasions ..
I hope my information helps.
Cheers.

Related

Start Animation (Animate CC) only when the canvas become visible after scrolling.

I have an animation (made with Adobe animate CC) that I have included into my html file. I am trying to change its original script in order to start the animation from the beginning only when it becomes visible in the viewport of the browser. Unfortunately, I searched widely but couldn't make any of the solutions I found worked for my case.
This is the original code I'm trying to change:
<html>
<head>
<script>
var canvas, stage, exportRoot, anim_container, dom_overlay_container,
fnStartAnimation;
function init() {
canvas = document.getElementById("canvas");
anim_container = document.getElementById("animation_container");
dom_overlay_container = document.getElementById("dom_overlay_container");
var comp=AdobeAn.getComposition("07578064E5C140B781D146A1AE4968A3");
var lib=comp.getLibrary();
handleComplete({},comp);
}
function handleComplete(evt,comp) {
//This function is always called, irrespective of the content. You can use the variable "stage" after it is created in token create_stage.
var lib=comp.getLibrary();
var ss=comp.getSpriteSheet();
exportRoot = new lib.Water_illustrazione_revista_scrollplay();
stage = new lib.Stage(canvas);
//Registers the "tick" event listener.
fnStartAnimation = function() {
stage.addChild(exportRoot);
createjs.Ticker.setFPS(lib.properties.fps);
createjs.Ticker.addEventListener("tick", stage);
}
//follow a code to support hidpi screens and responsive scaling.
</script>
</head>
<body onload="init();" style="margin:0px;">
<div id="anchor5" class="Anime_p">
<div id="animation_container" style="background-color:rgba(255, 255, 255, 1.00); width:1280px; height:700px">
<canvas id="canvas" width="1280" height="700" style="position: absolute; display: block; background-color:rgba(255, 255, 255, 1.00);"></canvas>
<div id="dom_overlay_container" style="pointer-events:none; overflow:hidden; width:1280px; height:700px; position: absolute; left: 0px; top: 0px; display: block;">
</div>
</div>
</div>
</body>
</html>
You simply need to export the animation as stopped at first and then check when the div comes in browser view. Whenever it does, start the animation.
Add exportRoot.stop(); in the end of fnStartAnimation();
Check for visibility of your animation div in browser as explained here - How to tell if a DOM element is visible in the current viewport?
Whenever the condition is satisfied, add the code - exportRoot.play();

Play animation when content get into view

I've been searching on many posts but almost all of them are confusing.
I'm working with animate.css into a which is at the middle of my page.
For default the animation is played when the page is loaded, but i want that it play when i reach the (when i'm scrolling).
Please, don't say about JS Reveal, i'd like to use the animation from animate.css
What i was trying:
HTML
<!-- Others div above -->
<div class="row sf-medida" id="sf-medida" onscroll="Animar();">
<!-- Others div below -->
JS
function Animar() {
setTimeout(function(){
document.getElementById("sf-medida").style.visibility = "visible";
$("#titulo-general").addClass("animated fadeInLeft");
$(".sub-titulo").addClass("animated bounceInRight");
$(".titulo-izquierda").addClass("animated swing");
$(".texto-1").addClass("animated fadeIn");
$(".texto-2").addClass("animated fadeIn");
},1000)
}
But it doesn't work, however, i've tried adding
window.addEventListener("scroll", Animar);
But what it does is that the animation is played whenever i scroll on the page,
This can be very easily done using little jquery. All you need to do is listen to the scroll event, then check if user have scrolled to the target element. If the user did, then add animation class from your animate.css. Adjust your if condition according to your desires. Check the below code and fiddle https://jsfiddle.net/15z6x5ko/ for reference
$(document).ready(function(){
$(document).scroll(function(evt){
var v2 = Math.abs($('.box').position().top - $(window).height()/2);
var v1 = $(this).scrollTop();
if( v1 > v2 ){
console.log('in');
$('.box').addClass('animated flip')
}
});
});
So as per your request, let me try to explain the code line by line
$(document).ready(function(){
This is easy to understand. It just waits for browser to load all HTML & CSS first and when everything is loaded, the javascript code inside this function will run.
$(document).scroll(function(evt){
This is an event handler, our callback function will run whenever user scrolls on document. Remember change $(document) according whatever the parent is of your target element. So if your target div is inside another div whose class is .parent then use $('.parent').scroll . As for my code I am listening the event on document. When my document scrolls, my event will trigger.
var v1 = $(this).scrollTop();
This code will get the amount of scrolling user had done in pixels.
var v2 = Math.abs($('.box').position().top - $(window).height()/2);
This is a simple math that checks the position of my target div from its parent element subtracting the half of the size of window from it. This will return the pixel positing of your target div. So when user reaches this pixel positing while scrolling, your animation will start.
$('.box').addClass('animated flip')
Now this code simply adds the animation css classes into the target div as soon as user scrolls to the target div.
I'm using "WoW.js" for my scroll reveal library. It's pretty easy to use, like for real. One line of code
<div class="wow fadeIn">content</div>
Here, take a look: http://mynameismatthieu.com/WOW/docs.html
Here's an example using Jquery.
In it we use .scrollTop and .height to measure the videos container from the top of the page so that we know when it comes into view when scrolling. (it's actually set to load when it reaches 100px below the bottom of the viewable area, a sort of preload. you can adjust it to whatever you like.)
The video load is done by copying the url from data-src= into src= when the video container is at the desired spot on the page. (in this case, 100px below the viewable area)
fiddle
note, the video won't load on stack so be sure to view the fiddle
https://jsfiddle.net/Hastig/xszu6b1p/
I scraped it together from these two answers..
Youtube Autoplay
Ladyload Images
$(window).scroll(function() {
$.each($('iframe'), function() {
if ( $(this).attr('data-src') && $(this).offset().top < ($(window).scrollTop() + $(window).height() + 100) ) {
var source = $(this).data('src');
$(this).attr('src', source);
$(this).removeAttr('data-src');
}
})
})
body {
margin: 0;
}
.filler {
display: flex;
justify-content: center;
align-items: center;
height: 800px;
}
.filler-top { background-color: blue }
.filler-btm { background-color: green; }
.video-container {
/* css tricks - responsive iframe video */
/* https://css-tricks.com/NetMag/FluidWidthVideo/Article-FluidWidthVideo.php */
position: relative;
padding-bottom: 56.25%; /* 16:9 */
padding-top: 25px;
height: 0;
display: flex;
justify-content: center;
background-color: red;
}
.video-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="filler filler-top">filler top</div>
<div class="video-container">
<iframe data-src="https://www.youtube.com/embed/f0JDs4FY8cQ?rel=0&autoplay=1"></iframe>
</div>
<div class="filler filler-btm">filler bottom</div>

auto height for the <object/> element with the embedded content

I am trying to get the auto height for the <object/> element according to the embedded content inside. Is this possible?
An example of the issue is here: JSFiddle. Here In Chrome, it seems the auto is ignored. How can I fix this?
HTML
<body>
<object id="my-object" data="http://www.rfc-editor.org/rfc/rfc1.txt"></object>
</body>
CSS
#my-object {
height : auto;
width : 300px;
}
EDIT
I want to make the object as big as its content, so as to avoid the scroll of object element. It should be page scroll instrad of object elements scroll.
working fiddle (100% height, min-height and overflow hidden to body and html elements )
http://jsfiddle.net/DmF6B/2/
html, body{
overflow:hidden;
height: 100%;
min-height: 100%;
}
#my-object {
height : 100%;
width : 100%;
overflow : hidden;
}
html
<body scroll="no">
<object id="my-object" data="http://www.rfc-editor.org/rfc/rfc1.txt">
</object>
</body>
if it is in the same domain use the javascript function "contentDocument()"
try this instead : ajax
it must be run under a server
with "contentDocument()"
<object id="my-object" type="text/plain" data="newfile.txt">
</object>
<script>
var object = document.getElementById("my-object");
object.onload = function () {
var objectPre = object.contentDocument.body.childNodes[0];
object.style.height = (objectPre.offsetHeight+20) + "px";
};
</script>
with ajax do a search on loading the txt file using ajax

Two serial webkit transitions does not work on some android devices

I want to have two webkitTransitions applied one after one to the same div element for webkitTransform property. Here is the code:
<html>
<head>
<title></title>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", init);
function init() {
var d1 = document.getElementById("d1");
d1.style.webkitTransition = "-webkit-transform 1s linear";
d1.style.webkitTransform = "translate(-100px,0px)";
setTimeout(function(){
d1.style.webkitTransition = "-webkit-transform 1s linear";
d1.style.webkitTransform = "translate(-150px,0px)";
}, 1500);
}
</script>
<style type="text/css">
div#d1 {
position: absolute;
background-color: rgba(13,15,112,122);
width: 200px;
height: 200px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="d1"/>
</body>
</html>
http://bit.ly/UnTqAV
This results to the second transform is applied directly without any transition on Android 4.0.4 Samsung tablets default browser (GT-P5110 GT-P3110 ...). Other devices work fine.
I've tried using with/without 3d postfix and open GL switched on/off. Does anyone have the same experience?
We had the same problem, it's a (big) bug of Android 4.0.4 WebView. We had to write again some animations on our webapp.
The trick is to use the CSS matrix property for every transformation, instead of the specific translate, scale, and so on.
This link is very nice to learn more on 2D matrices:
http://www.eleqtriq.com/wp-content/static/demos/2010/css3d/matrix2dExplorer.html

Liquid Layout IE Problems, of course (Newbie)

I'm new to CSS, never created a layout before and I'm having some issues with my first one in Internet Explorer. I think it looks good in Firefox though.
I have done a lot of reading about HTML and CSS before starting the layout so I knew IE had some bugs but even after making the layout and researching the issues none of the resolutions seem to be working. Im hoping someone here can help.
TL;DR: New layout not working in IE, need help(did research)
Problem 1: In IE the 2 right sidebars are too wide compared to Firefox. Everything else appears normal, just those 2 are too wide which is affecting the layout
Problem 2: When the window width is below 1024 it is supposed to switch from container1.css to container2.css effectively changing the container properties to better display in smaller resolutions. Works great in Firefox, but in IE it seems to remove the container period leaving the contents to flow throughout the entire window.
<HTML>
<HEAD>
<TITLE>My Liquid Layout</TITLE>
<link rel="stylesheet" type="text/css" href="LiquidLayout.css" />
<link id="container1" rel="stylesheet" type="text/css" href="container1.css" />
<link id="container2" rel="alternate" type="text/css" href="container2.css" />
<script type="text/javascript">
<!--
var css = "container1";
function changeStyle(styleSheet)
{
if(styleSheet == css)
return;
var selected = document.getElementById(styleSheet);
var current = document.getElementById(css);
if(!selected)
{
selected = current.cloneNode(true);
selected.id=styleSheet;
selected.setAttribute("href",current.getAttribute("href").replace(new
RegExp(css),styleSheet));
}
current.setAttribute("rel","stylesheet1");
selected.setAttribute("rel","stylesheet");
document.getElementsByTagName('head')[0].appendChild(selected);
css = styleSheet;
}
function windowSize()
{
var windowWidth;
var windowHeight;
windowWidth = window.innerWidth;
windowHeight = window.innerHeight;
if (document.body && document.body.offsetWidth)
{
windowWidth = document.body.offsetWidth;
windowHeight = document.body.offsetHeight;
}
if (document.compatMode=='CSS1Compat' &&
document.documentElement &&
document.documentElement.offsetWidth )
{
windowWidth = document.documentElement.offsetWidth;
windowHeight = document.documentElement.offsetHeight;
}
if (window.innerWidth && window.innerHeight)
{
windowWidth = window.innerWidth;
windowHeight= window.innerHeight;
}
if(windowWidth < 1024)
changeStyle('container2');
else if(windowWidth >= 1024)
changeStyle('container1');
}
window.onresize = new Function("windowSize()");
//-->
</script>
</HEAD>
<BODY>
<div id = "container">
<div id = "header"><p id = "size"></p></div>
<div id = "content">
<div id = "menu">
<ul>
<li>About</li>
<li>Contact</li>
<li>Home</li>
<li>Video</li>
<li>Gallery</li>
<li>IGN</li>
</ul>
</div>
<div id = "sidebox"></div>
<div class = "column" id = "sidebar"></div>
<div class = "column" id = "main"></div>
</div>
<div id = "footer"></div>
</div>
</BODY>
</HTML>
The main CSS is:
body
{
background-color:gray;
margin: 0px;
text-align: center;
}
#header
{
width: 100%;
height: 200px;
background-color: yellow;
}
#content
{
padding-top:5px;
padding-bottom:0px;
padding-right:5px;
padding-left:5px;
min-height: 768px;
}
#menu
{
width: 66%;
height: 250px;
background-color: blue;
float: left;
}
#sidebox
{
width: 34%;
height: 250px;
background-color: red;
float: right;
display: inline;
}
#sidebar
{
width: 34%;
background-color: red;
height: 100%;
float: right;
}
#main
{
width: 65%;
height: 100%;
background-color: green;
float: left;
}
If anyone can please offer some advice on fixing these issues in IE I would appreciate it!
Any suggestions for improvement are welcome as well
You didn't specify which version of IE, so I'm guessing you've only checked the most recent version?
Add a doctype as suggested, and you should be ok in IE9, but if you're supporting other versions of IE as well you are going to want some way of targeting each version independently as they all have different and progressively worse bugs. Occasionally, something will work in IE7 but not IE8, but generally as you head towards IE6 your problems will multiply exponentially, especially with a liquid layout.
I'd recommend using Modernizr, which will add different class names to the HTML element depending on the version of IE in use. It also does a bunch of other stuff like making HTML5 elements styleable in older IE as well, so it is worth using, even without any of the other feature tests it offers. I can see you aren't using any HTML5 elements, but I don't know if that's your whole layout, or just the beginnings of it...
You'll probably also want to use Selectivizr so that most useful CSS3 features can be used in IE8 and below as well, although you need to use a JS library, such as jQuery for this, so it may or may not be useful. There isn't any CSS3 in your CSS, but again, your example could be much simplified
In terms of improvements to your code, you don't need to include HTML comments in your script tags <!-- and haven't since the days of like IE4 or something. Additionally, your should go at the bottom of the <body> (just before the closing </body>) for performance reasons, rather than in the <head>, and if you use the HTML5 doctype (which you can still use even if you aren't planning on using any HTML5 elements) you don't need to specify a type attribute on the <script> element. In JavaScript, the opening curly brackets should go on the same line as the function definition or conditional, so do:
if (condition) {
or:
function something() {
and not:
if (condition)
{
or:
function something()
{
This is usually ok most of the time, but it can produce bugs that are very hard to spot, so it is worth getting into the habit of doing it all the time. And when attaching an event listener, you don't need to specify new Function("function_name"), you can just attach the function directly:
window.onresize = windowSize();
Also, in CSS, zero values do not need to specify measurement units, so you can just have 0 instead of 0px...
If you have copy and pasted the entirity then your missing a doctype making IE render in quirksmode.
I would suggest adding the HTML5 doctype to the top of your document <!DOCTYPE html>
More information on quirks mode can be found here

Categories