Marquee Slider lacks after few iterations - javascript

I have created a marquee slider. After a few iterations the marquee lacks.
I want to have the marquee to have full view-width. As I can see the marquee is lacking less on smaller devices. I have created other similar marquees before with different elements and never had that problem. The empty list elements I have implemented to have a spacing between the text elements, but the icons should be next to the text as they are currently.
(function marquee() {
var marqueeWrapper = $('.js-marquee');
var FPS = (60/100); // 60fps
var SLIDESPEED = 1000; // default | lower is faster
marqueeWrapper.each(function (index, element) {
var _marqueeWrapper = $(element);
var _marqueeTracks = $('>ul', _marqueeWrapper);
var _marqueeSlides = $('>ul>li', _marqueeWrapper);
var _marqueeWidth = parseFloat(_marqueeSlides.last().position().left + _marqueeSlides.last().outerWidth(true));
var shifted = _marqueeWrapper.attr('data-marquee-shift') || false;
var SPEED = (_marqueeWrapper.attr('data-marquee-speed') * _marqueeSlides.length) || (SLIDESPEED * _marqueeSlides.length);
var frames = SPEED * FPS;
var steps = _marqueeWidth / frames; // distance elems will move each frames
var posX = 0;
var tempSteps;
function _clone() {
var times = Math.ceil(_marqueeWrapper.outerWidth(true) / _marqueeWidth) + 1;
_marqueeTracks.each(function () {
$('>ul', _marqueeWrapper).empty();
var sliders = _marqueeSlides;
for (i = 1; i <= times; i++) {
sliders.clone().appendTo(($(this)));
}
})
}
function _animated() {
posX += -steps;
_marqueeTracks.css({
transform: 'translate3d(' + posX + 'px, 0, 0)'
});
if (Math.abs(posX) >= _marqueeWidth) {
posX = 0;
}
window.requestAnimationFrame(_animated);
}
function _pause() {
tempSteps = steps;
return steps = 0;
}
function _resume() {
return steps = tempSteps;
}
function _shiftPosition() {
if(shifted) return posX = -(_marqueeSlides.first().outerWidth(true)) / 2 ;
}
/*
function _registerEvents() {
_marqueeTracks.on('mouseenter', _pause);
_marqueeTracks.on('mouseleave', _resume);
$(window).on('resize', debounce(_clone, 300))
}*/
function init() {
_shiftPosition()
_clone();
_animated();
/*_registerEvents();*/
}
function debounce(func, wait, immediate) {
var timeout;
return function () {
var context = this,
args = arguments;
var later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};// debounce
init();
})
})();
.marquee {
background: black;
width: 100%;
overflow: hidden;
}
.marquee__track {
display: flex;
padding: 0;
margin: 0;
list-style: none;
}
.marquee__item {
display: flex;
justify-content: center;
align-items: center;
color: white;
height: 100px;
margin-right: 10px;
padding-bottom: 10px;
}
.marquee__item {
height: 80px;
}
.marquee__item_vegan {
flex: 0 0 120px;
font-size: 50px;
font-family: Gothic821;
}
.marquee__item_gluten {
flex: 0 0 160px;
font-size: 50px;
font-family: Gothic821;
}
.marquee__item_natural {
flex: 0 0 130px;
font-size: 50px;
font-family: Gothic821;
}
.marquee__item_empty {
flex: 0 0 180px;
}
.marquee__item_small {
flex: 0 0 80px;
}
.marquee__item_icon {
width: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div data-marquee-speed="100" data-marquee-shift="false" class="marquee js-marquee">
<ul class="marquee__track">
<li class="marquee__item marquee__item_small"><img class="marquee__item_icon" src="{{ 'Haken_weiss.svg' | asset_url }}"/></li>
<li class="marquee__item marquee__item_vegan">VEGAN</li>
<li class="marquee__item marquee__item_empty"></li>
<li class="marquee__item marquee__item_small"><img class="marquee__item_icon" src="{{ 'Haken_weiss.svg' | asset_url }}"/></li>
<li class="marquee__item marquee__item_gluten">GLUTENFREI</li>
<li class="marquee__item marquee__item_empty"></li>
<li class="marquee__item marquee__item_small"><img class="marquee__item_icon" src="{{ 'Haken_weiss.svg' | asset_url }}"/></li>
<li class="marquee__item marquee__item_natural">NATURAL</li>
<li class="marquee__item marquee__item_empty"></li>
</ul>
</div>

The given code seems rather complex for a simple marquee.
While you will need to invoke a little JS at the start (on a load or a resize) to make sure the timing is right for the speed required (it varies depending on viewport width) there seems little to be gained from using JS for the actual animation.
And there may be some loss in using JS which does not guarantee real-time timing (your system may be busy doing other things) and that can introduce lag. Using a CSS method can help to smooth things as there is less need to move back and forth between CPU and GPU.
The given code also performs the animation in steps, moving position, which can be jerkier than translating.
This snippet is stripped down to demonstrate the basic ideas in using HTML and CSS without JS.
As in the code in the question, a second copy of the items is made. This allows the marquee to appear continuous, as the first item disappears to the left it can be seen coming in from the right.
The units used are related to the viewport width so the whole thing is responsive. A CSS animation is used to get the movement, moving the whole 50% of its width, then when the copy comes in it is overwritten by the first part so the movement looks continuous (this is the same technique as used in the given code but with pure CSS rather than JS/CSS).
.marquee,
.marquee * {
margin: 0;
padding: 0;
border-width: 0;
}
.marquee {
background: black;
overflow: hidden;
}
.marquee>ul {
display: flex;
width: 200vw;
justify-content: space-around;
list-style: none;
animation: move 5s linear infinite;
white-space: nowrap;
}
.marquee>ul li {
font-size: 4vw;
color: white;
margin: 5vw;
position: relative;
}
.marquee__item_vegan,
.marquee__item_gluten,
.marquee__item_natural {
--bg: linear-gradient(white, white);
/* just for demo */
}
.marquee>ul li::before {
content: '';
width: 4vw;
height: 4vw;
left: -4vw;
display: inline-block;
position: absolute;
background-image: var(--bg);
background-repeat: no-repeat;
background-size: 80% 80%;
background-position: bottom left;
}
#keyframes move {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-50%);
}
}
<div class="marquee">
<ul>
<li class="marquee__item_vegan">VEGAN</li>
<li class="marquee__item_gluten">GLUTENFREI</li>
<li class="marquee__item_natural">NATURAL</li>
<li class="marquee__item_vegan">VEGAN</li>
<li class="marquee__item_gluten">GLUTENFREI</li>
<li class="marquee__item_natural">NATURAL</li>
</ul>
</div>
Notes: you may want to reinstate some JS to calculate the timing - depends on your use case.
The spurious list items have been removed. The imgs which are really just visual clues are added as before pseudo elements. The empty items are not needed. (It's best to keep formatting and content separate, especially for those using assistive technology such as screen readers).

Related

jQuery mouseover doesn't work as expected on document

I would like to have my own cursor only displayed over certain images with a certain class.
I've already written a few lines for that.
Here is my code:
function registerCursorHoverEffect() {
if (!isTouch()) {
const el = document.body;
var cursorDiv = document.createElement("div");
cursorDiv.setAttribute("id", "cursor");
cursorDiv.setAttribute("class", "light-spot light-spot--cursor light-spot--center-center light-spot--color-red light-spot--filled light-spot--outside");
el.before(cursorDiv);
document.getElementById("cursor").innerHTML = '<svg class="cursor-main" xmlns="http://www.w3.org/2000/svg" width="70" height="70" viewport="0 0 100 100" style="stroke: white; fill:white;font-size:300px; z-index: 9999999;position: absolute; top: 40px; right: 40px; bottom: 0;"><path d="M59.71,31.29l-10-10a1,1,0,0,0-1.42,1.42L56.59,31H5a1,1,0,0,0,0,2H56.59l-8.3,8.29a1,1,0,0,0,0,1.42,1,1,0,0,0,1.42,0l10-10A1,1,0,0,0,59.71,31.29Z"/></svg>';
var cursorDivAppend = document.createElement("div");
cursorDivAppend.setAttribute("id", "cursor-append");
cursorDivAppend.setAttribute("class", "cursor-append");
el.before(cursorDivAppend);
// Mousemove
$(document).on('mousemove', function (event) {
if($('.col-3:hover').length != 0) {
const appendScale = 1
var destinationX = event.pageX;
var destinationY = event.pageY;
var transformScale = `translate(calc(${destinationX}px - 50%), calc(${destinationY}px - 50%)) scale(${appendScale})`
$('#cursor').css('transform', transformScale);
}
})
}
}
The following screenshot shows what is generated when you hover over an image with a certain class:
The critical part of it all is here:
// Mousemove
$(document).on('mousemove', function (event) {
if($('.col-3:hover').length != 0) {
const appendScale = 1
var destinationX = event.pageX;
var destinationY = event.pageY;
var transformScale = `translate(calc(${destinationX}px - 50%), calc(${destinationY}px - 50%)) scale(${appendScale})`
$('#cursor').css('transform', transformScale);
}
})
event.pageX should always give me the current mouse position of the $(document) and not of the event itself. Exactly the same for event.pageY. But I always get the current position of the event and I don't know why.
Can somebody help me please?
UPDATE:
However, the width of the cursor element hinders me because I get the coordinates of the $ (documents). The event is only triggered when I am outside the cursor.
Here is a screenshot and to clarify the problem:
I would like to have my own cursor only displayed over certain images with a certain class.
You can do that only with css,
.cursors {
display: flex;
justify-content: flex-start;
align-items: stretch;
height: 100vh;
}
.cursors > div {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
box-sizing: border-box;
padding: 10px 2px;
text-align: center;
}
.cursors > div:nth-child(odd) {
background: #eee;
}
.cursors > div:hover {
opacity: 0.25;
}
.png {
cursor: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/9632/heart.png"), auto;
}
.gif {
cursor: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/9632/happy.png"), auto;
}
.rotated {
transform: rotate(45deg); /* Equal to rotateZ(45deg) */
background-color: pink;
}
<div class="cursors">
<div><img class="png rotated"src="https://uxwing.com/wp-content/themes/uxwing/images/patreon_btn.png"/> </div>
<div class="gif">GIF</div>
</div>

z-index not working on Safari when manipulating it using Javascript

I am making a website that has multiple layers to it, which is brought back and forth by manipulating the z-index in Javascript through event reactions (like onclick). I have a navigation bar which has a large z-index value compared to every other element as I would like it to be at the very front regardless of anything. However, when run on Safari, the nav bar disappears from the get go, while it works fine on Google Chrome and FireFox.
I have included the css code and javascript code that dictates this role:
JAVASCRIPT:
//Global variables representing DOM elements
var introTitleElem = document.getElementById('introduction-title');
var resumeElem = document.getElementById('resume-container');
var introElem = document.getElementById('intro-content');
var eduElem = document.getElementById('edu-content');
//Layer tracker (for transition effect)
var prev = introElem;
var prevButton = "";
//Function that actually changes the layers
function changeLayer(layer, button) {
if (layer === prev) return;
introTitleElem.style.opacity = "0";
prev.style.zIndex = "40";
layer.style.zIndex = "50";
layer.style.cssText = "opacity: 1; transition: opacity 0.5s";
prev.style.zIndex = "5";
prev.style.opacity = "0";
prev = layer;
if (prevButton !== "") prevButton.style.textDecoration = "none";
button.style.textDecoration = "underline";
prevButton = button;
}
//Manages events triggered by name button toggle
function revealResume() {
introTitleElem.style.zIndex = "0";
resumeElem.style.zIndex = "10";
resumeElem.style.opacity = "1";
introElem.style.opacity = "1";
resumeElem.style.transition = "opacity 0.7s";
introElem.style.transition = "opacity 0.7s";
}
document.getElementById("name-title").addEventListener("click", revealResume);
//Manage z-index of different components of the resume and reveal them accordingly
$('#nav-education').click(function () {
onEducation = true;
changeLayer(eduElem, this);
});
CSS (SASS):
/*NAVIGATION STYLING*/
#fixed-nav {
align-self: flex-start;
overflow-x: hidden;
float: right;
z-index: 9999 !important;
display: flex;
margin: 1em;
li {
margin: 0.6em;
font: {
family: $font-plex-sans-condensed;
size: 0.8em;
}
text-align: center;
color: $lightest-grey;
transition: color 0.3s;
&:hover {
cursor: pointer;
color: $dark-grey;
transition: color 0.3s;
}
}
}
/*OVERALL DIV FORMATTING*/
.format-div {
width: 100vw;
height: 100vh;
display: flex;
position: absolute;
justify-content: center;
align-items: center;
flex-direction: column;
opacity: 0;
}
/*EDUCATION CONTENT STYLING*/
#edu-content {
background-color: $red-1;
}
HTML:
<div id="resume-container">
<ul id="fixed-nav">
<li id="nav-education">education.</li>
<li id="nav-experiences">experiences.</li>
<li id="nav-skills">skills.</li>
<li id="nav-projects">projects.</li>
<li id="nav-additional">additional.</li>
<li id="nav-contact">contact.</li>
</ul>
<div id="intro-content" class="format-div">
<h1 class="type-effect">
<h1>I'm Daniel <b>(Sang Don)</b> Joo</h1>
<span class="blinking-cursor">|</span>
</h1>
</div>
<div id="edu-content" class="format-div">
<h1>education</h1>
</div>
Sorry about the large amount of code but I'm really unsure of where this problem is rooted. Cheers!
it has to be the position feature of the elements so that it can work
wrong example ( not working )
.className { z-index: 99999 !important; }
correct example ( it work )
.className { position: 'relative'; z-index: 99999 !important; }
.className { position: 'absolute'; z-index: 99999 !important; }
etc..
good luck :)

