JSFiddle - React, Tailwind, and code Playground
by aflin
HTML
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/themes/base/jquery-ui.css">
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>
<script src="http://flin.org/js/jquery.transform.js"></script>
<script src="http://flin.org/js/jquery.transformable.js"></script>
<a target='_top' href=http://jsfiddle.net/aflin/vbSMy/embedded/result/>Full Screen Demo</a>
<div class='box box1'>
<button class='reset'>Reset Me</button>
<div class='box box2'>
<button class='reset'>Reset Me</button><br>
<img width=200 height=119 src="http://upload.wikimedia.org/wikipedia/commons/e/e9/Dog%27s_guardian_angel.jpg">
<br>this box is not contained</div>
</div>
<div class='box box1' style='top:550px'>
<button class='reset'>Reset Me</button>
<div id='box3' class='box box2'>
<button class='reset'>Reset Me</button><br>
<img width=200 height=150 src="http://upload.wikimedia.org/wikipedia/commons/thumb/7/7e/Week_z00.jpg/200px-Week_z00.jpg">This one is contained</div>
<div style="bottom: 0px; left: 10px; position: absolute; font-size: 12px">An example with parent containment</div>
</div>
<div class='infobox'>Div Transformation Info:</div>
CSS
.box {position: absolute; width:300px; height: 300px; border: 1px black solid; top: 210px; z-index:10}
.box1 {background-color: #d0d0d0;}
.box2 {position: absolute; top: 30px; left: 10px; width:200px; height: 200px; border: 1px blue solid; background-color: white;}
.box.ui-resizable-disabled { opacity: 1.0; filter: Alpha(Opacity=100);}
.infobox {position: absolute; width:400px; height: 175px; border: 1px green solid; font-size: 10px}
li{ list-style-type: bold; padding: 0; margin-left: 36px;}
button {position: relative; left: 20px;}
JavaScript
$(function() {
var b=$('.box');
var ib=$('.infobox');
b.draggable({stop: showinfo});
b.resizable({stop: showinfo});
//double click on resize icon to toggle scale function
b.transformable( {
rotateStop: showinfo,
skewStop: showinfo,
scaleStop: showinfo,
rotate: showrotate,
scale: constrainscale
});
//containment is still a bit expiramental
$('#box3').draggable('option','containment','parent')
.transformable('option','containment',true)
.resizable('option','containment','parent');
$('.box2').find('.ui-resizable-handle').trigger('dblclick');
function constrainscale(e,ui) {
//uncomment to see how you can set value to constrain size
//if (ui.scalex<0.5) ui.scalex=0.5;
//if (ui.scaley<0.5) ui.scaley=0.5;
}
function showrotate(e,ui) {
$('#rotate').html(ui.angle.rad);
//uncomment this to see how you can set the value to constrain angle
//if(ui.angle.rad>1)ui.angle.rad=1;if(ui.angle.rad<-1) ui.angle.rad=-1;
}
function showinfo (e,ui) {
var u=$(this).getTransform();
var o=$(this).tOffset();
console.log(o);
function xytostr(c) {
return(parseInt(c.x)+','+parseInt(c.y));
}
ib.html(
'Div Transformation Info:<ul>Current Matrix:<li>'
+ $(this).matrixToArray()+'</li></ul><ul>Rotation:<li id="rotate">'
+u.rotate+'</li></ul><ul>Skew:<li>'
+u.skew+"</li></ul><ul>Scale:<li>"
+u.scale+'</li></ul><ul>Offset:<li>'
+'left:'+parseInt(o.left)+", top:"+parseInt(o.top)
+', right:'+parseInt(o.right)+'bottom:'+parseInt(o.bottom)
+'</li></ul>'
+'<ul>Corners:<li>lt:'+xytostr(o.corners[0])
+', rt:'+xytostr(o.corners[1])
+', rb:'+xytostr(o.corners[2])
+', lb:'+xytostr(o.corners[3])
);
}
$('.reset').click(function() {
...