I'm using Locomotive Scroll on a website. What i try to achieve is the following : when a section with the id #mysection is in the viewport, i'd like an icon to appear, then disappear when the section is out of the viewport.
I've tried searching in the docs and on the web ways to achieve this, but i can't figure out how to make it work. Right now, i've seen that you can launch events in the docs by using the following :
<!-- Using jQuery events -->
<div data-scroll data-scroll-call="EVENT_NAME">Trigger</div>
then in the javascript file :
import LocomotiveScroll from 'locomotive-scroll';
const scroll = new LocomotiveScroll();
scroll.on('call', func => {
// Using modularJS
this.call(...func);
// Using jQuery events
$(document).trigger(func);
// Or do it your own way 😎
});
So what i did is the following :
let serviceWebDigital;
let serviceGraphicDesign;
let serviceMarketing;
let serviceVideoMotion;
smoothScroll.on("call", (value, way, obj) => {
if (value === "serviceWebDigital") {
serviceWebDigital = TweenMax.to($(".arrow-service-1"), 1, { opacity: 1 });
} else {
serviceWebDigital = TweenMax.to($(".arrow-service-1"), 1, { opacity: 0 });
}
if (value === "serviceGraphicDesign") {
serviceGraphicDesign = TweenMax.to($(".arrow-service-2"), 1, { opacity: 1 });
} else {
serviceGraphicDesign = TweenMax.to($(".arrow-service-2"), 1, { opacity: 0 });
}
if (value === "serviceMarketing") {
serviceMarketing = TweenMax.to($(".arrow-service-3"), 1, { opacity: 1 });
} else {
serviceMarketing = TweenMax.to($(".arrow-service-3"), 1, { opacity: 0 });
}
if (value === "serviceVideoMotion") {
serviceVideoMotion = TweenMax.to($(".arrow-service-4"), 1, { opacity: 1 });
} else {
serviceVideoMotion = TweenMax.to($(".arrow-service-4"), 1, { opacity: 0 });
}
});
My issue is that when the elements enter in the viewport, the arrows appears fine. But when i scroll down then up, the arrows don't appear no more when the sections enter in the viewport. What am i missing?
Another issue is that i'd like to control when the elements appear. Right now, they appear right when the div elements enter the bottom of the viewport. Is there a way to create some "delay"? So they appear when the element is fully in the viewport for example?
EDIT :
When looking at the live code, it appears that the class that is added by locomotive is-inview when elements enter the viewport doesn't disappear when the element is out of view. That might be part of the issue here..
To quickly answer the questions about the "is-inview" class not being removed, you need to include the "data-scroll-repeat" attribute to the element.
eg: <div data-scroll data-scroll-repeat>content</div>
Regarding controlling when it triggers, I'd look at the data-scroll-offset="?, ?"
In the docs is says the 1st is bottom (when the elements enters) and 2nd is top (when the element exits). Can be a number for pixels or a percentage.
Hope that helps for part of your question at least.
Related
So I want to add a function that when I click a div it moves, but when I click something else it moves back to its original position, I want to use gsap here too. I tried using an if else statement but I didn't know want to put in here(The part where there is two stars):
let btnSide1 = document.querySelector('.button-side-one'),
btnSide2 = document.querySelector('.button-side-two'),
btnTop = document.querySelector('.button-top'),
btnBig = document.querySelector('.button-big');
if (btnSide1 = **active**) {
gsap.to(btnSide1, .5, { x: 3 })
} else {
gsap.to(btnSide1, .5, { x: 0 })
}
here is the codepen link for this: https://codepen.io/sowg/pen/GRvQxpN
I figured this out I used toggle class list for this,
Here is how it works:
// Variables
btnSide1.onclick = function () {
btnSide1.classList.toggle("activex1");
};
.activex1 { left: 30vmin !important }
So when I click on the div it moves position
You have a typo.
if (btnSide1 === active)
Need to scroll to bottom automatically once messages are being added in a chat.
Tried AfterViewChecked method of implementing this, as suggessted in
[angular2 scroll to bottom (chat style) - It works fine as it makes the scroll move to bottom. But when we try scrolling up as soon as we add a message in the chat, it is not allowing and it again pushes the view to the bottom of the chat
Please suggest a workaround on this.
The below code worked for me for my angular 4 chat application
My component.html
<div class="feedBody" #scrollMe (scroll)="onScroll()" >
<div class="feedList">
</div>
</div>
My component.css
.feedBody {
height: 235px;
overflow-y: auto;
}
My component.ts
scrollToBottom():void{
if (this.disableScrollDown) {
return
}
try {
this.myScrollContainer.nativeElement.scrollTop = this.myScrollContainer.nativeElement.scrollHeight;
} catch(err) { }
}
onScroll(){
let element = this.myScrollContainer.nativeElement;
let atBottom = (element.scrollTop+200) >= (element.scrollHeight - element.offsetHeight);
if (atBottom) {
this.disableScrollDown = false
} else {
this.disableScrollDown = true
}
}
I was using element.scrollTop+200 because I wanted a behaviour where I should not compulsorily present at the bottom of the screen but can be a little top by 200px.
Hope it works for you.
I am trying to replicate the scrolling effect from here: http://www.altisliferpg.com/
I have a feeling that they are using a heavily modified version of Bootstrap Navbar, which I have taken from here: http://www.enjin.com/forums/page/1/m/10826/viewthread/8514993-boot-strap-30-navbar-full-module and have changed it to fit into my specific case.
How would I make it so when you scroll down the page, the bar on the top gets "smaller" and scrolls along with the page as you scroll? Thanks
You can use css transitions for the height, font size and whatever else you want changed. Then simply set a scroll listener, which adds a class to the header so the size changes. Quick (and very ugly) example. jsFiddle
$(window).scroll(function () {
if ($(this).scrollTop()) {
$('#header').addClass('small');
}
else {
$('#header').removeClass('small');
}
});
Maybe you should detect the scroll event of the window, after that, set the position of the navbar to fixed and then, perform the animation. Here's an example of the javascript part and a link see it in action:
$(function(){
var performingDownAnimation = false,
performingUpAnimation = false;
var performScroll = function(){
if($("body").scrollTop() > 0) {
if(performingUpAnimation) {
$('#logo').stop();
performingUpAnimation = false;
}
if(!performingDownAnimation){
$('#navbar').addClass('navbar-fixed');
$('#logo').animate({ 'font-size': "12px" }, 1000, function(){
performingDownAnimation = false;
});
performingDownAnimation = true;
}
}else if($("body").scrollTop() == 0){
if(performingDownAnimation) {
$('#logo').stop();
performingDownAnimation = false;
}
if(!performingUpAnimation){
$('#navbar').removeClass('navbar-fixed');
$('#logo').animate({ 'font-size': "48px" }, 1000, function(){
performingUpAnimation = false;
});
performingUpAnimation = true;
}
}
}
$(document).on('scroll', performScroll);
});
On scroll event and position fixed
I edited my response for adding support for the "up" direction too. About using bootstrap for the animation, I have no idea how to do it, and I think it can't be done, because bootstrap is based mainly on applying CSS classes to different elements. CSS classes are discrete, but you are asking for animating something numerical, as the font-size property is. As much, you could create an animation that looks "staggered".
I try to use jQuery visible plugin to detect if an element is or isn't visible in the viewport. I use a code like this:
animateFrontPage: function(){
var apps = 0;
if($('#apps-shelf').visible(true)) {
apps = 1;
if(apps == 1) {
$('#apps-shelf li').velocity("transition.bounceUpIn", { stagger: 150 });
apps = 0
}
}
}
and I run it with scroll function:
$(window).scroll(function() {
Functions.animateFrontPage();
});
The problem is - animation repeats itself with every scroll. What can I do to prevent it?
If you only want the animation to show once, what you could do is add a class to the element to flag that it is finished - then each time you only carry out the animation if the element does not have this class. Perhaps something along these lines :
animateFrontPage: function(){
var $el = $('#apps-shelf');
if($el.visible(true) && !$el.hasClass('finished')) {
$el.addClass('finished');
$el.find('li').velocity("transition.bounceUpIn", { stagger: 150 });
}
}
Update
This is the else statement you need if you want the other animation to run on these conditions : a) the animation of the first element $('#apps-shelf') has already happened and b) the element $('#apps-shelf') is no longer visible on the screen (you have scrolled past it for example)
animateFrontPage: function(){
var $el = $('#apps-shelf');
if($el.visible(true) && !$el.hasClass('finished')) {
$el.addClass('finished');
$el.find('li').velocity("transition.bounceUpIn", { stagger: 150 });
} else if (!$el.visible(true) && $el.hasClass('finished')){
//other animation here
}
}
I made a simple content/box slider which uses the following javascript:
$('#left').click(function () {
$('#videos').animate({
marginLeft: '-=800px'
}, 500);
});
$('#right').click(function () {
$('#videos').animate({
marginLeft: '+=800px'
}, 500);
});
Here is the demo: http://jsfiddle.net/tjset/2/
What I want to do and I can't figure out how to show and hide arrows(left and right box) as the all the boxes slided.
So I clicked 4 time to the LEFT and slided all the boxes! then hide "left" so that you can't give more -800px
What can I do?
What you can do is check after the animation completes to see if the margin-left property is smaller or larger than the bounds of the video <div>. If it is, depending on which navigation button was clicked, hide the appropriate navigation link.
Check out the code below:
$('#left').click(function () {
// reset the #right navigation button to show
$('#right').show();
$('#videos').animate({
marginLeft: '-=800px'
}, 500, 'linear', function(){
// grab the margin-left property
var mLeft = parseInt($('#videos').css('marginLeft'));
// store the width of the #video div
// invert the number since the margin left is a negative value
var videoWidth = $('#videos').width() * -1;
// if the left margin that is set is less than the videoWidth var,
// hide the #left navigation. Otherwise, keep it shown
if(mLeft < videoWidth){
$('#left').hide();
} else {
$('#left').show();
}
});
});
// do similar things if the right button is clicked
$('#right').click(function () {
$('#left').show();
$('#videos').animate({
marginLeft: '+=800px'
}, 500, 'linear', function(){
var mRight = parseInt($('#videos').css('marginLeft'));
if(mRight > 100){
$('#right').hide();
} else {
$('#right').show();
}
});
});
Check out the jsfiddle:
http://jsfiddle.net/dnVYW/1/
There are many jQuery plugins for this. First determine how many results there are, then determine how many you want visible, then use another variable to keep track with how many are hidden to the left and how many are hidden to the right. So...
var total = TOTAL_RESULTS;
var leftScrolled = 0;
var rightScrolled = total - 3; // minus 3, since you want 3 displayed at a time.
instead of using marginLeft I would wrap all of these inside of a wrapper and set the positions to absolute. Then animate using "left" property or "right". There's a lot of code required to do this, well not MUCH, but since there are many plugins, I think you'd be better off searching jquery.com for a plugin and look for examples on how to do this. marginLeft is just not the way to go, since it can cause many viewing problems depending on what version of browser you are using.