I am new to GSAP and I am trying to enable dragging and click on custom html5 video timeline with GSAP. I have read a couple of posts on the GSAP forum but there is something I obviously can't understand...
I've reproduced a simplified example on the following jsfiddle: https://jsfiddle.net/epigeyre/oLmk6b0d/2/
So I create my draggable element from an element stored in a variable, bound it to it's container (which is the timeline container), and then add my function onDrag (I guess click will be the same). The timeline progress is shown by a div inside the timeline container that is scaling on an X axis from 0 to 1. I think linking to the current video time is ok but the animation is not (I don't understand why a translate is applied...).
Here is that specific snippet:
Draggable.create( timelineProgress, {
type:'x',
bounds: timeline, // My timeline container
onDrag: function() {
video.currentTime = this.x / this.maxX * video.duration;
TweenLite.set( timelineProgress, { scaleX: this.x / this.maxX } ) ;
},
onClick: function() {
video.currentTime = this.x / this.maxX * video.duration;
TweenLite.set( timelineProgress, { scaleX: this.x / this.maxX } ) ;
}
});
Could you help me understand what's going? Thanks a lot for your help!
Alright so here the solution for those in need of building a custom video player. Using GSAP you have a really interesting trigger
property within the Draggable plugin.
Here is how I made it work for an HTML5 video timeline.
var video = document.getElementsByTagName('video')[0],
play = document.getElementsByClassName('video__play')[0],
timeline = document.getElementsByClassName('timeline')[0],
timelineProgress = document.getElementsByClassName('timeline__progress')[0],
drag = document.getElementsByClassName('timeline__drag')[0];
// Toggle Play / Pause
play.addEventListener('click', togglePlay, false);
function togglePlay() {
if (video.paused) {
video.play();
} else {
video.pause();
}
}
// on interaction with video controls
video.onplay = function() {
TweenMax.ticker.addEventListener('tick', vidUpdate);
};
video.onpause = function() {
TweenMax.ticker.removeEventListener('tick', vidUpdate);
};
video.onended = function() {
TweenMax.ticker.removeEventListener('tick', vidUpdate);
};
// Sync the timeline with the video duration
function vidUpdate() {
TweenMax.set(timelineProgress, {
scaleX: (video.currentTime / video.duration).toFixed(5)
});
TweenMax.set(drag, {
x: (video.currentTime / video.duration * timeline.offsetWidth).toFixed(4)
});
}
// Make the timeline draggable
Draggable.create(drag, {
type: 'x',
trigger: timeline,
bounds: timeline,
onPress: function(e) {
video.currentTime = this.x / this.maxX * video.duration;
TweenMax.set(this.target, {
x: this.pointerX - timeline.getBoundingClientRect().left
});
this.update();
var progress = this.x / timeline.offsetWidth;
TweenMax.set(timelineProgress, {
scaleX: progress
});
},
onDrag: function() {
video.currentTime = this.x / this.maxX * video.duration;
var progress = this.x / timeline.offsetWidth;
TweenMax.set(timelineProgress, {
scaleX: progress
});
},
onRelease: function(e) {
e.preventDefault();
}
});
video {
display: block;
width: 100%;
height: auto;
}
.timeline {
width: 100%;
height: 10px;
background-color: black;
cursor: pointer;
position: relative;
}
/* Here is the dragger that I will use to move the video
* current time forward or backward.
* I have added a background color for you to see it
* but just remove it in production.
*/
.timeline__drag {
width: 1px;
height: 20px;
top: -10px;
background-color: yellow;
position: absolute;
z-index: 2;
transform-origin: 0 0;
}
.timeline__progress {
display: block;
width: 100%;
height: 100%;
background-color: green;
transform: scaleX(0);
transform-origin: 0 0;
position: relative;
z-index: 1;
}
button {
margin-top: 2em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.0/utils/Draggable.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.0/TweenMax.min.js"></script>
<video>
<source src="http://clips.vorwaerts-gmbh.de/VfE_html5.mp4" type="video/mp4">
</video>
<div class="timeline">
<div class="timeline__drag"></div>
<span class="timeline__progress"></span>
</div>
<button class="video__play">Play / Pause video</button>
I have to thanks Carl of the GSAP forum for his wonderful help!