我试图弄清楚每次将鼠标悬停在盒子上时如何重播 Vimeo 视频,就像将鼠标悬停在他们的视频上时的 Pond5 一样。但问题是,当您第一次悬停时,它只会一直播放。
看起来有可能用 Froogaloop 做到这一点,但我不确定如何在当前的 javascript 代码中实现它。
有没有办法在每次悬停时重新启动视频?
这是我到目前为止所拥有的。任何帮助都是极好的!
HTML
<section class="full video-downloads gray-bg">
<div class="video-downloads-wrapper" video-rollover="1">
<div class="video-item">
<div class="download-wrap video-rollover black-bg" data-video="642263700">
<p style="color:#ffffff;display:grid;justify-content:center;align-items:center;width:100%;">rollover this</p>
</div>
</div>
</div>
</section>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://player.vimeo.com/api/player.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vimeo-froogaloop@0.1.0/froogaloop.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.8.0/gsap.min.js"></script>
CSS
.video-item .download-wrap a{
display: flex;
}
.video-item img{
max-width: 100%;
height: 305px;
object-fit: contain;
width: 100%;
border: 1px solid #424242;
}
.video-item .video-rollover i span{
font-family: myriad-pro, sans-serif;
font-size: 12px;
text-transform: uppercase;
margin-top: 10px;
}
.video-item .video-rollover{
position: relative;
margin-bottom: 10px;
display: flex;
cursor: pointer;
width:350px;
height:350px;
background: black;
}
.video-reveal {
position: fixed;
width: 350px;
height: 200px;
top: 0;
left: 0;
pointer-events: none;
opacity: 0;
background: #000000;
border: 1px solid #424242;
}
.video-reveal-clip iframe{
width: 100%;
height: 100%;
object-fit: contain;
}
.video-reveal-inner,
.video-reveal-clip {
width: 100%;
height: 100%;
position: relative;
}
.video-downloads-wrapper{
color: #ffffff;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(241px,1fr));
gap: 20px;
}
JS
{ // Video Rollover Function
const mapNumber = (X,A,B,C,D) => (X-A)*(D-C)/(B-A)+C;
// from http://www.quirksmode.org/js/events_properties.html#position
const getMousePos = (e) => {
let posx = 0;
let posy = 0;
if (!e) e = window.event;
if (e.pageX || e.pageY) {
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX || e.clientY) {
posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
return { x : posx, y : posy }
}
// Generate a random float.
const getRandomFloat = (min, max) => (Math.random() * (max - min) + min).toFixed(2);
// Plug in video id into iframe
class videoHover {
constructor(el) {
this.DOM = {el: el};
this.DOM.reveal = document.createElement('div');
this.DOM.reveal.className = 'video-reveal';
this.DOM.reveal.innerHTML = `
<div class="video-reveal-inner">
<div class="video-reveal-clip">
<iframe id="${this.DOM.el.dataset.video}" class="video-iframe" src="https://player.vimeo.com/video/${this.DOM.el.dataset.video}?h=53a1e27e93&badge=0&autopause=0&autoplay=1&loop=1&muted=1" width="1080" height="1350" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" title="video-test"></iframe>
</div>
</div>`;
this.DOM.el.appendChild(this.DOM.reveal);
this.DOM.revealInner = this.DOM.reveal.querySelector('.video-reveal-inner');
this.DOM.revealInner.style.overflow = 'hidden';
this.DOM.revealVideo = this.DOM.revealInner.querySelector('.video-reveal-clip');
this.initEvents();
}
initEvents() {
this.positionElement = (ev) => {
const mousePos = getMousePos(ev);
const docScrolls = {
left : document.body.scrollLeft + document.documentElement.scrollLeft,
top : document.body.scrollTop + document.documentElement.scrollTop
};
this.DOM.reveal.style.top = `${mousePos.y+20-docScrolls.top}px`;
this.DOM.reveal.style.left = `${mousePos.x+20-docScrolls.left}px`;
};
this.mouseenterFn = (ev) => {
this.positionElement(ev);
this.showVideo();
};
this.mousemoveFn = ev => requestAnimationFrame(() => {
this.positionElement(ev);
});
this.mouseleaveFn = () => {
this.hideVideo();
};
this.DOM.el.addEventListener('mouseenter', this.mouseenterFn);
this.DOM.el.addEventListener('mousemove', this.mousemoveFn);
this.DOM.el.addEventListener('mouseleave', this.mouseleaveFn);
}
showVideo() {
TweenMax.killTweensOf(this.DOM.revealInner);
TweenMax.killTweensOf(this.DOM.revealVideo);
this.tl = new TimelineMax({
onStart: () => {
this.DOM.reveal.style.opacity = 1;
TweenMax.set(this.DOM.el, {zIndex: 1000});
}
})
.add('begin')
.add(new TweenMax(this.DOM.revealInner, 0.2, {
ease: Sine.easeOut,
startAt: {x: '-100%'},
x: '0%'
}), 'begin')
.add(new TweenMax(this.DOM.revealVideo, 0.2, {
ease: Sine.easeOut,
startAt: {x: '100%'},
x: '0%'
}), 'begin');
}
hideVideo() {
TweenMax.killTweensOf(this.DOM.revealInner);
TweenMax.killTweensOf(this.DOM.revealVideo);
this.tl = new TimelineMax({
onStart: () => {
TweenMax.set(this.DOM.el, {zIndex: 999});
},
onComplete: () => {
TweenMax.set(this.DOM.el, {zIndex: ''});
TweenMax.set(this.DOM.reveal, {opacity: 0});
}
})
.add('begin')
.add(new TweenMax(this.DOM.revealInner, 0.2, {
ease: Sine.easeOut,
x: '100%'
}), 'begin')
.add(new TweenMax(this.DOM.revealVideo, 0.2, {
ease: Sine.easeOut,
x: '-100%'
}), 'begin');
}
}
// Attach video to cursor on hover
[...document.querySelectorAll('[video-rollover="1"] .video-rollover, a[video-rollover="1"]')].forEach(link => new videoHover(link));
}
CODEPEN 链接
https://codepen.io/tampham/pen/ExwaJWX