Cross-browser Supported Image Skew effect using Javascript

Crossbrowser image shaking effect

Cross-browser image shaking effect using javascript

Today’s lesson quite entertaining, we’ll learn how to construct a shaking effect. For clarity, we will apply this effect to the picture. You will need to hold down by mouse a certain area in the image and move it to another location (drag). Now, I sure that better to see our online demonstration. How did it achieve? In principle, simply enough, the entire ‘image’ divided into 4 sectors. Place, where we will begin to drag by mouse – is the boundary separating of our four pictures. And shaking effect itself – will only change the sizes of our sectors and pictures in them. Read more.

Here are samples and downloadable package:

Live Demo
download in package

Ok, download the example files and lets start coding !


Step 1. HTML

As usual, we start with the HTML. This is source code of our sample:

index.html

<html>
<head>
    <title>Image shaking effect using pure JavaScript</title>
    <link rel="stylesheet" type="text/css" href="css/main.css" />
    <script type="text/javascript" src="js/main.js"></script>
</head>
 <body>
    <div class="example">
        <div id="main_object">
            <div class="tl"><img alt="" src="image.jpg"></div>
            <div class="tr"><img alt="" src="image.jpg"></div>
            <div class="bl"><img alt="" src="image.jpg"></div>
            <div class="br"><img alt="" src="image.jpg"></div>
        </div>
    </div>
 </body>
</html>

Here are main object with 4 images inside

Step 2. CSS

Here are single CSS file with all necessary styles:

css/main.css

