cameronmcefee / plax

JQuery powered parallaxing
http://www.cameronmcefee.com/plax
MIT License
2.28k stars 206 forks source link

Plax Responsive-ness #39

Closed jaredrethman closed 11 years ago

jaredrethman commented 11 years ago

Hi Cameron,

Firstly, what a champion plugin, possibly one of my favorite jQuery plugins. I am currently building my portfolio, implementing your plugin. And everything is going great.

This isn't as much of an issue as it is rather a request on some advise.

I'm trying to make the site responsive using css mediaqueries, but struggled to get the layers to update on resize() - I managed to get it to work when refreshed on an already resized window. But wanted to get it to work dynamically/instantly while resizing... anyway long story short...

I managed to achieve this by passing a function to on resize event - like so...

function disablePlax(){ $.plax.disable({ "clearLayers": true }) $('img.js-plaxify[style]').css('top', ''); $('img.js-plaxify[style]').css('left', ''); $('div.js-plaxify[style]').css('top', ''); $('div.js-plaxify[style]').css('left', ''); }

and then start it up again, by calling the same function(s) called in document ready, like this:

function enablePlax(){ var layers = $('.js-plaxify') $.each(layers, function(index, layer){ $(layer).plaxify({ xRange: $(layer).data('xrange') || 0, yRange: $(layer).data('yrange') || 0, invert: $(layer).data('invert') || false }) })

    $.plax.enable();

}

I am a complete noob to jQuery, and am not sure if this is the best way to handle this sort of thing, but wanted to know if there was a better way of doing this. Or is it a case of "Don't fix if its not broken"?

Thanks again for Plax

cameronmcefee commented 11 years ago

Hi @Lawless55,

What you want to do definitely possible. There are two avenues you can choose, depending on the desired result

1. I want to reposition the plax illustration, but the ranges and element position can stay the same

If you're not rescaling the ranges, simply trying to move the whole plaxed illustration around, all it takes is a wrapper div. All of plax's elements are absolutely positioned, so all you would need to do is put them in a div is position:relative or position:absolute. Then in your mediaquery specific code, you just move the wrapper div around and plax will follow.

2. You want to change the ranges

If you need to actually change the distance elements travel or where they travel from this is possible, but a little more work.

First, because of the amount of calculation that happens, I'd avoid changing plax directly on resize(), since this event continually fires until you stop resizing. You could try it out on resize(), but I'm not sure what to expect. Stuff may jump around or your browser may burst into flames.

Essentially all you need to do is replaxify your element. Check out this example from the docs:

$('#plax-octocat').plaxify({"xRange":40,"yRange":40})
$('#plax-earth').plaxify({"xRange":20,"yRange":20,"invert":true})
$('#plax-bg').plaxify({"xRange":10,"yRange":10,"invert":true})
$.plax.enable()

$('#my-btn').click(function(){
  // bigger range
  $('#plax-octocat').plaxify({"xRange":200,"yRange":200})
})

On the click, it just specifies the range for #plax-octocat again. Plax will just drop the old range and use the new one.

Since you're doing responsive stuff (something plax technically wasn't designed for) and the xy coordinates for where your elements need to start from are likely to change, you may need to have something in there that works like this pseudo code

on resize complete do:
  disable plax
  clear all plax element inline css
  reposition plax elements to their new base positions
  replaxify your elements with new preferred ranges
  enable plax again

This may seem like a lot of work to do for something simple like resizing, but keep in mind, mediaqueries are mostly intended for different device sizes, and not so much browser resizing (which doesn't happen all that often). Chances are, this won't happen more than once on a page.

jaredrethman commented 11 years ago

Hey @cameronmcefee

Thanks a mill for getting back to me.

Almost exactly "point for point" how you described it above is how i tried to tackle this. But i kept running into issues, for instance i was attaching the invert, x, yRange(s) to the elements like on the 404 github page, i didn't know how to (Cause i'm such a noob) update the elements when resized. So i eventually had success doing it the way you mentioned step for step, in the above two functions and then running this resize() function below, so it didn't set my computer alight :)