how to increase speed of scrollmagic

Hey this is the plugin of Scrollmagic.io I am using this in my work.
But this is slow. How increase the duration time I want to change the content faster.
I looked at documentation but not much clear in docs.
Please help me out
//First the variables our app is going to use need to be declared
//References to DOM elements
var $window = $(window);
var $document = $(document);
//Only links that starts with #
var $navButtons = $("nav a").filter("[href^=#]");
var $navGoPrev = $(".go-prev");
var $navGoNext = $(".go-next");
var $slidesContainer = $(".slides-container");
var $slides = $(".slide");
var $currentSlide = $slides.first();
//Animating flag - is our app animating
var isAnimating = false;
//The height of the window
var pageHeight = $window.innerHeight();
//Key codes for up and down arrows on keyboard. We'll be using this to navigate change slides using the keyboard
var keyCodes = {
UP : 38,
DOWN: 40
}
//Going to the first slide
goToSlide($currentSlide);
/*
* Adding event listeners
* */
$window.on("resize", onResize).resize();
$window.on("mousewheel DOMMouseScroll", onMouseWheel);
$document.on("keydown", onKeyDown);
$navButtons.on("click", onNavButtonClick);
$navGoPrev.on("click", goToPrevSlide);
$navGoNext.on("click", goToNextSlide);
/*
* Internal functions
* */
/*
* When a button is clicked - first get the button href, and then slide to the container, if there's such a container
* */
function onNavButtonClick(event)
{
//The clicked button
var $button = $(this);
//The slide the button points to
var $slide = $($button.attr("href"));
//If the slide exists, we go to it
if($slide.length)
{
goToSlide($slide);
event.preventDefault();
}
}
/*
* Getting the pressed key. Only if it's up or down arrow, we go to prev or next slide and prevent default behaviour
* This way, if there's text input, the user is still able to fill it
* */
function onKeyDown(event)
{
var PRESSED_KEY = event.keyCode;
if(PRESSED_KEY == keyCodes.UP)
{
goToPrevSlide();
event.preventDefault();
}
else if(PRESSED_KEY == keyCodes.DOWN)
{
goToNextSlide();
event.preventDefault();
}
}
/*
* When user scrolls with the mouse, we have to change slides
* */
function onMouseWheel(event)
{
//Normalize event wheel delta
var delta = event.originalEvent.wheelDelta / 30 || -event.originalEvent.detail;
//If the user scrolled up, it goes to previous slide, otherwise - to next slide
if(delta < -1)
{
goToNextSlide();
}
else if(delta > 1)
{
goToPrevSlide();
}
event.preventDefault();
}
/*
* If there's a previous slide, slide to it
* */
function goToPrevSlide()
{
if($currentSlide.prev().length)
{
goToSlide($currentSlide.prev());
}
}
/*
* If there's a next slide, slide to it
* */
function goToNextSlide()
{
if($currentSlide.next().length)
{
goToSlide($currentSlide.next());
}
}
/*
* Actual transition between slides
* */
function goToSlide($slide)
{
//If the slides are not changing and there's such a slide
if(!isAnimating && $slide.length)
{
//setting animating flag to true
isAnimating = true;
$currentSlide = $slide;
//Sliding to current slide
TweenLite.to($slidesContainer, 1, {scrollTo: {y: pageHeight * $currentSlide.index() }, onComplete: onSlideChangeEnd, onCompleteScope: this});
//Animating menu items
TweenLite.to($navButtons.filter(".active"), 0.5, {className: "-=active"});
TweenLite.to($navButtons.filter("[href=#" + $currentSlide.attr("id") + "]"), 0.5, {className: "+=active"});
}
}
/*
* Once the sliding is finished, we need to restore "isAnimating" flag.
* You can also do other things in this function, such as changing page title
* */
function onSlideChangeEnd()
{
isAnimating = false;
}
/*
* When user resize it's browser we need to know the new height, so we can properly align the current slide
* */
function onResize(event)
{
//This will give us the new height of the window
var newPageHeight = $window.innerHeight();
/*
* If the new height is different from the old height ( the browser is resized vertically ), the slides are resized
* */
if(pageHeight !== newPageHeight)
{
pageHeight = newPageHeight;
//This can be done via CSS only, but fails into some old browsers, so I prefer to set height via JS
TweenLite.set([$slidesContainer, $slides], {height: pageHeight + "px"});
//The current slide should be always on the top
TweenLite.set($slidesContainer, {scrollTo: {y: pageHeight * $currentSlide.index() }});
}
}
body, div, p {
margin: 0;
padding: 0;
}
body {
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
font-weight: 300;
letter-spacing: 0.0625em;
}
a {
text-decoration: none;
}
nav {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 100;
}
nav ul {
list-style: none;
text-align: center;
margin-top: 30px;
}
nav ul li {
display: inline-block;
margin-right: 20px;
}
nav ul li:last-child {
margin-right: 0;
}
#back-to-tutorial {
margin-left: 100px;
}
nav a {
position: relative;
top: 0;
padding: 10px 20px;
font-weight: normal;
font-size: 20px;
text-align: center;
border-radius: 4px;
background-color: #FFFFFF;
color: #83C78E;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
nav a.active {
top: -4px;
background-color: #69C773;
color: #FFFFFF;
-webkit-box-shadow: 0 4px 0 0 #51a65f;
-moz-box-shadow: 0 4px 0 0 #51a65f;
box-shadow: 0 4px 0 0 #51a65f;
}
.slides-container {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: hidden;
z-index: 10;
}
.slide {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
}
.slide .centered {
width: 60%;
margin: 200px auto 0;
}
.slide .centered h1 {
text-align: center;
}
.slide .centered p {
text-align: center;
margin-top: 20px;
font-size: 20px;
}
#slide-1 {
background-color: #FFFFFF;
}
#slide-2 {
background-color: #45959b;
}
#slide-3 {
background-color: #778899;
}
#slide-4 {
color: #FFFFFF;
background-color: #291F37;
}
.go-prev, .go-next {
cursor: pointer;
font-weight: bold;
text-decoration: underline;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.11.6/TweenLite.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.11.6/plugins/CSSPlugin.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.11.6/plugins/ScrollToPlugin.min.js"></script>
<nav>
<ul>
<li>Slide 1</li>
<li>Slide 2</li>
<li>Slide 3</li>
<li>Slide 4</li>
</ul>
</nav>
<div class="slides-container">
<div class="slide" id="slide-1">
<div class="centered">
<h1>Fullscreen slides with GSAP</h1>
<p>Let's go to the <span class="go-next">next slide</span>.</p>
</div>
</div>
<div class="slide" id="slide-2">
<div class="centered">
<h1>It is so easy to navigate through slides</h1>
<p>You can go back to <span class="go-prev">previous slide</span> or go to the <span class="go-next">next slide</span>.</p>
</div>
</div>
<div class="slide" id="slide-3">
<div class="centered">
<h1>Use mouse wheel</h1>
<p>No, really. Try to scroll up and down with the mouse wheel to switch between slides.</p>
</div>
</div>
<div class="slide" id="slide-4">
<div class="centered">
<h1>... Or use keyboard arrows</h1>
<p>You go to previous and next slide, using up and down keyboard arrows.</p>
</div>
</div>
</div>
This is the link of scroll.io docs http://scrollmagic.io/docs/ScrollMagic.Scene.html#duration
How to apply this I bit confused please have a look
It's actually a TweenLite parameter: https://greensock.com/tweenlite
Change
TweenLite.to($slidesContainer, 1, {scrollTo: {y: pageHeight * $currentSlide.index() }, onComplete: onSlideChangeEnd, onCompleteScope: this});
To a lower value, e.g.:
TweenLite.to($slidesContainer, 0.2, {scrollTo: {y: pageHeight * $currentSlide.index() }, onComplete: onSlideChangeEnd, onCompleteScope: this});

Why overheating on scrolling with SVG effect

I create a SVG blur effect on my page sections. You can see in below snippet. However, my CPU is overloaded and overheating my laptop when I scroll several times. I check complex animation websites without this problem. What's my problem? Is there a problem with my codes?
$(window).on('load', function() {
$('.blurred-bg').each(function(index, value) {
var filterName = $(this).attr('id') + 'filtering';
$(this).prepend(
'<svg class="svgs" xmlns="http://www.w3.org/2000/svg" version="1.1" height="0"><filter id="' + filterName + '"><feGaussianBlur result="blur"></feGaussianBlur><feMorphology in="blur" operator="dilate" radius="15" result="expanded"/><feMerge><feMergeNode in="expanded"/><feMergeNode in="blur"/></feMerge></filter></svg>'
);
});
$(window).scroll(function(e) {
var distanceScrolled = $(this).scrollTop();
$('.blurred-bg').each(function(index, value) {
var distanceElementTop = ($(this).offset().top);
if (distanceScrolled < distanceElementTop) {
$(('svg.svgs filter feGaussianBlur'), this)[0].setAttribute("stdDeviation", '0');
} else if (distanceScrolled > distanceElementTop) {
var elmHeight = $(this).height();
var sub = elmHeight / 10;
var result = ((distanceScrolled - distanceElementTop) / sub);
if (result >= 0 && result <= 10) {
$(('svg.svgs filter feGaussianBlur'), this)[0].setAttribute("stdDeviation", result);
}
}
});
});
});
section {
position: relative;
width: 100%;
height: 100vh;
background-size: cover;
background-attachment: fixed;
background-repeat: no-repeat;
overflow-x: hidden;
overflow-y: auto;
}
section:before {
background: inherit;
bottom: 0;
content: '';
left: 0;
position: absolute;
right: 0;
top: 0;
}
#first {
background-image: url('https://freephotos.cc/storage/path/1Sujr0vCiT0cQpjbMgmdzAIjtdfEq2lF3bq4U1oo.jpeg');
}
#first:before {
-webkit-filter: url(#firstfiltering);
filter: url(#firstfiltering);
}
#two {
background-image: url('https://freephotos.cc/storage/path/c1haICnHGYIyRK2juLs36iEBoBiJMOarzSQ9CKRv.jpeg');
}
#two:before {
-webkit-filter: url(#twofiltering);
filter: url(#twofiltering);
}
#three {
background-image: url('https://freephotos.cc/storage/path/OpgzqCRPTnxQ5z22gNvNgiF7ZSTzNyPXtXKwVwS4.jpeg');
}
#three:before {
-webkit-filter: url(#threefiltering);
filter: url(#threefiltering);
}
.svgs,
.svg-section {
position: absolute;
width: 0;
height: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section id="first" class="blurred-bg"></section>
<section id="two" class="blurred-bg"></section>
<section id="three" class="blurred-bg"></section>
https://codepen.io/mehrdadam/pen/NyexLa
UPDATE:
I test this without SVG filter and remove jQuery and set blur filter for section. My CPU overloaded on view of blurred section!
Constantly recalcuating blurs is extremely CPU intensive. A better way to do this is to overlay a highly blurred, transparent copy of the image on top of the original and gradually increase its opacity as you scroll down.

How do you create 3 adjustable divs?

What I want:
| A | | B | | C |
^ ^
When you move the handles left and right A, B, and C resize accordingly
| A | | B | | C |
What I have is the || between B and C sliding, but not resizing B and all I get on the other one is the resize cursor. Basically C is a curtain and covers A and B. I did get min size working for C.
| A | C |
I broke somebody else's perfectly good code to get this far:
var isResizing = false,
who='',
lastDownX = 0;
$(function () {
var container = $('#container'),
left = $('#left'),
right = $('#right'),
middle = $('#middle'),
hand2 = $('#hand2'),
handle = $('#handle');
handle.on('mousedown', function (e) {
isResizing = true;
who=e.target.id;
lastDownX = e.clientX;
});
$(document).on('mousemove', function (e) {
var temp, min;
// we don't want to do anything if we aren't resizing.
if (!isResizing)
return;
min=container.width() * 0.1;
temp = container.width() - (e.clientX - container.offset().left);
if (temp < min)
temp = min;
if (who == 'handle')
right.css('width', temp);
if (who == 'hand2')
left.css('width', temp);
}).on('mouseup', function (e) {
// stop resizing
isResizing = false;
});
});
body, html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#container {
width: 100%;
height: 100%;
/* Disable selection so it doesn't get annoying when dragging. */
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: moz-none;
-ms-user-select: none;
user-select: none;
}
#container #left {
width: 40%;
height: 100%;
float: left;
background: red;
}
#container #middle {
margin-left: 40%;
height: 100%;
background: green;
}
#container #right {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 200px;
background: rgba(0, 0, 255, 0.90);
}
#container #handle {
position: absolute;
left: -4px;
top: 0;
bottom: 0;
width: 80px;
cursor: w-resize;
}
#container #hand2 {
position: absolute;
left: 39%;
top: 0;
bottom: 0;
width: 80px;
cursor: w-resize;
}
<div id="container">
<!-- Left side -->
<div id="left"> This is the left side's content!</div>
<!-- middle -->
<div id="middle">
<div id="hand2"></div> This is the middle content!
</div>
<!-- Right side -->
<div id="right">
<!-- Actual resize handle -->
<div id="handle"></div> This is the right side's content!
</div>
</div>
Been playing with it here: https://jsfiddle.net/ju9zb1he/5/
I was looking for a solution that required less extensive CSS. It does have one minor bug(FIXED), but hopefully this should get you started. Here is a DEMO.
Also I aimed to use DOM Traversal methods like .next() and .prev() that way it wouldn't be so attribute dependent, and would be easily reusable if you needed a feature like this multiple times on a page.
Edit - Further Explanation
The idea here is onClick of a .handle we want to gather the total width (var tWidth) of the .prev() and .next() divs relative to the .handle in the DOM. We can then use the start mouse position (var sPos) to substract the amount of pixels we've moved our mouse (e.pageX). Doing so gives us the correct width that the .prev() div should have on mousemove. To get the width of the .next() div we need only to subtract the width of the .prev() div from the total width (var tWidth) that we stored onClick of the .handle. Hope this helps! Let me know if you have any further questions, however I will likely be unavailable till tomorrow.
HTML
<div class="container">
<div id="left"></div>
<div id="l-handle" class="handle"></div>
<div id="middle"></div>
<div id="r-handle" class="handle"></div>
<div id="right"></div>
</div>
CSS
#left, #middle, #right {
display: inline-block;
background: #e5e5e5;
min-height: 200px;
margin: 0px;
}
#l-handle, #r-handle {
display: inline-block;
background: #000;
width: 2px;
min-height: 200px;
cursor: col-resize;
margin: 0px;
}
jQuery
var isDragging = false,
cWidth = $('.container').width(),
sPos,
handle,
tWidth;
$('#left, #middle, #right').width((cWidth / 3) - 7); // Set the initial width of content sections
$('.handle').on('mousedown', function(e){
isDragging = true;
sPos = e.pageX;
handle = $(this);
tWidth = handle.prev().width() + handle.next().width();
});
$(window).on('mouseup', function(e){
isDragging = false;
});
$('.container').on('mousemove', function(e){
if(isDragging){ // Added an additional condition here below
var cPos = sPos - e.pageX;
handle.prev().width((tWidth / 2) - cPos); // This was part of the bug...
handle.next().width(tWidth - handle.prev().width());
// Added an update to sPos here below
}
});
Edit
The bug was caused by 2 things.
1) On mousemove we were dividing the total width by two, instead of an updated mouse offset.
2) The sPos was not updating on mousemove, and stayed a static number based off of the click location.
Resolution
Update the sPos on mousemove that way the mouse offset is accurately based off of the previous mousemove position, rather than the click position. When this is done we can then subtract the .next() div's width from the total width. Then we subtract our current mouse position from the remaining width. The fiddle has been updated as well.
$('.container').on('mousemove', function(e){
var cPos = sPos - e.pageX;
if(isDragging && ((tWidth - handle.next().width()) - cPos) <= tWidth){
handle.prev().width((tWidth - handle.next().width()) - cPos);
handle.next().width(tWidth - handle.prev().width());
sPos = e.pageX;
}
});
Edit
Added an additional condition on mousemove to prevent the drag from exceeding the total width (var tWidth).
Can you please explain what you're trying to accomplish?
I don't believe you need to use position: absolute. The premise of absolute positioning is to override the margin and padding imposed on an element by its parent.
You don't need to do this, all elements have relative positioning by default which makes them push eachother around and don't allow overlapping.
I'm probably missing something, but I think this is what you want with nothing but some very basic CSS: http://jsfiddle.net/3bdoazpk/
<div class='first'>
asdf
</div><div class='second'>
dasdf
</div><div class='third'>
sadf
</div>
body {
margin: 0;
}
div {
display: inline-block;
height: 100%;
}
.first, .third {
width: 40%;
}
.first {
background-color: red;
}
.second {
background-color: blue;
width: 20%;
}
.third {
background-color: green;
}

Categories

Resources