body{background:#eee;margin:0;padding:0}
.example{background:#FFF;width:900px;border:1px #000 solid;margin:20px auto;padding:15px;-moz-border-radius: 3px;-webkit-border-radius: 3px}

#main_object{position:relative;width:900px;height:675px;overflow:hidden;cursor:pointer}
#main_object div{position:absolute;overflow:hidden}
#main_object img{position:absolute;-ms-interpolation-mode:nearest-neighbor}
#main_object .tl,#main_object .tl img{top:0;left:0}
#main_object .tr,#main_object .tr img{top:0;right:0}
#main_object .bl,#main_object .bl img{bottom:0;left:0}
#main_object .br,#main_object .br img{right:0;bottom:0}

Step 3. JS

Here are our main Javascript:

js/main.js

var ishk = {
    // variables
    speedD : .98, // degree of attenuation
    speedX : 50, // speed by X
    speedY : 60, // speed by X

    // inner variables
    xm   : 0,
    ym   : 0,
    sx   : 1,
    sy   : 1,
    svx  : 0,
    svy  : 0,
    xd   : 1,
    yd   : 1,
    drag : false,

    // initialization
    init : function() {
        // firstly we will pass through all inner div`s and its images and collect styles
        this.mobj = document.getElementById('main_object');
        var div = this.mobj.getElementsByTagName('div');
        this.d = [];
        this.i = [];
        for (var i = 0; i<4; i++) {
            this.d[i] = div[i].style;
            this.i[i] = div[i].getElementsByTagName('img')[0].style;
        }

        // set initial params of our generated result
        this.resize();

        // prevent text selection in IE
        document.onselectstart = function() {
            return false;
        }
        // prevent IE from trying to drag an image
        this.mobj.ondrag = function() {
            return false;
        }
        // mouse down event, we will set 'drag flag to true, change cursor and positions
        this.mobj.onmousedown = function() {
            ishk.drag = true;
            ishk.mobj.style.cursor = 'move';
            ishk.xd = ishk.xm - ishk.nx;
            ishk.yd = ishk.ym - ishk.ny;
            return false;
        }
        // on mouse up - release 'drag' flag, change pointer
        document.onmouseup = function() {
            ishk.drag = false;
            ishk.mobj.style.cursor = 'pointer';
            return false;
        }
        // set max sizes to last image
        this.i[3].width =  ishk.nw;
        this.i[3].height = ishk.nh;
        // and initial positions too
        ishk.sx = ishk.nx;
        ishk.sy = ishk.ny;

        // start looping
        this.shake();
    },

    // refreshing mouse positions
    mousemove : function(e) {
        this.xm = e.clientX;
        this.ym = e.clientY;
    }, 

    // sub init of initial positions, plus, in case of window resizing - repeat too
    resize : function() {
        var o = ishk.mobj;
        for (ishk.nx = 0, ishk.ny = 0; o != null; o = o.offsetParent)
            ishk.nx += o.offsetLeft, ishk.ny += o.offsetTop;
        ishk.nw = ishk.mobj.offsetWidth;
        ishk.nh = ishk.mobj.offsetHeight;
    },

    // main shaking function
    shake : function() {
        // in case of mouse move and dragging - change center position
        if (ishk.drag) {
            ishk.sx = ishk.xm;
            ishk.sy = ishk.ym;
        } else { // otherwise - attenuation
            ishk.svx = ishk.speedD * ishk.svx - (ishk.sx - ishk.xd - ishk.nx) / ishk.speedX;
            ishk.svy = ishk.speedD * ishk.svy - (ishk.sy - ishk.yd - ishk.ny) / ishk.speedY;
            ishk.sx += ishk.svx;
            ishk.sy += ishk.svy;
        }

        // calculation new widths and heights of our div`s and images
        var w0 = Math.max(0, Math.round(ishk.sx) - ishk.nx);
        var h0 = Math.max(0, Math.round(ishk.sy) - ishk.ny);
        var w1 = Math.max(0, ishk.nw - (Math.round(ishk.sx) - ishk.nx));
        var h1 = Math.max(0, ishk.nh - (Math.round(ishk.sy) - ishk.ny));
        var w2 = Math.max(0, Math.round((w0 * ishk.nw) / ishk.xd));
        var h2 = Math.max(0, Math.round((h0 * ishk.nh) / ishk.yd));
        var w3 = Math.max(0, Math.round((w1 * ishk.nw) / (ishk.nw - ishk.xd)));
        var h3 = Math.max(0, Math.round((h1 * ishk.nh) / (ishk.nh - ishk.yd)));

        // apply new widths
        ishk.d[0].width = w0 + 'px';
        ishk.d[1].width = w1 + 'px';
        ishk.d[2].width = w0 + 'px';
        ishk.d[3].width = w1 + 'px';
        ishk.d[0].height = h0 + 'px';
        ishk.d[1].height = h0 + 'px';
        ishk.d[2].height = h1 + 'px';
        ishk.d[3].height = h1 + 'px';
        ishk.i[0].width = w2 + 'px';
        ishk.i[1].width = w3 + 'px';
        ishk.i[2].width = w2 + 'px';
        ishk.i[3].width = w3 + 'px';
        ishk.i[0].height = h2 + 'px';
        ishk.i[1].height = h2 + 'px';
        ishk.i[2].height = h3 + 'px';
        ishk.i[3].height = h3 + 'px';

        // looping current function
        setTimeout(ishk.shake, 20); // 1/50*1000 = 20ms (for 50 fps) :)
    }
};

window.onload = function() {
    ishk.init(); // first initialization

    // binding mouse move event
    document.onmousemove = function(e) {
        if (window.event) e = window.event; // for IE
        ishk.mousemove(e);
    }

    // binding onresize event
    window.onresize = ishk.resize;
}

It is rather simple. When the page loads – I initialize our main object, and link all the necessary events. Then, after initialization, I loop our main ‘shake’ function, which changing sizes of all our 4 images (sectors).

Step 4. Images

For our demo I used only one image:

img_01


Live Demo
download in package

Conclusion

Today I told you how to create easy shaking effect to images. Commonly – you can try to play with any another objects too. Hope our javascript lessons still interesting for you. Good luck!

Enjoyed this Post?

If you enjoy our articles, feel free to share our tutorials with your friends.

3 thoughts on “Cross-browser Supported Image Skew effect using Javascript

  1. Hi,
    Thanks for the awesome script.
    What if I want to retain the image once it is skewed by the user? This was the user can perform multiple skew on the image.

    • Hi Murtaza,
      It could be difficult to achieve because of the logic of this script. Pay attention that this is not a single object, but four objects.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

     

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>