@opherv / Oct 2016 / CPHFront
I work with developers, designers and video makers to create some pretty cool experiences
I'm a creative developer at Interlude
A game
A presentation
An interview
An app
and anything else, really
Changing/switching the video stream content
Manipulating the video stream display (postprocessing, shaders)
Graphic overlays ("buttons")
Interface (gestures, phone sensors, web services)
Sounds simple...?
<div class="videoContainer">
<video controls id="video" muted autoplay loop>
<source src="http://opherv.com/cartest.mp4" type="video/mp4">
</video>
<button>Do something</button>
</div>
Basic Layout
#1: GUI is Time Based and context sensitive
video "timeupdate" event to the rescue!
videoEl.addEventListener("timeupdate",function(e){
if (videoEl.currentTime > 1
&& videoEl.currentTime < 2){
buttonEl.style.opacity = 1;
buttonEl.style.pointerEvents = "all";
}
else if (videoEl.currentTime > 6){
buttonEl.style.opacity = 0;
buttonEl.style.pointerEvents = "none";
}
});
Example: That Moment When
videoEl.addEventListener("timeupdate",function(e){
if (videoEl.currentTime > startTime
&& videoEl.currentTime < endTime){
buttonEl.style.left = SOME_CALCULATION;
}
});
Moving GUI
//will get called on each frame render
var onRender = function(){
if (videoEl.currentTime > startTime
&& videoEl.currentTime < endTime){
buttonEl.style.left = CURRENT_TIME_BASED_CALCULATION
}
requestAnimationFrame(onRender)
}
requestAnimationFrame(onRender)
#2: GUI needs to correspond
to your video size
responsive
scaling
.guiContainer{
position: absolute;
width: 100%;
padding-top: 1/$aspectRatio * 100%;
left: 0;
top: 50%;
transform: translateY(-50%);
}
function calculateGuiContainerSize(containerWidth, containerHeight){
var isPillarBoxing = containerWidth/containerHeight > aspectRatio;
if (isPillarBoxing){
var scale = containerHeight/originalHeight;
guiContainer.style.height = "100%";
guiContainer.style.width = containerHeight * aspectRatio + "px";
guiContainer.style.left =
( containerWidth - containerHeight * aspectRatio ) / 2 + "px";
guiContainer.style.top = 0;
}
else{
var scale = containerWidth/originalWidth;
guiContainer.style.width="100%";
guiContainer.style.height = containerWidth / aspectRatio + "px";
guiContainer.style.top =
( containerHeight - containerWidth / aspectRatio ) / 2 + "px";
guiContainer.style.left = 0;
}
}
Example: Trending Loop
var isPillarBoxing = containerWidth/containerHeight > aspectRatio;
if (isPillarBoxing){
var scale = containerHeight/originalHeight;
guiContainer.style.transform = "scaleX("+scale+") scaleY("+scale+")";
guiContainer.style.top = 0;
guiContainer.style.left = ( containerWidth - containerHeight * aspectRatio ) / 2 + "px";
}
else{
var scale = containerWidth/originalWidth;
guiContainer.style.transform="scaleX("+scale+") scaleY("+scale+")";
guiContainer.style.top = ( containerHeight - containerWidth / aspectRatio ) / 2 + "px";
guiContainer.style.left = 0;
}
GUI Scaling
Example: Mind Blown
Another option:
example: Clash Up
Moving GUI can pose a challenge
requestAnimationFrame to the rescue
GUI needs to adapt to your video size
account for letterboxing/pillarboxing - scale or respond
recap
Account for imprecisions!
Prefer animation using hardware accelerated properties:
CSS3 3D Transforms, CSS3 Transitions (not "left" or "top")
Disable interactions when not shown
pointerEvents: "none"/ display: "none"
Test test test test test (did I say test?)
Devices fragmentation = nightmare / spec implementations / network conditions
Chrome, FF, Safari, Edge
Mobile Chrome / Android
Mobile Safari / iPad
Mobile Safari / iPhone
Yeah!
Yeah!
sorta...
>iOS 10
Video is played in its own quicktime context,
on top of the browser
All UI events are captured by this context
On iOS-based devices with small screens—such as iPhone and iPod touch—video always plays in fullscreen mode, so the canvas cannot be superimposed on playing video. On iOS-based devices with larger screens, such as iPad, you can superimpose canvas graphics on playing video, just as you can on the desktop"
The magic keyword - use a UKWebView
Roll your own app!
the video element in the HTML document must also include the webkit-playsinline attribute.
We solved a lot of this stuff so you don't have to
Want to learn more?
(tell them @OpherV sent you)
@OpherV
opherv.com
opherv@gmail.com
github.com/opherv