JSFiddle - React, Tailwind, and code Playground
HTML
<link rel="stylesheet" href="http://greenethumb.com/github/jquery-free-transform/css/jquery.freetrans.css">
<script src="http://greenethumb.com/github/jquery-free-transform/js/Matrix.js"></script>
<script src="http://greenethumb.com/github/jquery-free-transform/js/jquery.freetrans.js"></script>
Picture should be steady, we are transforming just the clipping mask (so picture could be later moved/scaled inside "Placeholder" as well). The problem is, mask does not follow FT transformations properly after scaling/rotation:
<!--Free transform element-->
<div id="ft" class="shape trans" width="300" height="250"></div>
<!-- SVG drawing element -->
<div id="drawing">
<svg id="SvgjsSvg1000" xmlns="http://www.w3.org/2000/svg" version="1.1" width="300" height="250" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="SvgjsG1007" clip-path="url("#SvgjsClipPath1009")">
<image id="SvgjsImage1036" xlink:href="http://greenethumb.com/github/jquery-free-transform/example/assets/bandit!.png" x="0" y="0" height="250" width="300"/>
</g>
<defs id="SvgjsDefs1001">
<clipPath id="SvgjsClipPath1009">
<rect id="SvgjsRect1008" width="300" height="250" fill="#ff7200"></rect>
</clipPath>
</defs>
</svg>
</div>
CSS
body{
user-select: none;
-webkit-user-select: none;
-moz-user-select: none;
-o-user-select: none;
-ms-user-select: none;
padding:50px;
margin:0;
background:#f2f2f2;
}
.shape{
width: 300px;
height: 250px;
color: #123456;
}
.ft-controls {
border:1px solid #ff7200;
}
JavaScript
// main goal - create SVG editor, where you can edit images like in Word (cropping when dragging edges instead of scaling them, being able to drag images inside free transform placeholder, etc.). It means we need using SVG clipping/masking, and binding position and FT elements to those masks/clippings.
// problem - same matrix transformation and position applied to svg elements acts differently -
// Try rotate or scale example...
// initialize free transform (FT) element
$('#ft').freetrans({
x: 10,
y: 50
});
//function for copying FT transfomation into SVG mask element
var refreshSVGMask = function(){
//get element transform
var elTransform = $('#ft').css("transform");
//quick parse of matrix transform:
var elMatrix = elTransform.substring(elTransform.indexOf("matrix") + 7, elTransform.indexOf(")"));
//modify matrix, to apply last two values (top and left position), which in jquery free transform are in "top" and "left" css attributes. Note - I've also tried applying same matrix, but changing "x" and "y" attributes in SVG (like: .attr("x", elTop)) -> got exactly same results.
var elTop = parseInt($("#ft").position().top);
var elLeft = parseInt($("#ft").position().left);
var matrixChanged = elMatrix.substring(0, elMatrix.length-6) + ", " + elLeft + ", " + elTop;
//apply matrix to SVG clip element:
$("#SvgjsRect1008").attr("transform", "matrix("+matrixChanged+")")
.attr("transform-origin", "50%,50%"); // also - put transform origin, but it does not seem to work
};
//setup simple drag mouse event and call refreshSVGMask function
$(document).mousemove(function(e){
if(e.which==1) {
refreshSVGMask();
}
});
refreshSVGMask(); //also, refresh position when document ready