$(window).resize(function() { disablePlax(); if (plaxDisabled) clearTimeout(plaxDisabled); plaxDisabled = setTimeout(function() { enablePlax(); }, 20); });

And it seamed to do the trick, it shudders a bit - but it works. Thanks again for Plax and your help mate.

The support for accelerometer is what sold it for me, so with a couple of hacks, it can also be responsive :) . Also i did try using the update from - https://github.com/cameronmcefee/plax/pull/36, but it through an error and froze every time on my Galaxy note 10.1 - but i think that has something to do with another plugin i'm using... not sure, maybe if its cool i could send you the finished product and you could let me know what you think about how I've implemented your code?

cameronmcefee commented 11 years ago

There isn't a built in resizestop event, so you'd have to write something on your own or grab a plugin. Since you're using jQuery, this looks like it might do the trick. https://github.com/misteroneill/resize-stop

Just be sure it loads after jQuery and before Plax.

jaredrethman commented 11 years ago

The reason i needed to use the resize event like this is that i needed to run disablePlax(); while/during the resize event and then once complete then start Plax up again - enablePlax();. Not sure, as i said, i'm still learning :)

vbk commented 11 years ago

@Lawless55

Could you tell me if you are able to responsify? Please let me know how you achieved it and provide me the code if possible.

Thanks!

jaredrethman commented 11 years ago

Hey VBK,

What I did was create two sets of data objects on each div, like so.

"<"div class="js-plaxify" data-xrangesml="25" data-yrangesml="35" data-xrangelrg="50" data-yrangelrg="70" id="parallax_ele">"

Then I created three separate functions, one for each data object size (Small and large) and one to disable and clear all Plax'd elements.

For Desktop: function enableDeskPlax(){ var layers = $('.js-plaxify') var plaxDesk = $.each(layers, function(index, layer){ $(layer).plaxify({ xRange: $(layer).data('xrangelrg') || 0, yRange: $(layer).data('yrangelrg') || 0, invert: $(layer).data('invert') || false }) }) $.plax.enable(); }

For Mobile: function enableMobiPlax(){ var layers = $('.js-plaxify') var plaxMobi = $.each(layers, function(index, layer){ $(layer).plaxify({ xRange: $(layer).data('xrangesml') || 0, yRange: $(layer).data('yrangesml') || 0, invert: $(layer).data('invert') || false }) }) $.plax.enable(); }

Clearing function: function disablePlax(){ $.plax.disable({ "clearLayers": true }) $('div.js-plaxify[style]').css('top', ''); //use jQuery to clear all inline styles generated by Plax $('div.js-plaxify[style]').css('left', ''); //use jQuery to clear all inline styles generated by Plax }

Then I setup a function that gets run through on load and on resize();

function resizeShit() { disablePlax(); //Start by clearing Plax, especially for resize() var windowSize = $(window).width(); if (windowSize < 769){ enableMobiPlax();
} else { enableDeskPlax(); } }

I would suggest using something like the debounce resize method, or Camerons above mentioned plugin to do your resizing, otherwise each of those calls gets fired a gizilian times and your "browser might burst into flames".

Also you will need to use Media Queries to swap out the background images, in conjunction with something like respond.js for cross browser support And you will need to size down the wrapper on each iteration too.

Lastly, I haven't had good luck with the later versions of plax the earlier versions have worked better for me.

Hope this helps.

vbk commented 11 years ago

Thank you!

Dwtbc commented 11 years ago

Hello Lawless55

I tried your code but I can't seem to get it working.

When I use your code, the PLAX effect gets turned off.

Have you got a demo of what you've made?

Daniel

jaredrethman commented 11 years ago

Sorry mate, its my portfolio... and i have put it on hold until i get some more free time :)

You need to make sure you run either enableDeskPlax() or enableMobiPlax() onResize. I would suggest putting in a console.log("Plax Enabled"); into both functions and check the console to see if they get called.

Could you post your code to have a look.

xaolas commented 9 years ago

Its work on resize:

    $('.forest__man, .forest__lens').plaxify();
    $.plax.enable();

    $(window).resize(function() {
        $('.forest__man, .forest__lens').removeAttr('style');
    });