<!doctype html>
<html>
<head>
<title>CSS Transform Matrix Dragging Tests ... RJM Programming - September, 2017 ... Thanks to http://franklinta.com/2014/09/08/computing-css-matrix3d-transforms/</title>
<style>
.box {
margin: 20px;
padding: 10px;
height: 150px;
width: 500px;
border: 1px solid black;
}
</style>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type='text/javascript'>


//<style><br>
//.box {<br>
// margin: 20px; padding: 10px;<br>
// height: 150px; width: 500px;<br>
// border: 1px solid black; }<br>
//</style><br>


// Thanks to http://franklinta.com/2014/09/08/computing-css-matrix3d-transforms/ for most of jQuery Javascript below

var selector = '#img' // Replace this with the selector for the element you want to make transformable


jQuery.getScript('//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js', function() {
jQuery.getScript('//cdnjs.cloudflare.com/ajax/libs/numeric/1.2.6/numeric.min.js', function() {

(function() {
var $, applyTransform, getTransform, makeTransformable;

$ = jQuery;

getTransform = function(from, to) {
var A, H, b, h, i, k_i, lhs, rhs, _i, _j, _k, _ref;
console.assert((from.length === (_ref = to.length) && _ref === 4));
A = [];
for (i = _i = 0; _i < 4; i = ++_i) {
A.push([from[i].x, from[i].y, 1, 0, 0, 0, -from[i].x * to[i].x, -from[i].y * to[i].x]);
A.push([0, 0, 0, from[i].x, from[i].y, 1, -from[i].x * to[i].y, -from[i].y * to[i].y]);
}
b = [];
for (i = _j = 0; _j < 4; i = ++_j) {
b.push(to[i].x);
b.push(to[i].y);
}
h = numeric.solve(A, b);
H = [[h[0], h[1], 0, h[2]], [h[3], h[4], 0, h[5]], [0, 0, 1, 0], [h[6], h[7], 0, 1]];
for (i = _k = 0; _k < 4; i = ++_k) {
lhs = numeric.dot(H, [from[i].x, from[i].y, 0, 1]);
k_i = lhs[3];
rhs = numeric.dot(k_i, [to[i].x, to[i].y, 0, 1]);
console.assert(numeric.norm2(numeric.sub(lhs, rhs)) < 1e-9, "Not equal:", lhs, rhs);
}
return H;
};

applyTransform = function(element, originalPos, targetPos, callback) {
var H, from, i, j, p, to;
from = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = originalPos.length; _i < _len; _i++) {
p = originalPos[_i];
_results.push({
x: p[0] - originalPos[0][0],
y: p[1] - originalPos[0][1]
});
}
return _results;
})();
to = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = targetPos.length; _i < _len; _i++) {
p = targetPos[_i];
_results.push({
x: p[0] - originalPos[0][0],
y: p[1] - originalPos[0][1]
});
}
return _results;
})();
H = getTransform(from, to);
$(element).css({
'transform': "matrix3d(" + (((function() {
var _i, _results;
_results = [];
for (i = _i = 0; _i < 4; i = ++_i) {
_results.push((function() {
var _j, _results1;
_results1 = [];
for (j = _j = 0; _j < 4; j = ++_j) {
_results1.push(H[j][i].toFixed(20));
}
return _results1;
})());
}
return _results;
})()).join(',')) + ")",
'transform-origin': '0 0'
});
var bits=('' + H).split(',');
var cbits='' + bits[0];
for (var ibits=1; ibits<bits.length; ibits++) {
cbits+=',';
if (eval(ibits % 4) == 0) cbits+='<br>';
cbits+='' + bits[ibits];
}
document.getElementById(selector.replace('#','')).title='matrix3d(' + cbits.replace(/<br>/g,'') + ')';
if (('' + document.getElementById(selector.replace('#','')).style.background) == '' && document.getElementById(selector.replace('#','')).innerHTML.replace(/<br>/g,'').indexOf('<') == -1) {
document.getElementById(selector.replace('#','')).innerHTML='matrix3d(' + cbits + ')';
} else {
document.getElementById(selector.replace('#','')).innerHTML='';
}
return typeof callback === "function" ? callback(element, H) : void 0;
};

makeTransformable = function(selector, callback) {
return $(selector).each(function(i, element) {
var controlPoints, originalPos, p, position;
$(element).css('transform', '');
controlPoints = (function() {
var _i, _len, _ref, _results;
_ref = ['left top', 'left bottom', 'right top', 'right bottom'];
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
position = _ref[_i];
_results.push($('<div>').css({
border: '3px solid black',
borderRadius: '3px',
cursor: 'move',
position: 'absolute',
zIndex: 100000
}).appendTo('body').position({
at: position,
of: element,
collision: 'none'
}));
}
return _results;
})();
originalPos = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = controlPoints.length; _i < _len; _i++) {
p = controlPoints[_i];
_results.push([p.offset().left, p.offset().top]);
}
return _results;
})();
$(controlPoints).draggable({
start: (function(_this) {
return function() {
return $(element).css('pointer-events', 'none');
};
})(this),
drag: (function(_this) {
return function() {
return applyTransform(element, originalPos, (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = controlPoints.length; _i < _len; _i++) {
p = controlPoints[_i];
_results.push([p.offset().left, p.offset().top]);
}
return _results;
})(), callback);
};
})(this),
stop: (function(_this) {
return function() {
applyTransform(element, originalPos, (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = controlPoints.length; _i < _len; _i++) {
p = controlPoints[_i];
_results.push([p.offset().left, p.offset().top]);
}
return _results;
})(), callback);
return $(element).css('pointer-events', 'auto');
};
})(this)
});
return element;
});
};

window.makeTransformable = makeTransformable;

}).call(this);

makeTransformable(selector);

});
});

function applythis(tv) {
var hides, ihides=0;
if (tv != "") {
if (tv.trim() == tv) {
document.getElementById(selector.replace('#','')).style.background='URL(' + tv + ')';
document.getElementById(selector.replace('#','')).style.backgroundRepeat='repeat';
} else {
if (tv.indexOf(tv.trim() + ' ') != -1) {
document.getElementById(selector.replace('#','')).style.background='URL(' + tv.trim() + ')';
document.getElementById(selector.replace('#','')).style.backgroundSize='cover';
document.getElementById(selector.replace('#','')).style.backgroundRepeat='no-repeat';
} else if (tv.indexOf(tv.trim() + ' ') != -1) {
document.getElementById(selector.replace('#','')).style.background='URL(' + tv.trim() + ')';
document.getElementById(selector.replace('#','')).style.backgroundSize='contain';
document.getElementById(selector.replace('#','')).style.backgroundRepeat='no-repeat';
} else {
document.getElementById(selector.replace('#','')).style.background='URL(' + tv.trim() + ')';
document.getElementById(selector.replace('#','')).style.backgroundRepeat='no-repeat';
}
}
if (tv.indexOf('#') != -1) {
hides=document.getElementsByTagName('h1');
for (ihides=0; ihides<hides.length; ihides++) {
hides[ihides].style.visibility='hidden';
}
hides=document.getElementsByTagName('h3');
for (ihides=0; ihides<hides.length; ihides++) {
hides[ihides].style.visibility='hidden';
}
hides=document.getElementsByTagName('p');
for (ihides=0; ihides<hides.length; ihides++) {
hides[ihides].style.visibility='hidden';
}
}
}
}

function fixstyle(stih) {
var idivs=0, boxrect=null, kdivs=0;
stih=stih.replace(/\&\;lt\;/g, '<').replace(/\&\;gt\;/g, '>').replace(/\<\;/g, '<').replace(/\>\;/g, '>');
//alert('0:' + stih);
if (stih.indexOf('<style>') != -1 && stih.indexOf('</style>') != -1) {
document.getElementById('dstyle').innerHTML='<style>' + stih.split('</style>')[0].split('<style>')[1] + '</style>';
//alert('<Style>' + stih.split('</style>')[0].split('<style>')[1] + '</style>');
var divs=document.getElementsByTagName('div');
for (var jdivs=0; jdivs<2; jdivs++) {
if (kdivs == 0) {
for (idivs=0; idivs<divs.length; idivs++) {
if (('' + divs[idivs].className).indexOf('ui-draggable') != -1) {
if (boxrect) {
if (kdivs == 0) {
kdivs++;
divs[idivs].style.left=('' + boxrect.left) + 'px';
divs[idivs].style.top=('' + boxrect.top) + 'px';
} else if (kdivs == 1) {
kdivs++;
divs[idivs].style.left=('' + boxrect.left) + 'px';
divs[idivs].style.top=('' + boxrect.bottom) + 'px';
} else if (kdivs == 2) {
kdivs++;
divs[idivs].style.left=('' + boxrect.right) + 'px';
divs[idivs].style.top=('' + boxrect.top) + 'px';
} else if (kdivs == 3) {
kdivs++;
divs[idivs].style.left=('' + boxrect.right) + 'px';
divs[idivs].style.top=('' + boxrect.bottom) + 'px';
//alert('<stylE>' + stih.split('</style>')[0].split('<style>')[1] + '</style>');
location.href=document.URL.split('?')[0].split('#')[0] + '?styling=' + encodeURIComponent('<style>' + stih.split('</style>')[0].split('<style>')[1] + '</style>');
}
}
} else if (('' + divs[idivs].className).indexOf('box') != -1 && !boxrect) {
boxrect=divs[idivs].getBoundingClientRect();
}
}
}
}
} //else {
//alert(stih);
//}
}
</script>
<body>
<div id=dstyle style='display:none;'>
<script type='text/javascript'>
var styis=location.search.split('styling=')[1] ? decodeURIComponent(location.search.split('styling=')[1].split('&')[0]) : '';
if (styis != '') {
document.write(styis);
}
</script>
</div>
<h1>CSS Transform Matrix Dragging Tests</h1>
<h3>RJM Programming <a target=_blank title=Reset href='./more_transform.html'>-</a> September, 2017</h3>
<h3>Thanks to <a target=_blank title='Frank Ta work regarding CSS transform matrix ... thanks' href='http://franklinta.com/2014/09/08/computing-css-matrix3d-transforms/'>http://franklinta.com/2014/09/08/computing-css-matrix3d-transforms/</a></h3>
<p>Optional Background Image URL for Box Below: <input style="width:530px;" type='text' id='iurl' title='Optionally append space to this image URL to not have it repeat, two spaces for contain and three spaces for cover, and include hash # for top element invisibility' value='http://www.rjmprogramming.com.au/MyBusinessUnidad/Welcome_files/logo.jpg'></input> <input type='button' style='background-color:yellow;' title='Optionally append space to this image URL to not have it repeat, two spaces for contain and three spaces for cover, and include hash # for top element invisibility' onclick=" applythis(document.getElementById('iurl').value); " value="Apply Below"></input><br></p>
<div id="img" class="box" contenteditable=true onblur="fixstyle((this.innerText || this.contentWindow || this.contentDocument).replace(/\<br\>/g, ' ').replace(/\&\;lt\;/g, '<').replace(/\&\;gt\;/g, '>').replace(/\<\;/g, '<').replace(/\>\;/g, '>'));">
Drag the points to transform the box! Optionally change styling below.<br>
<script type='text/javascript'>
var xstyis=location.search.split('styling=')[1] ? decodeURIComponent(location.search.split('styling=')[1].split('&')[0]) : '';
if (xstyis != '') {
while (xstyis.indexOf(String.fromCharCode(10)) != -1) {
xstyis=xstyis.replace(String.fromCharCode(10), '<br>');
}
//alert(xstyis.replace(/\</g,'<').replace(/\>/g,'>'));
document.write(xstyis.replace(/\<s/g,'<s').replace(/\<\//g,'</').replace(/e\>/g,'e>'));
} else {
document.write('<style><br>.box {<br>margin: 20px; padding: 10px;<br>height: 150px; width: 500px;<br>border: 1px solid black; }<br></style><br>');
}
</script>
</div>
</body>
</html>