Pseudo 3D or parallax using javascript

After reading a post about the pseudo 3D effect , it became interesting to implement a certain analogue for use in web applications. I ask for the result under cat

The basics


After watching the video and twisting a couple of applications from the app, I came to the conclusion: sprites (layers) are as if in a cube. Therefore, when we turn the device, the near layers move in one direction and the farthest layers in the other. Somewhere in the middle is the main layer, to which our attention is riveted.

Having dealt with the theory, we proceed to the development.

Place the layers


We will not go far and use DIVs, and the CSS z-index property is also useful to us.

Above, I gave 3 sprites with the .flow class, initial coordinates and pictures. Now it's time to get them moving.

Device rotation


All our needs for obtaining a position in space will be satisfied by the event: window.ondevicemotion.
window.ondevicemotion = function(event) {  
     X = event.accelerationIncludingGravity.x;  
     Y = event.accelerationIncludingGravity.y;  
     Z = event.accelerationIncludingGravity.z;
}

I will not paint the event, send the curious to the list of references.
We need 2 values ​​from this event: X and U.
We calculate the offset delta:
    deltaX = lastX - X;
    deltaY = lastY - Y;
    lastY = Y;
    lastX = X;

We find all the sprites by class name .flow
Since sprites with a small z-index 'are the most "remote" and should move in the opposite direction, the movements for each group are calculated separately:
elements = $('div.flow');
 elements.each(function (key, layer) {
        zIndex = layer.style.zIndex;
        sprite = $('#' + layer.id);
                if (zIndex > 9) { //Я решил что дальние спрайты это спрайты с z-index < 10
                    anim = {"left":"-=" + deltaX * zIndex * 2, "top":"+=" + deltaY * zIndex * 0.5}; //0.5  это случайный коэффициент пришедший в голову, использую эти коэффициенты для отладки скоростей движения слоев
                } else {
                    anim = {"left":"+=" + deltaX * zIndex * 2, "top":"-=" + deltaY * zIndex * 2};
                }
sprite.animate(anim, 100); //Используем анимацию из jQuery
}

In addition to its usual task, z-index also acts as a coefficient for accelerating the movement of sprites.
Well, that's basically it.

Enhancements


1. To reduce the number of triggering of the layer motion method, timer activation has been added. This gave an increase, but an increase in the interval entails a twitch in the animation.
2. To reduce shaking, the delta is calculated differently: delta = X - Xsredn; Xredn - calculated at the moments of the timer interval. Even if at the last moment you shake your hand, everything will be smooth.
3. Added support for screen orientations

Problems


1. Shaking is still noticeable, I don’t know, I need to calibrate or I need to write a completely different algorithm
2. I can not really configure the speed of sprites

Could be done


1. A simple designer of Drag & Drop sprites, with level control
2. Work not only with the accelerometer, but also with the mouse, scroll bar (depending on availability or settings)
3. Work with the camera is possible, but ... I

recommend that you familiarize yourself with the

demo (if the device doesn’t If devicemotion is supported, then a random slope generator will turn on)

As a code and example, a short time from the idea to the implementation is guilty. It will be curious to know an opinion, tips. If there is interest, then I will try to finish the library.

UPD : It was not and is not possible to test on Andriod devices. And, unfortunately, the code does not work on them. I'll try to find a solution.

Also popular now: