JSFiddle - React, Tailwind, and code Playground
by Krzysztof
HTML
<div class="upcoming-element">
<p>Upcoming:</p>
<div class="marqueeable">
<div class="wrapper active">
<div class="subwrapper">
<h3>Watch this new video! Watch this new video! Watch this new video!</h3>
</div>
</div>
<div class="wrapper masked">
<div class="subwrapper">
<h3>Watch this new video! Watch this new video! Watch this new video!</h3>
</div>
</div>
<div class="wrapper masked">
<div class="subwrapper">
<h3>Watch this new video! Watch this new video! Watch this new video!</h3>
</div>
</div>
</div>
</div>
<button id="maskLeft">maskLeft</button>
<button id="maskRight">maskRight</button>
<button id="scroll">scroll</button>
<!-- Used to measure width of h3 title -->
<h3 class="measure"></h3>
CSS
body {
background-color: #F00;
}
p, h3 {
margin: 2px;
}
p {
display: inline-block;
margin-left: 12px;
}
h3 {
padding-left: 12px;
white-space: nowrap;
}
h3.measure {
display: none;
padding: 0 10px;
}
.upcoming-element {
width: 450px;
position: relative;
background-color: #00CCFF;
margin-bottom: 25px;
opacity: 0.75;
}
.marqueeable {
overflow-x: hidden;
width: 450px;
position: relative;
opacity: 0.75;
}
.wrapper {
opacity: 0;
transition: opacity .75s ease-in-out;
-moz-transition: opacity .75s ease-in-out;
-webkit-transition: opacity .75s ease-in-out;
}
.wrapper.active {
opacity: 1;
transition: opacity .5s ease-in-out;
-moz-transition: opacity .5s ease-in-out;
-webkit-transition: opacity .5s ease-in-out;
}
.wrapper.masked {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
.wrapper.fade {
opacity: 0;
}
.wrapper.mask {
-webkit-mask-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0) 10px, rgba(0, 0, 0, 1) 100px);
}
.subwrapper.mask {
-webkit-mask-image: -webkit-linear-gradient(right, rgba(0, 0, 0, 0) 10px, rgba(0, 0, 0, 1) 100px);
}
JavaScript
var remask = function (left, right) {
var $active = $('.wrapper').eq(active),
leftMask = $active.hasClass('mask'),
rightMask = $active.find('.subwrapper').hasClass('mask');
console.log('Active', active, $('.wrapper').eq(active));
if (left != null) {
leftMask = left;
}
if (right != null) {
rightMask = right;
}
active = (active + 1) % 3;
console.log('Active', active, $('.wrapper').eq(active));
var $nextActive = $('.wrapper').eq(active),
$nextActiveSub = $nextActive.find('.subwrapper');
leftMask ? $nextActive.addClass('mask') : $nextActive.removeClass('mask');
rightMask ? $nextActiveSub.addClass('mask') : $nextActiveSub.removeClass('mask');
$active.toggleClass('active');
$nextActive.toggleClass('active');
};
var scrollHandler = function (evt) {
$('.measure').text($('.marqueeable .wrapper.active h3').text());
var marqueeSpeed = 35; // px per s
var marqueeWidth = $('.measure').outerWidth() - $('.marqueeable').width();
var marqueeDuration = Math.round(marqueeWidth / marqueeSpeed * 1000);
if (marqueeWidth > 0) {
$('.marqueeable h3').animate({
"margin-left": "-=" + marqueeWidth
}, marqueeDuration, function () {
$('.marqueeable h3').css('margin-left', 0);
});
}
};
var left = false;
var right = false;
var active = 0;
$('#maskLeft').on('click', function (evt) {
left = !left;
remask(left);
});
$('#maskRight').on('click', function (evt) {
right = !right;
remask(null, right);
});
$('#scroll').on('click', scrollHandler);