3

I have a wrapper called #mousearea and I have a div called #mouseshift what I would like to do is when I hover over #mousearea I would like to shift the translate3d(0,230%,0) value between a particular range.

I have got the mousemove working but I currently end up with something like translate3d(7881%,230%,0) it's just too sensetive I would like it to translate the X co-ordinate between something like 0-60% so it's far more subtle.

Here is what I have so far:

jQuery(document).ready(function($){
    $('#mousearea').mousemove(function (e) {

        var shiftAmount = 1;

        $('#mouseshift').css(
            'transform', 'rotate(90deg) translate3d(' + -e.pageY + shiftAmount + '%,230%,0)'
        );
    });
});

Update:

This is a little closer, except it logs the correct translate3d but doesn't apply it to #mouseshift.

$('#mousearea').mousemove(function(e){
        var x = e.pageY - this.offsetTop;
        var transfromPosition = 'translate3d(' + x + ', 230%, 0)';
        console.log(transfromPosition);

        if ((x <= 800)) {
            //$('#mouseshift').css({'top': x});
            $('#mouseshift').css('transform', transfromPosition);
        }
    });

Final Solution:

jQuery(document).ready(function($){

    $('#mousearea').mousemove(function(e){

        var min = 50;
        var max = 70;

        var x = e.pageY;
        var windowHeight = window.innerHeight;

        scrolled = (x / windowHeight);
        percentageScrolled = scrolled * 100;

        offsetScroll = max - min;
        offsetPercentage = scrolled * 20;
        translateX = min + offsetPercentage;


        console.log(x + 'px');
        console.log(windowHeight + 'px window height');
        console.log(percentageScrolled + '% scrolled');
        console.log(offsetScroll + 'offset scroll');
        console.log(offsetPercentage + '% offset percentage');




        var transfromPosition = 'rotate(90deg) translate3d(' + translateX + '%, 230%, 0)';
        $('#mouseshift h1').css('transform', transfromPosition);
    });

});

Convert to a reusable plugin I would like to extend this to work with more than one object now and each object would have a different max and min value:

This is what I have but it seems to effect all the items on only use on elements max and min.

$(function () {
    $('#mouseshift-1, #mouseshift-2').mouseShift();
});    
(function ($) {
    $.fn.mouseShift = function () {
        return this.each(function () {
            var myEl = $(this);
            var min = $(this).data('min');
            var max = $(this).data('max');

            $('#mousearea').mousemove(function (e) {
                var yPosition = e.pageY;
                var windowHeight = window.innerHeight;

                scrolled = (yPosition / windowHeight);
                //percentageScrolled = scrolled * 100;
                offsetRange = max - min;
                offsetRangePercentage = scrolled * 20;
                offset = min + offsetRangePercentage;

                ////  Debug
                console.log('max: ' + max + ', Min:' + min);
                console.log(yPosition + 'px');
                console.log(windowHeight + 'px window height');
                //console.log(percentageScrolled + '% scrolled');
                console.log(offsetRange + 'px offset scroll');
                console.log(offsetRangePercentage + '% offset percentage');

                var transfromPosition = 'rotate(90deg) translate3d(' + offset + '%, 230%, 0)';
                myEl.css('transform', transfromPosition);
            });
        });
    };
})(jQuery);

And some HTML for clarity:

<div class="column"><h1 id="mouseshift-1" data-min="50" data-max="70">boo</h1></div>
      <div class="column"><h1 id="mouseshift-2" data-min="20" data-max="90">bah</h1></div>
      <div class="column"><h1 id="mouseshift-3" data-min="80" data-max="100">bing</h1></div>
Daimz
  • 3,243
  • 14
  • 49
  • 76
  • I don't know what your maximum mouseposition is, but you could simply do `x / window.innerWidth * 60` to get a number between 0 and 60. The only thing I don't know is what `width` it should be, so `window.innerWidth` might need to be replaced by something else... – somethinghere Mar 07 '16 at 13:27

2 Answers2

4

I think what you are looking for is finding an average that your can distribute. The best way to do this is to divide by the maximum amount it can move, and multiply it by the maximum value it can have, so basically:

position / maxposition * maxvalue

The first bit will return a number between 0 and 1, while the last bit will make it the value between 0 and 60. Below I have built a simply (jquery-less) version of it to show how this would work:

var mousePointer = document.getElementById('test')

document.addEventListener('mousemove', function(e){
  var x = e.pageX / window.innerHeight;
      x = x * -60;
  mousePointer.style.webkitTransform = 'translateX(' + x + '%)';
  mousePointer.style.transform = 'translateX(' + x + '%)';
})
#test {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 20px;
  height: 20px;
  background: red;
}
<div id="test"></div>

Update: Reusable Snippet

I don't really like using jQuery, so once again it will be vanilla javascript (but it's pretty simple). Is that what you were - sort of - trying to do with the reusable plugin?

var divs = Array.prototype.slice.call(document.querySelectorAll('[data-range]'));

document.addEventListener('mousemove', function(e){
  
  var eased = e.pageX / window.innerWidth;
  
  divs.forEach(function(div){
    
    var range = div.getAttribute('data-range').split(',');
    var min = parseFloat(range[0]);
    var max = parseFloat(range[1]);
    
    var ease = min + (eased * (max - min));
    
    div.style.webkitTransform = 'translateX(' + ease + '%)';
    div.style.transform = 'translateX(' + ease + '%)';
    
  });
  
});
div {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 200px;
  height: 200px;
  background: gray;
}

#d2 { background: yellow; }
#d3 { background: #666; }
<div data-range="60,70" id="d1"></div>
<div data-range="-70,70" id="d2"></div>
<div data-range="-60,-70" id="d3"></div>
somethinghere
  • 16,311
  • 2
  • 28
  • 42
  • I took what you suggested but instead found what the percentage of the screen scrolled and then worked out the difference between my maximum and minimum values `(70 - 50) = 20` multiplied that by the scrolled % and then added that to my minimum value. So now I can shift the translate % with in a particular range. Thanks for the help! I posted my final solution above, any further suggestions most welcome. – Daimz Mar 08 '16 at 10:30
  • @Daimz Congrats, this is basically how easing works in general :) If you want to add a bit of extra pizzaz, use `Math.pow()` on thre value between 0 and 1 and it will give you some cool values on a curve! – somethinghere Mar 08 '16 at 10:31
  • I took a slightly different path and decided to try my hand at turning it into a reusable plugin that I could set a max and min for each object and they could move independently at different rates, but I hit a snag, I posted my code above in the hope you might be able to help even though I realise it's probably out of the scope of the question, that said it does build on the original question :) – Daimz Mar 08 '16 at 11:22
  • @Daimz I've added a 'resuable' snippet to my answer above, I hope it helps. These can move independently at different rates defined in the `data-range` attribute. – somethinghere Mar 08 '16 at 13:12
2

From simple reading, I see that you're missing a % sign. Should be like this:

$('#mousearea').mousemove(function(e){
    var x = e.pageY - this.offsetTop;
    var transfromPosition = 'translate3d(' + x + '%, 230%, 0)';
    console.log(transfromPosition);

    if ((x <= 800)) {
        //$('#mouseshift').css({'top': x});
        $('#mouseshift').css('transform', transfromPosition);
    }
});

This should be working like your first example, where you do use % for both values inside the translate3d string.

Update:

To coerce your x Value to something between 0 and 60, you need to find a pair of possible min and max values for x. Then you can do something like what's shown in this answer:

Convert a number range to another range, maintaining ratio

Community
  • 1
  • 1
groooves
  • 460
  • 2
  • 7
  • `I would like it to translate the X co-ordinate between something like 0-60% so it's far more subtle` - That seemed to be the OPs question. – somethinghere Mar 07 '16 at 13:28
  • Yes, but OP also made an update where his code is working as he expects it (or at least close to it) and it's missing a %. – groooves Mar 07 '16 at 13:30
  • True, but that seems like either a typo or something that was forgotten and is better of in the comments IMHO, as it doesn't answer the question. – somethinghere Mar 07 '16 at 13:33