Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Child fixed container & smooth scrolling section container #58

Open
atwaves opened this issue Feb 16, 2017 · 12 comments
Open

Child fixed container & smooth scrolling section container #58

atwaves opened this issue Feb 16, 2017 · 12 comments

Comments

@atwaves
Copy link

atwaves commented Feb 16, 2017

Hi. How to make child container fixed relative to window? Smooth scrolling container also is fixed.
And additionally: how to use listener?

this.smooth = new Smooth({
            extends: false,
            // when hide scrollbar
            native: false,
            // when hide scrollbar
            noscrollbar: true,
            section: container,
            ease: 0.15,
            preload: true,
            listener: function(){

                console.log("listen")
            }
           
        })

this.smooth.init()
  • no logs
@baptistebriel
Copy link
Owner

Hi @atwaves,

You'd like to have a fixed element inside the section?
Here's some options you could try:

  1. Add this fixed element outside of the smooth-scrolling container.
  2. Apply negative transform to the element in the run function of the extended class (see below).

From what I see, you're not extending the base class but directly using the default class Smooth.
If you want to do custom transforms, you'd have to extend the Smooth class just like in the demos. For example:

import Smooth from 'smooth-scrolling'

export default class Custom extends Smooth {

    constructor(opt) {

        super(opt)
        
        // pass extra HTMLElement to the options object
        // and save them into the dom object of your Smooth instance
        this.dom.section = opt.section
        this.dom.child = opt.child
    }

    run() {

        super.run()
       
        // apply double transform to achieve a fixed position effect on the child element
        this.dom.child.style[this.prefix] = this.getTransform(this.vars.current.toFixed(2))
        this.dom.section.style[this.prefix] = this.getTransform(-this.vars.current.toFixed(2))
    }

    resize() {

        // you will need to set this.vars.bounding again in the extended class
        // just in case you want a different value for the scrolling bound
        this.vars.bounding = this.dom.section.getBoundingClientRect().height - this.vars.height
        super.resize()
    }
}
import Custom from '../smooth/custom'

const container = document.querySelector('.vs-container')
const child = document.querySelector('.vs-child')

this.smooth = new Smooth({
    native: false,
    noscrollbar: true,
    section: container,
    child: child,
    ease: 0.15,
    preload: true
})

this.smooth.init()

I would just try to do the first option if you can (moving the fixed child element outside of the section) so you don't have to apply another transform.

The listener option is not a function, but a DOM node like an HTMLElement.
It will be used to attach event listeners like scroll for desktop and touch for devices.
By default, the listener element is document.body. Useful if you want to do a scrolling sidebar where it would not scroll if your mouse if outside of that element.

Also, you don't need to pass in extends to the options as it'll just look if it's an extended class of Smooth or if you're just using the base class (see #17).

Let me know if that helps!

@atwaves
Copy link
Author

atwaves commented Feb 17, 2017

don't work

I would just try to do the first option if you can (moving the fixed child element outside of the section) so you don't have to apply another transform.

I use react for rendering, this step will break dom constructing methodology

@baptistebriel
Copy link
Owner

Did you tried the second option then?

@atwaves
Copy link
Author

atwaves commented Feb 17, 2017

Yes, I did. No effect

@baptistebriel
Copy link
Owner

Does the .vs-child element gets transforms applied to it?
I'd be glad to help if you send a demo/codepen example.

Let me know!

@atwaves
Copy link
Author

atwaves commented Feb 17, 2017

No transforms applied, I will write clear example tomorrow. Thank you for support

@baptistebriel
Copy link
Owner

No problem!

@23d1
Copy link

23d1 commented Jul 13, 2018

Hey guys, I would love to find out if anyone sorted this out. Looking to apply reversed transform to a child element for a sticky feel, and can't pull it out of the container, for visual purposes (elements passing in front of an below).

@baptistebriel
Copy link
Owner

Hi @23d1, would you be able to create a CodePen example of what you currently have? Let me know!

@baptistebriel baptistebriel reopened this Jul 13, 2018
@23d1
Copy link

23d1 commented Jul 13, 2018

Hey @baptistebriel,

Unfortunately not, but here's my exact setup (as it relates to smooth-scrolling) in webpack;

import Smooth from 'smooth-scrolling'

export default class Sticky extends Smooth {
    constructor(opt) {
        super(opt)

        this.dom.section = opt.section
        this.dom.sticky = opt.sticky
    }

    run() {
        super.run()

        this.dom.sticky.style[this.prefix] = this.getTransform(this.vars.current.toFixed(2))
        this.dom.section.style[this.prefix] = this.getTransform(-this.vars.current.toFixed(2))
    }

    resize() {
        this.vars.bounding = this.dom.section.getBoundingClientRect().height - this.vars.height
        super.resize()
    }
}

const sticky = document.querySelectorAll('.vs-sticky')

const smooth = new Smooth({
    native: true,
    sticky: sticky,
    ease: 0.1
})
smooth.init();

It doesn't apply any transform inline styles to the .vs-sticky element(s).

As a side note, I also have to add the smooth.init() into a setTimeout callback to make sure it captures all the content (typically skips a footer when setting the initial height of the .vs-scroll-view element on init).

@baptistebriel
Copy link
Owner

Hello @23d1

Do you mean no transform at all is applied to .vs-sticky? Also, are you trying to apply a transform to a single element or is there multiple elements with the class .vs-sticky?

If you're trying to apply a transform to a single element, use document.querySelector('.vs-sticky').
If there is multiple elements, you'll have to create an array using something like Array.from(document.querySelectorAll('.vs-sticky')) and passing this array in the options.
Once in the run() function, loop through all the elements and apply a transform for each one of them.

this.dom.sticky.forEach((el) => {
  el.style[this.prefix] = this.getTransform(this.vars.current.toFixed(2))
})

Using a setTimeout is usually because your content height gets updated after all resize calculations have been made with smooth-scrolling. Check if there is any images that might take some time to load. You can try using preload: true in the options and it will call resize() after the last image in the container has been loaded.

@23d1
Copy link

23d1 commented Jul 18, 2018

@baptistebriel I couldn't for the life of me get that to work, any chance you could help me with a codepen or something? It's a much nicer solution, albeit "heavier" then what I ended up going with, which was simply getting the callback (but that only works for one direction right now, and could get convoluted pretty quickly when adding other directions... right?)...

This is where I'm at now;

callback: function(val) {
    sticky.forEach(function(elem) {
        elem.style.transform = 'translate3d(0, ' + val + 'px, 0)';
    })
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants