summaryrefslogtreecommitdiff
path: root/addons/web_editor/static/lib/jQuery.transfo.js
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/web_editor/static/lib/jQuery.transfo.js
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/web_editor/static/lib/jQuery.transfo.js')
-rw-r--r--addons/web_editor/static/lib/jQuery.transfo.js453
1 files changed, 453 insertions, 0 deletions
diff --git a/addons/web_editor/static/lib/jQuery.transfo.js b/addons/web_editor/static/lib/jQuery.transfo.js
new file mode 100644
index 00000000..855d6f48
--- /dev/null
+++ b/addons/web_editor/static/lib/jQuery.transfo.js
@@ -0,0 +1,453 @@
+/*
+Copyright (c) 2014 Christophe Matthieu,
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+(function($){
+ 'use strict';
+ var rad = Math.PI/180;
+
+ // public methods
+ var methods = {
+ init : function(settings) {
+ return this.each(function() {
+ var $this = $(this), transfo = $this.data('transfo');
+ if (!transfo) {
+ _init($this, settings);
+ } else {
+ _overwriteOptions($this, transfo, settings);
+ _targetCss($this, transfo);
+ }
+ });
+ },
+
+ destroy : function() {
+ return this.each(function() {
+ var $this = $(this);
+ if ($this.data('transfo')) {
+ _destroy($this);
+ }
+ });
+ },
+
+ reset : function() {
+ return this.each(function() {
+ var $this = $(this);
+ if ($this.data('transfo')) {
+ _reset($this);
+ }
+ });
+ },
+
+ toggle : function() {
+ return this.each(function() {
+ var $this = $(this);
+ var transfo = $this.data('transfo');
+ if (transfo) {
+ transfo.settings.hide = !transfo.settings.hide;
+ _showHide($this, transfo);
+ }
+ });
+ },
+
+ hide : function() {
+ return this.each(function() {
+ var $this = $(this);
+ var transfo = $this.data('transfo');
+ if (transfo) {
+ transfo.settings.hide = true;
+ _showHide($this, transfo);
+ }
+ });
+ },
+
+ show : function() {
+ return this.each(function() {
+ var $this = $(this);
+ var transfo = $this.data('transfo');
+ if (transfo) {
+ transfo.settings.hide = false;
+ _showHide($this, transfo);
+ }
+ });
+ },
+
+ settings : function() {
+ if(this.length > 1) {
+ this.map(function () {
+ var $this = $(this);
+ return $this.data('transfo') && $this.data('transfo').settings;
+ });
+ }
+ return this.data('transfo') && $this.data('transfo').settings;
+ },
+ center : function() {
+ if(this.length > 1) {
+ this.map(function () {
+ var $this = $(this);
+ return $this.data('transfo') && $this.data('transfo').$center.offset();
+ });
+ }
+ return this.data('transfo') && this.data('transfo').$center.offset();
+ }
+ };
+
+ $.fn.transfo = function( method ) {
+ if ( methods[method] ) {
+ return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
+ } else if ( typeof method === 'object' || ! method ) {
+ return methods.init.apply( this, arguments );
+ } else {
+ $.error( 'Method ' + method + ' does not exist on jQuery.transfo' );
+ }
+ return false;
+ };
+
+ function _init ($this, settings) {
+ var transfo = {};
+ $this.data('transfo', transfo);
+ transfo.settings = settings;
+
+ // generate all the controls markup
+ var css = "box-sizing: border-box; position: absolute; background-color: #fff; border: 1px solid #ccc; width: 8px; height: 8px; margin-left: -4px; margin-top: -4px;";
+ transfo.$markup = $(''
+ + '<div class="transfo-container">'
+ + '<div class="transfo-controls">'
+ + '<div style="cursor: crosshair; position: absolute; margin: -30px; top: 0; right: 0; padding: 1px 0 0 1px;" class="transfo-rotator">'
+ + '<span class="fa-stack fa-lg">'
+ + '<i class="fa fa-circle fa-stack-2x"></i>'
+ + '<i class="fa fa-repeat fa-stack-1x fa-inverse"></i>'
+ + '</span>'
+ + '</div>'
+ + '<div style="' + css + 'top: 0%; left: 0%; cursor: nw-resize;" class="transfo-scaler-tl"></div>'
+ + '<div style="' + css + 'top: 0%; left: 100%; cursor: ne-resize;" class="transfo-scaler-tr"></div>'
+ + '<div style="' + css + 'top: 100%; left: 100%; cursor: se-resize;" class="transfo-scaler-br"></div>'
+ + '<div style="' + css + 'top: 100%; left: 0%; cursor: sw-resize;" class="transfo-scaler-bl"></div>'
+ + '<div style="' + css + 'top: 0%; left: 50%; cursor: n-resize;" class="transfo-scaler-tc"></div>'
+ + '<div style="' + css + 'top: 100%; left: 50%; cursor: s-resize;" class="transfo-scaler-bc"></div>'
+ + '<div style="' + css + 'top: 50%; left: 0%; cursor: w-resize;" class="transfo-scaler-ml"></div>'
+ + '<div style="' + css + 'top: 50%; left: 100%; cursor: e-resize;" class="transfo-scaler-mr"></div>'
+ + '<div style="' + css + 'border: 0; width: 0px; height: 0px; top: 50%; left: 50%;" class="transfo-scaler-mc"></div>'
+ + '</div>'
+ + '</div>');
+ transfo.$center = transfo.$markup.find(".transfo-scaler-mc");
+
+ // init setting and get css to set wrap
+ _setOptions($this, transfo);
+ _overwriteOptions ($this, transfo, settings);
+
+ // append controls to container
+ $("body").append(transfo.$markup);
+
+ // set transfo container and markup
+ setTimeout(function () {
+ _targetCss($this, transfo);
+ },0);
+
+ _bind($this, transfo);
+
+ _targetCss($this, transfo);
+ _stop_animation($this[0]);
+ }
+
+ function _overwriteOptions ($this, transfo, settings) {
+ transfo.settings = $.extend(transfo.settings, settings || {});
+ }
+
+ function _stop_animation (target) {
+ target.style.webkitAnimationPlayState = "paused";
+ target.style.animationPlayState = "paused";
+ target.style.webkitTransition = "none";
+ target.style.transition = "none";
+ }
+
+ function _setOptions ($this, transfo) {
+ var style = $this.attr("style") || "";
+ var transform = style.match(/transform\s*:([^;]+)/) ? style.match(/transform\s*:([^;]+)/)[1] : "";
+
+ transfo.settings = {};
+
+ transfo.settings.angle= transform.indexOf('rotate') != -1 ? parseFloat(transform.match(/rotate\(([^)]+)deg\)/)[1]) : 0;
+ transfo.settings.scalex= transform.indexOf('scaleX') != -1 ? parseFloat(transform.match(/scaleX\(([^)]+)\)/)[1]) : 1;
+ transfo.settings.scaley= transform.indexOf('scaleY') != -1 ? parseFloat(transform.match(/scaleY\(([^)]+)\)/)[1]) : 1;
+
+ transfo.settings.style = style.replace(/[^;]*transform[^;]+/g, '').replace(/;+/g, ';');
+
+ $this.attr("style", transfo.settings.style);
+ _stop_animation($this[0]);
+ transfo.settings.pos = $this.offset();
+
+ transfo.settings.height = $this.innerHeight();
+ transfo.settings.width = $this.innerWidth();
+
+ var translatex = transform.match(/translateX\(([0-9.-]+)(%|px)\)/);
+ var translatey = transform.match(/translateY\(([0-9.-]+)(%|px)\)/);
+ transfo.settings.translate = "%";
+
+ if (translatex && translatex[2] === "%") {
+ transfo.settings.translatexp = parseFloat(translatex[1]);
+ transfo.settings.translatex = transfo.settings.translatexp / 100 * transfo.settings.width;
+ } else {
+ transfo.settings.translatex = translatex ? parseFloat(translatex[1]) : 0;
+ }
+ if (translatey && translatey[2] === "%") {
+ transfo.settings.translateyp = parseFloat(translatey[1]);
+ transfo.settings.translatey = transfo.settings.translateyp / 100 * transfo.settings.height;
+ } else {
+ transfo.settings.translatey = translatey ? parseFloat(translatey[1]) : 0;
+ }
+
+ transfo.settings.css = window.getComputedStyle($this[0], null);
+
+ transfo.settings.rotationStep = 5;
+ transfo.settings.hide = false;
+ transfo.settings.callback = function () {};
+ }
+
+ function _bind ($this, transfo) {
+ function mousedown (event) {
+ _mouseDown($this, this, transfo, event);
+ $(document).on("mousemove", mousemove).on("mouseup", mouseup);
+ }
+ function mousemove (event) {
+ _mouseMove($this, this, transfo, event);
+ }
+ function mouseup (event) {
+ _mouseUp($this, this, transfo, event);
+ $(document).off("mousemove", mousemove).off("mouseup", mouseup);
+ }
+
+ transfo.$markup.off().on("mousedown", mousedown);
+ transfo.$markup.find(".transfo-controls >:not(.transfo-scaler-mc)").off().on("mousedown", mousedown);
+ }
+
+ function _mouseDown($this, div, transfo, event) {
+ event.preventDefault();
+ if (transfo.active || event.which !== 1) return;
+
+ var type = "position", $e = $(div);
+ if ($e.hasClass("transfo-rotator")) type = "rotator";
+ else if ($e.hasClass("transfo-scaler-tl")) type = "tl";
+ else if ($e.hasClass("transfo-scaler-tr")) type = "tr";
+ else if ($e.hasClass("transfo-scaler-br")) type = "br";
+ else if ($e.hasClass("transfo-scaler-bl")) type = "bl";
+ else if ($e.hasClass("transfo-scaler-tc")) type = "tc";
+ else if ($e.hasClass("transfo-scaler-bc")) type = "bc";
+ else if ($e.hasClass("transfo-scaler-ml")) type = "ml";
+ else if ($e.hasClass("transfo-scaler-mr")) type = "mr";
+
+ transfo.active = {
+ "type": type,
+ "scalex": transfo.settings.scalex,
+ "scaley": transfo.settings.scaley,
+ "pageX": event.pageX,
+ "pageY": event.pageY,
+ "center": transfo.$center.offset(),
+ };
+ }
+ function _mouseUp($this, div, transfo, event) {
+ transfo.active = null;
+ }
+
+ function _mouseMove($this, div, transfo, event) {
+ event.preventDefault();
+ if (!transfo.active) return;
+ var settings = transfo.settings;
+ var center = transfo.active.center;
+ var cdx = center.left - event.pageX;
+ var cdy = center.top - event.pageY;
+
+ if (transfo.active.type == "rotator") {
+ var ang, dang = Math.atan((settings.width * settings.scalex) / (settings.height * settings.scaley)) / rad;
+
+ if (cdy) ang = Math.atan(- cdx / cdy) / rad;
+ else ang = 0;
+ if (event.pageY >= center.top && event.pageX >= center.left) ang += 180;
+ else if (event.pageY >= center.top && event.pageX < center.left) ang += 180;
+ else if (event.pageY < center.top && event.pageX < center.left) ang += 360;
+
+ ang -= dang;
+ if (settings.scaley < 0 && settings.scalex < 0) ang += 180;
+
+ if (!event.ctrlKey) {
+ settings.angle = Math.round(ang / transfo.settings.rotationStep) * transfo.settings.rotationStep;
+ } else {
+ settings.angle = ang;
+ }
+
+ // reset position : don't move center
+ _targetCss($this, transfo);
+ var new_center = transfo.$center.offset();
+ var x = center.left - new_center.left;
+ var y = center.top - new_center.top;
+ var angle = ang * rad;
+ settings.translatex += x*Math.cos(angle) - y*Math.sin(-angle);
+ settings.translatey += - x*Math.sin(angle) + y*Math.cos(-angle);
+ }
+ else if (transfo.active.type == "position") {
+ var angle = settings.angle * rad;
+ var x = event.pageX - transfo.active.pageX;
+ var y = event.pageY - transfo.active.pageY;
+ transfo.active.pageX = event.pageX;
+ transfo.active.pageY = event.pageY;
+ var dx = x*Math.cos(angle) - y*Math.sin(-angle);
+ var dy = - x*Math.sin(angle) + y*Math.cos(-angle);
+
+ settings.translatex += dx;
+ settings.translatey += dy;
+ }
+ else if (transfo.active.type.length === 2) {
+ var angle = settings.angle * rad;
+ var dx = cdx*Math.cos(angle) - cdy*Math.sin(-angle);
+ var dy = - cdx*Math.sin(angle) + cdy*Math.cos(-angle);
+ if (transfo.active.type.indexOf("t") != -1) {
+ settings.scaley = dy / (settings.height/2);
+ }
+ if (transfo.active.type.indexOf("b") != -1) {
+ settings.scaley = - dy / (settings.height/2);
+ }
+ if (transfo.active.type.indexOf("l") != -1) {
+ settings.scalex = dx / (settings.width/2);
+ }
+ if (transfo.active.type.indexOf("r") != -1) {
+ settings.scalex = - dx / (settings.width/2);
+ }
+ if (settings.scaley > 0 && settings.scaley < 0.05) settings.scaley = 0.05;
+ if (settings.scalex > 0 && settings.scalex < 0.05) settings.scalex = 0.05;
+ if (settings.scaley < 0 && settings.scaley > -0.05) settings.scaley = -0.05;
+ if (settings.scalex < 0 && settings.scalex > -0.05) settings.scalex = -0.05;
+
+ if (event.shiftKey &&
+ (transfo.active.type === "tl" || transfo.active.type === "bl" ||
+ transfo.active.type === "tr" || transfo.active.type === "br")) {
+ settings.scaley = settings.scalex;
+ }
+ }
+
+ settings.angle = Math.round(settings.angle);
+ settings.translatex = Math.round(settings.translatex);
+ settings.translatey = Math.round(settings.translatey);
+ settings.scalex = Math.round(settings.scalex*100)/100;
+ settings.scaley = Math.round(settings.scaley*100)/100;
+
+ _targetCss($this, transfo);
+ _stop_animation($this[0]);
+ return false;
+ }
+
+ function _setCss($this, css, settings) {
+ var transform = "";
+ var trans = false;
+ if (settings.angle !== 0) {
+ trans = true;
+ transform += " rotate("+settings.angle+"deg) ";
+ }
+ if (settings.translatex) {
+ trans = true;
+ transform += " translateX("+(settings.translate === "%" ? settings.translatexp+"%" : settings.translatex+"px")+") ";
+ }
+ if (settings.translatey) {
+ trans = true;
+ transform += " translateY("+(settings.translate === "%" ? settings.translateyp+"%" : settings.translatey+"px")+") ";
+ }
+ if (settings.scalex != 1) {
+ trans = true;
+ transform += " scaleX("+settings.scalex+") ";
+ }
+ if (settings.scaley != 1){
+ trans = true;
+ transform += " scaleY("+settings.scaley+") ";
+ }
+
+ if (trans) {
+ css += ";"
+ /* Safari */
+ css += "-webkit-transform:" + transform + ";"
+ /* Firefox */
+ + "-moz-transform:" + transform + ";"
+ /* IE */
+ + "-ms-transform:" + transform + ";"
+ /* Opera */
+ + "-o-transform:" + transform + ";"
+ /* Other */
+ + "transform:" + transform + ";";
+ }
+
+ css = css.replace(/(\s*;)+/g, ';').replace(/^\s*;|;\s*$/g, '');
+
+ $this.attr("style", css);
+ }
+
+ function _targetCss ($this, transfo) {
+ var settings = transfo.settings;
+ var width = parseFloat(settings.css.width);
+ var height = parseFloat(settings.css.height);
+ settings.translatexp = Math.round(settings.translatex/width*1000)/10;
+ settings.translateyp = Math.round(settings.translatey/height*1000)/10;
+
+ _setCss($this, settings.style, settings);
+
+ transfo.$markup.css({
+ "position": "absolute",
+ "width": width + "px",
+ "height": height + "px",
+ "top": settings.pos.top + "px",
+ "left": settings.pos.left + "px"
+ });
+
+ var $controls = transfo.$markup.find('.transfo-controls');
+ _setCss($controls,
+ "width:" + width + "px;" +
+ "height:" + height + "px;" +
+ "cursor: move;",
+ settings);
+
+ $controls.children().css("transform", "scaleX("+(1/settings.scalex)+") scaleY("+(1/settings.scaley)+")");
+
+ _showHide($this, transfo);
+
+ transfo.settings.callback.call($this[0], $this);
+ }
+
+ function _showHide ($this, transfo) {
+ transfo.$markup.css("z-index", transfo.settings.hide ? -1 : 1000);
+ if (transfo.settings.hide) {
+ transfo.$markup.find(".transfo-controls > *").hide();
+ transfo.$markup.find(".transfo-scaler-mc").show();
+ } else {
+ transfo.$markup.find(".transfo-controls > *").show();
+ }
+ }
+
+ function _destroy ($this) {
+ $this.data('transfo').$markup.remove();
+ $this.removeData('transfo');
+ }
+
+ function _reset ($this) {
+ var transfo = $this.data('transfo');
+ _destroy($this);
+ $this.transfo(transfo.settings);
+ }
+
+})(jQuery);