|
|
var canvesBodyScale = 0.7;
|
|
|
var doBlendColorV2 = false;
|
|
|
var priceLayerSubTypeArr = new Array();
|
|
|
function Galaxy(config) {
|
|
|
var callbackCanvasCancelSelectLayer = config.callbackCanvasCancelSelectLayer;
|
|
|
var callbackCanvasSelectLayer = config.callbackCanvasSelectLayer;
|
|
|
var callbackSizeOrPositionChange = config.callbackSizeOrPositionChange;
|
|
|
|
|
|
priceLayerSubTypeArr = config.priceLayerSubTypeArr;
|
|
|
if (config.canvesBodyScale) {
|
|
|
canvesBodyScale = config.canvesBodyScale;
|
|
|
}
|
|
|
if (config.doBlendColorV2) {
|
|
|
doBlendColorV2 = true;
|
|
|
}
|
|
|
var spacialLayerSubTypeArr = config.spacialLayerSubTypeArr;
|
|
|
|
|
|
var NONE = 0, MOVING = 1, SCALING = 2, ROTATING = 3;
|
|
|
var SCALING_LEFT_TOP = 4, SCALING_TOP = 5, SCALING_RIGHT_TOP = 6;
|
|
|
var SCALING_RIGHT = 7, SCALING_RIGHT_BOTTOM = 8, SCALING_BOTTOM = 9, SCALING_LEFT_BOTTOM = 10, SCALING_LEFT = 11;
|
|
|
var ROTATE_ARC_RADIUS = 7 / canvesBodyScale;
|
|
|
var RESIZE_ARC_RADIUS = 3 / canvesBodyScale;
|
|
|
var ROTATE_DISTANCE = 20 / canvesBodyScale;
|
|
|
var SEPARATION_X1 = 88;
|
|
|
var SEPARATION_X2 = 712;
|
|
|
|
|
|
var drawNeedMaker = true;
|
|
|
var drawNeedSpecial = true;
|
|
|
var drawNeedSeparationConfigVal = config.drawNeedSeparation;
|
|
|
var drawNeedSeparation = drawNeedSeparationConfigVal;
|
|
|
|
|
|
var mouseDown = false;
|
|
|
var mousePrevX = 0;
|
|
|
var mousePrevY = 0;
|
|
|
var mouseDownNotInLayer = false;
|
|
|
var rotatePrevValue = 0;
|
|
|
|
|
|
var selectedLayer = null;
|
|
|
|
|
|
var layerState = NONE;
|
|
|
var selectedIndex = null;
|
|
|
var dragSelectedIndexs = new Array();
|
|
|
|
|
|
var backgroundColor = '';
|
|
|
var backgroundImage = null;
|
|
|
var borderColor = '';
|
|
|
var borderSize = 0;
|
|
|
var cursorStyle = 'default';
|
|
|
|
|
|
var canvasId = config.canvasId;
|
|
|
var canvas = document.getElementById(canvasId);
|
|
|
canvas.backgroundAlpha = 0;
|
|
|
|
|
|
var canvasOffsetX = $("#" + canvasId).offset().left;
|
|
|
var canvasOffsetY = $("#" + canvasId).offset().top;
|
|
|
|
|
|
var context = canvas.getContext('2d');
|
|
|
var layers = new Array();
|
|
|
|
|
|
var startClickVector = null;
|
|
|
var endClickVector = null;
|
|
|
canvas.addEventListener('mousemove', mouseMoveEvent, false);
|
|
|
canvas.addEventListener('mouseout', moveUpEvent, false);
|
|
|
canvas.addEventListener('mouseup', moveUpEvent, false);
|
|
|
canvas.addEventListener('mouseleave', moveUpEvent, false);
|
|
|
canvas.addEventListener('mousedown', mouseDownEvent, false);
|
|
|
|
|
|
this.setDrawNeedSeparation = function (needSeparation) {
|
|
|
drawNeedSeparationConfigVal = needSeparation;
|
|
|
drawNeedSeparation = needSeparation;
|
|
|
},
|
|
|
|
|
|
this.setCanvesBodyScale = function (newScale) {
|
|
|
canvesBodyScale = newScale;
|
|
|
ROTATE_ARC_RADIUS = 7 / canvesBodyScale;
|
|
|
RESIZE_ARC_RADIUS = 3 / canvesBodyScale;
|
|
|
ROTATE_DISTANCE = 20 / canvesBodyScale;
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
this.setBorderSize = function(value) {
|
|
|
borderSize = value;
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
this.setBorderColor = function(value) {
|
|
|
borderColor = value;
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
this.setBackgroundColor = function (value) {
|
|
|
if (!value) {
|
|
|
backgroundColor = '#fff';
|
|
|
}
|
|
|
backgroundColor = value;
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
this.redrawCanvas = function () {
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
this.getDragSelectedIndexs = function () {
|
|
|
return dragSelectedIndexs;
|
|
|
}
|
|
|
|
|
|
this.delLayer = function (index) {
|
|
|
layers.splice(index, 1);
|
|
|
|
|
|
selectedLayer = null;
|
|
|
selectedIndex = null;
|
|
|
this.redraw();
|
|
|
}
|
|
|
|
|
|
this.cancelSelectLayer = function () {
|
|
|
selectedLayer = null;
|
|
|
selectedIndex = null;
|
|
|
|
|
|
this.redraw();
|
|
|
|
|
|
if($.type(callbackCanvasCancelSelectLayer) == 'function') {
|
|
|
callbackCanvasCancelSelectLayer();
|
|
|
}
|
|
|
},
|
|
|
|
|
|
this.cancelSelectLayerNotCallback = function () {
|
|
|
dragSelectedIndexs = new Array();
|
|
|
selectedLayer = null;
|
|
|
selectedIndex = null;
|
|
|
this.redraw();
|
|
|
},
|
|
|
|
|
|
this.setSelectedIndex = function (index) {
|
|
|
setSelectedIndex(index);
|
|
|
}
|
|
|
|
|
|
this.getSelectedIndex = function () {
|
|
|
return selectedIndex;
|
|
|
}
|
|
|
|
|
|
this.copyLayer = function(index, callback) {
|
|
|
var layer = layers[index];
|
|
|
if (layer == undefined) {
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
return this.baseCopyLayer(layer,callback);
|
|
|
}
|
|
|
|
|
|
this.copyLayerMulit = function(indexs, callback) {
|
|
|
var copyLayers = [];
|
|
|
for (var i = 0; i < indexs.length; i++) {
|
|
|
var index = indexs[i];
|
|
|
var layer = layers[index];
|
|
|
if (layer != undefined) {
|
|
|
copyLayers.push(layer)
|
|
|
}
|
|
|
}
|
|
|
for (var i = 0; i <copyLayers.length; i++) {
|
|
|
console.log(copyLayers[i])
|
|
|
this.baseCopyLayer(copyLayers[i], callback);
|
|
|
}
|
|
|
_.isFunction(callback) && callback();
|
|
|
}
|
|
|
|
|
|
this.baseCopyLayer = function(layer, callback) {
|
|
|
var layerObj = getLayerInfo(layer);
|
|
|
if (layer instanceof Layer) {
|
|
|
var image = document.createElement("img");
|
|
|
image.crossOrigin = 'anonymous';
|
|
|
image.src = layerObj.imgUrl;
|
|
|
|
|
|
var needInsertIndex = getNeedInsertLayersIndex(layer)
|
|
|
var newLayer = new Layer(image);
|
|
|
newLayer = Object.assign(newLayer,layerObj);
|
|
|
newLayer.canvas.width = newLayer.width;
|
|
|
newLayer.canvas.height = newLayer.height;
|
|
|
newLayer.context.translate(newLayer.width / 2, newLayer.height / 2);
|
|
|
insertLayerToLayersByIndex(newLayer, needInsertIndex);
|
|
|
redrawCanvas();
|
|
|
newLayer.setImgUrl(layerObj.imgUrl);
|
|
|
} else if (layer instanceof LinkLayer){
|
|
|
var needInsertIndex = getNeedInsertLayersIndex(layer)
|
|
|
var newLayer = new LinkLayer();
|
|
|
newLayer = Object.assign(newLayer,layerObj);
|
|
|
insertLayerToLayersByIndex(newLayer, needInsertIndex);
|
|
|
redrawCanvas();
|
|
|
} else {
|
|
|
var needInsertIndex = getNeedInsertLayersIndex(layer)
|
|
|
var newLayer = new TextLayer(layerObj.content,layerObj.style);
|
|
|
newLayer = Object.assign(newLayer,layerObj);
|
|
|
insertLayerToLayersByIndex(newLayer, needInsertIndex);
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
_.isFunction(callback) && callback(newLayer);
|
|
|
return newLayer;
|
|
|
}
|
|
|
|
|
|
this.addLayer = function(img) {
|
|
|
var layer = new Layer(img);
|
|
|
var needInsertIndex = getNeedInsertLayersIndex(layer);
|
|
|
|
|
|
insertLayerToLayersByIndex(layer, needInsertIndex);
|
|
|
redrawCanvas();
|
|
|
return layer;
|
|
|
}
|
|
|
|
|
|
this.addTextLayer = function (content, style) {
|
|
|
var layer = new TextLayer(content, style);
|
|
|
layer.setTitle(content);
|
|
|
var needInsertIndex = getNeedInsertLayersIndex(layer);
|
|
|
|
|
|
insertLayerToLayersByIndex(layer, needInsertIndex);
|
|
|
redrawCanvas();
|
|
|
|
|
|
return layer;
|
|
|
}
|
|
|
|
|
|
this.addLinkLayer = function (shape) {
|
|
|
var newLayer = new LinkLayer();
|
|
|
if (shape) {
|
|
|
newLayer.linkShape = shape;
|
|
|
}
|
|
|
var needInsertIndex = getNeedInsertLayersIndex(newLayer);
|
|
|
|
|
|
insertLayerToLayersByIndex(newLayer, needInsertIndex);
|
|
|
redrawCanvas();
|
|
|
return newLayer;
|
|
|
}
|
|
|
|
|
|
this.redraw = function() {
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
this.getCanvas = function() {
|
|
|
return canvas;
|
|
|
}
|
|
|
this.setBackgroundImage = function(img) {
|
|
|
backgroundImage = img;
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
this.setBackgroundColor = function(color) {
|
|
|
backgroundColor = color;
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
this.getLayers = function() {
|
|
|
return layers;
|
|
|
}
|
|
|
|
|
|
this.setLayers = function (newLayers) {
|
|
|
layers = newLayers;
|
|
|
layers.forEach(function (layer) {
|
|
|
layer.initLayerInfo();
|
|
|
});
|
|
|
redrawCanvas();
|
|
|
},
|
|
|
|
|
|
this.getLayer = function(i) {
|
|
|
return layers[i];
|
|
|
}
|
|
|
this.moveLayerUp = function(i) {
|
|
|
i = parseInt(i);
|
|
|
if (i < layers.length - 1) {
|
|
|
var swapLayer = layers[1 + i];
|
|
|
layers[1 + i] = layers[i];
|
|
|
layers[i] = swapLayer;
|
|
|
redrawCanvas();
|
|
|
return true;
|
|
|
} else {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
this.moveLayerDown = function(i) {
|
|
|
i = parseInt(i);
|
|
|
if (i > 0) {
|
|
|
var swapLayer = layers[i - 1];
|
|
|
layers[i - 1] = layers[i];
|
|
|
layers[i] = swapLayer;
|
|
|
redrawCanvas();
|
|
|
return true;
|
|
|
} else {
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
this.removeLayer = function(i) {
|
|
|
i = parseInt(i);
|
|
|
if (i >= 0 && i < layers.length) {
|
|
|
layers.splice(i,1);
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
this.getCanvesDataToPng = function (drawNeedSpecial) {
|
|
|
return getCanvesDataToPng(drawNeedSpecial);
|
|
|
}
|
|
|
|
|
|
this.saveCanvesData = function() {
|
|
|
window.location.href = this.getCanvesDataToPng;
|
|
|
}
|
|
|
|
|
|
this.setDragSelectedIndexsEmpty = function() {
|
|
|
dragSelectedIndexs = new Array();
|
|
|
}
|
|
|
|
|
|
this.getLayersInfo = function () {
|
|
|
var layerInfos = new Array();
|
|
|
for (var i = 0; i < layers.length; i++) {
|
|
|
var layer = layers[i];
|
|
|
var layerObj = getLayerInfo(layer);
|
|
|
layerInfos.push(layerObj);
|
|
|
}
|
|
|
|
|
|
return layerInfos;
|
|
|
}
|
|
|
|
|
|
this.getSaveCanvasInfo = function () {
|
|
|
return {
|
|
|
layersInfo: this.getLayersInfo(),
|
|
|
imageBase64Data: getCanvesDataToPng(false)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function getLayerInfo (layer) {
|
|
|
var layerObj = new Object();
|
|
|
if (layer instanceof Layer) {
|
|
|
layerObj.type = 'img';
|
|
|
layerObj.width = layer.width;
|
|
|
layerObj.height = layer.height;
|
|
|
layerObj.imgUrl = layer.imgUrl;
|
|
|
layerObj.blendColor = layer.blendColor;
|
|
|
} else if (layer instanceof LinkLayer){
|
|
|
layerObj.type = 'link';
|
|
|
layerObj.linkShape = layer.linkShape;
|
|
|
layerObj.width = layer.width;
|
|
|
layerObj.height = layer.height;
|
|
|
layerObj.linkUrl = layer.linkUrl;
|
|
|
} else {
|
|
|
layerObj.type = 'text';
|
|
|
layerObj.style = layer.style;
|
|
|
layerObj.content = layer.content;
|
|
|
layerObj.fontFamily = layer.fontFamily;
|
|
|
layerObj.width = layer.width;
|
|
|
layerObj.lineHeightScale = layer.lineHeightScale;
|
|
|
var square = layer.getSquare();
|
|
|
var d = square.d;
|
|
|
layerObj.positonDx = d.x;
|
|
|
layerObj.positonDy = d.y;
|
|
|
layerObj.fontSize = layer.fontSize;
|
|
|
layerObj.fontColor = layer.fontColor;
|
|
|
layerObj.layerSubType = layer.layerSubType;
|
|
|
|
|
|
layerObj.hidePriceConfig = layer.hidePriceConfig;
|
|
|
layerObj.formatPriceConfig = layer.formatPriceConfig;
|
|
|
layerObj.discountPriceConfig = layer.discountPriceConfig;
|
|
|
layerObj.textAlignPriceConfig = layer.textAlignPriceConfig;
|
|
|
layerObj.fullMinusConfig = layer.fullMinusConfig;
|
|
|
layerObj.priceCountTypeConfig = layer.priceCountTypeConfig;
|
|
|
|
|
|
layerObj.bold = layer.bold;
|
|
|
layerObj.italic = layer.italic;
|
|
|
layerObj.underline = layer.underline;
|
|
|
layerObj.strikethrough = layer.strikethrough;
|
|
|
}
|
|
|
layerObj.offsetX = layer.offsetX;
|
|
|
layerObj.offsetY = layer.offsetY;
|
|
|
layerObj.opacity = layer.opacity;
|
|
|
layerObj.visible = layer.visible;
|
|
|
layerObj.angle = layer.angle;
|
|
|
return layerObj;
|
|
|
}
|
|
|
|
|
|
function setSelectedIndex(index) {
|
|
|
selectedLayer = layers[index];
|
|
|
if (!selectedLayer) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
selectedIndex = index;
|
|
|
redrawCanvas();
|
|
|
|
|
|
if($.type(callbackCanvasSelectLayer) == 'function') {
|
|
|
callbackCanvasSelectLayer();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function getNeedInsertLayersIndex(layer) {
|
|
|
if ($.inArray(layer.layerSubType, spacialLayerSubTypeArr) !== -1) {
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
if (!layers) {
|
|
|
return null;
|
|
|
}
|
|
|
for (var i = 0; i < layers.length; i++) {
|
|
|
var layer = layers[i];
|
|
|
|
|
|
if ($.inArray(layer.layerSubType, spacialLayerSubTypeArr) === -1) {
|
|
|
return i;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return i;
|
|
|
}
|
|
|
|
|
|
function insertLayerToLayersByIndex(needInsertLayer, needInsertIndex) {
|
|
|
if (needInsertLayer === null) {
|
|
|
return ;
|
|
|
}
|
|
|
if (needInsertIndex === null) {
|
|
|
return;
|
|
|
}
|
|
|
needInsertIndex = parseInt(needInsertIndex);
|
|
|
for (var i = layers.length; i >= 0; i--) {
|
|
|
if (i == needInsertIndex) {
|
|
|
layers[i] = needInsertLayer;
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
layers[i] = layers[i-1];
|
|
|
}
|
|
|
setSelectedIndex(needInsertIndex);
|
|
|
}
|
|
|
|
|
|
function getCanvesDataToPng (needSpecial) {
|
|
|
drawNeedMaker = false;
|
|
|
drawNeedSpecial = needSpecial ? true : false;
|
|
|
drawNeedSeparation = 0;
|
|
|
redrawCanvas();
|
|
|
|
|
|
var image = new Image();
|
|
|
image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream;");
|
|
|
drawNeedMaker = true;
|
|
|
drawNeedSpecial = true;
|
|
|
|
|
|
drawNeedSeparation = drawNeedSeparationConfigVal;
|
|
|
return image;
|
|
|
}
|
|
|
|
|
|
function redrawBorder () {
|
|
|
if (!borderColor || !borderSize) {
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
context.beginPath();
|
|
|
context.rect(0, 0, canvas.width, canvas.height);
|
|
|
context.lineWidth = borderSize;
|
|
|
context.strokeStyle = borderColor;
|
|
|
context.stroke();
|
|
|
}
|
|
|
|
|
|
function redrawCanvas() {
|
|
|
canvas.style.cursor = cursorStyle;
|
|
|
|
|
|
if (backgroundImage != null) {
|
|
|
context.drawImage(backgroundImage, 0, 0, canvas.width, canvas.height);
|
|
|
} else if (backgroundColor != null && backgroundColor != "") {
|
|
|
context.fillStyle = backgroundColor;
|
|
|
context.fillRect(0, 0, canvas.width, canvas.height);
|
|
|
} else {
|
|
|
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
|
}
|
|
|
|
|
|
for (var i = (layers.length - 1); i >= 0; i--) {
|
|
|
var layer = layers[i];
|
|
|
var layerSubType = layer.hasOwnProperty("layerSubType") ? layer.layerSubType : null;
|
|
|
if (($.inArray(layer.layerSubType, spacialLayerSubTypeArr) !== -1) && !drawNeedSpecial) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
if (layers[i].isVisible()) {
|
|
|
context.save();
|
|
|
|
|
|
context.globalAlpha = layers[i].getOpacity();
|
|
|
context.globalCompositeOperation = layers[i].getCompositeOperation();
|
|
|
|
|
|
if (layers[i].hasShadow()) {
|
|
|
context.shadowColor = "#000";
|
|
|
context.shadowOffsetX = 3;
|
|
|
context.shadowOffsetY = 3;
|
|
|
context.shadowBlur = 15;
|
|
|
}
|
|
|
|
|
|
context.translate(layers[i].offsetX + (layers[i].width / 2), getTranslateY(layers[i]));
|
|
|
context.rotate(layers[i].getAngle());
|
|
|
|
|
|
context.drawImage(layers[i].getCanvas(), 0 - (layers[i].width / 2), 0 - (layers[i].height / 2));
|
|
|
|
|
|
context.restore();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (drawNeedMaker) {
|
|
|
drawSelectMarker();
|
|
|
drawListImgSeparation();
|
|
|
drawMouseDragMarker();
|
|
|
drawSelectLayersMarker();
|
|
|
}
|
|
|
|
|
|
redrawBorder();
|
|
|
}
|
|
|
|
|
|
function getTranslateY(layer) {
|
|
|
layer = layer || {};
|
|
|
var layerSubType = layer.hasOwnProperty("layerSubType") ? layer.layerSubType : null;
|
|
|
var isSpacialLayer = ($.inArray(layer.layerSubType, spacialLayerSubTypeArr) !== -1);
|
|
|
|
|
|
var translateY = layer.offsetY + (layer.height / 2);
|
|
|
if (layer.layerType == 'text' && !isSpacialLayer) {
|
|
|
translateY = translateY - 10;
|
|
|
}
|
|
|
|
|
|
return translateY;
|
|
|
}
|
|
|
|
|
|
function drawArc(x, y, r) {
|
|
|
context.save();
|
|
|
context.globalAlpha = 1;
|
|
|
|
|
|
context.beginPath();
|
|
|
context.arc(x, y, r, 0, 2 * Math.PI);
|
|
|
|
|
|
context.lineWidth = 4;
|
|
|
context.strokeStyle = 'red';
|
|
|
context.stroke();
|
|
|
|
|
|
context.fillStyle = '#fff';
|
|
|
context.fill();
|
|
|
context.closePath();
|
|
|
|
|
|
context.restore();
|
|
|
}
|
|
|
|
|
|
function drawSelectLayersMarker() {
|
|
|
if (!dragSelectedIndexs) {
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
if (dragSelectedIndexs.length < 1) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
for(var i = 0; i < dragSelectedIndexs.length; i++) {
|
|
|
drawMarkerRectangle(layers[dragSelectedIndexs[i]]);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
function drawMouseDragMarker() {
|
|
|
if (!startClickVector || !endClickVector || !mouseDownNotInLayer) {
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
context.fillStyle = 'rgba(26,75,171,0.2)';
|
|
|
context.strokeStyle = "rgba(26,75,171,0.8)";
|
|
|
context.lineWidth = 2;
|
|
|
var endX = endClickVector.x;
|
|
|
var endY = endClickVector.y;
|
|
|
var startX = startClickVector.x;
|
|
|
var startY = startClickVector.y;
|
|
|
|
|
|
var width = endX - startX;
|
|
|
var height = endY - startY;
|
|
|
|
|
|
context.fillRect(startX, startY, width, height); //填充的四个参数(x,y,width,height)
|
|
|
context.strokeRect(startX, startY, width, height);
|
|
|
|
|
|
}
|
|
|
|
|
|
function drawListImgSeparation() {
|
|
|
if (drawNeedSeparation < 1) {
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
context.beginPath();
|
|
|
for (var i = 0; i < 100; i++) {
|
|
|
context[i%2 == 0 ? 'moveTo' : 'lineTo'](SEPARATION_X1, 8*i);
|
|
|
}
|
|
|
context.strokeStyle = "#382727";
|
|
|
context.stroke();
|
|
|
|
|
|
context.beginPath();
|
|
|
for (var i = 0; i < 100; i++) {
|
|
|
context[i%2 == 0 ? 'moveTo' : 'lineTo'](SEPARATION_X2, 8*i);
|
|
|
}
|
|
|
context.strokeStyle = "#382727";
|
|
|
context.stroke();
|
|
|
}
|
|
|
|
|
|
function drawMarker(layer, i) {
|
|
|
if (i !== selectedIndex) {
|
|
|
cursorStyle = 'pointer';
|
|
|
}
|
|
|
redrawCanvas();
|
|
|
|
|
|
if (i !== selectedIndex) {
|
|
|
drawMarkerRectangle(layer);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function drawMarkerRectangle(layer) {
|
|
|
if (layer) {
|
|
|
context.save();
|
|
|
context.lineWidth= 2;
|
|
|
context.strokeStyle = "#045e91";
|
|
|
context.globalAlpha = 0.75;
|
|
|
|
|
|
context.translate(layer.offsetX + (layer.width / 2), getTranslateY(layer));
|
|
|
context.rotate(layer.getAngle());
|
|
|
|
|
|
context.strokeRect(0 - (layer.width / 2), 0 - (layer.height / 2),
|
|
|
layer.width, layer.height);
|
|
|
context.restore();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function drawSelectMarker() {
|
|
|
if (!selectedLayer) {
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
context.save();
|
|
|
context.lineWidth= 2;
|
|
|
context.strokeStyle = "#045e91";
|
|
|
context.globalAlpha = 0.75;
|
|
|
|
|
|
var offsetX = selectedLayer.offsetX;
|
|
|
var offsetY = selectedLayer.offsetY;
|
|
|
var width = selectedLayer.width;
|
|
|
var height = selectedLayer.height;
|
|
|
|
|
|
//画个矩形框框
|
|
|
context.translate(offsetX + (width / 2), getTranslateY(selectedLayer));
|
|
|
context.rotate(selectedLayer.getAngle());
|
|
|
context.strokeRect(-width / 2, - height / 2, width, height);
|
|
|
|
|
|
var offsetX = -width / 2;
|
|
|
var offsetY = -height / 2;
|
|
|
//画旋转图标,如果不是热区
|
|
|
if (!(selectedLayer instanceof LinkLayer)) {
|
|
|
context.beginPath();
|
|
|
context.moveTo(offsetX + width/2, offsetY);
|
|
|
context.lineTo(offsetX + width/2, offsetY-ROTATE_DISTANCE);
|
|
|
context.stroke();
|
|
|
drawArc(offsetX + width/2, offsetY-ROTATE_DISTANCE, ROTATE_ARC_RADIUS);
|
|
|
}
|
|
|
//如果不是文本,则有四个边的缩放
|
|
|
if (selectedLayer instanceof TextLayer) {
|
|
|
if (selectedLayer.allowResetWidth) {
|
|
|
drawArc(offsetX, offsetY + height / 2, RESIZE_ARC_RADIUS);
|
|
|
drawArc(offsetX + width, offsetY + height / 2, RESIZE_ARC_RADIUS);
|
|
|
}
|
|
|
context.restore();
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
//四个角缩放图标
|
|
|
drawArc(offsetX, offsetY, RESIZE_ARC_RADIUS);
|
|
|
drawArc(offsetX + width, offsetY, RESIZE_ARC_RADIUS);
|
|
|
drawArc(offsetX, offsetY + height, RESIZE_ARC_RADIUS);
|
|
|
drawArc(offsetX + width, offsetY + height, RESIZE_ARC_RADIUS);
|
|
|
|
|
|
//圆形热区无法单表缩放
|
|
|
if (selectedLayer.linkShape != 'circle') {
|
|
|
drawArc(offsetX + width / 2, offsetY, RESIZE_ARC_RADIUS);
|
|
|
drawArc(offsetX, offsetY + height / 2, RESIZE_ARC_RADIUS);
|
|
|
drawArc(offsetX + width, offsetY + height / 2, RESIZE_ARC_RADIUS);
|
|
|
drawArc(offsetX + width / 2, offsetY + height, RESIZE_ARC_RADIUS);
|
|
|
}
|
|
|
|
|
|
context.restore();
|
|
|
}
|
|
|
|
|
|
function moveOutEvent(e) {
|
|
|
mouseDown = false;
|
|
|
startClickVector = null;
|
|
|
endClickVector = null;
|
|
|
layerState = NONE;
|
|
|
|
|
|
if (mouseDownNotInLayer) {
|
|
|
buildVirtualLayerContainSelectLayers();
|
|
|
mouseMoveEvent(e);
|
|
|
redrawCanvas();
|
|
|
mouseDownNotInLayer = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function moveUpEvent(e) {
|
|
|
mouseDown = false;
|
|
|
startClickVector = null;
|
|
|
endClickVector = null;
|
|
|
layerState = NONE;
|
|
|
|
|
|
if (mouseDownNotInLayer) {
|
|
|
buildVirtualLayerContainSelectLayers();
|
|
|
mouseMoveEvent(e);
|
|
|
redrawCanvas();
|
|
|
mouseDownNotInLayer = false;
|
|
|
}
|
|
|
|
|
|
if($.type(callbackCanvasSelectLayer) == 'function') {
|
|
|
callbackCanvasSelectLayer();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function mouseDownEvent(e) {
|
|
|
mouseDown = true;
|
|
|
mouseDownNotInLayer = false;
|
|
|
endClickVector = null;
|
|
|
var x = getCanvesOpsitionX(e);
|
|
|
var y = getCanvesOpsitionY(e);
|
|
|
startClickVector = new Vector(x, y);
|
|
|
|
|
|
mouseMoveEvent(e);
|
|
|
}
|
|
|
|
|
|
function mouseMoveEvent(e) {
|
|
|
canvasOffsetX = $("#" + canvasId).offset().left;
|
|
|
canvasOffsetY = $("#" + canvasId).offset().top;
|
|
|
|
|
|
if (startClickVector && mouseDownNotInLayer) {
|
|
|
endClickVector = new Vector(getCanvesOpsitionX(e), getCanvesOpsitionY(e));
|
|
|
}
|
|
|
|
|
|
checkAndDoScalingTop(e);
|
|
|
checkAndDoScalingRight(e);
|
|
|
checkAndDoScalingBottom(e);
|
|
|
checkAndDoScalingLeft(e);
|
|
|
|
|
|
checkAndDoScalingLeftTop(e);
|
|
|
checkAndDoScalingRightTop(e);
|
|
|
checkAndDoScalingLeftBottom(e);
|
|
|
checkAndDoScalingRightBottom(e);
|
|
|
checkAndDoRotating(e);
|
|
|
checkAndDoMoving(e);
|
|
|
|
|
|
if (layers.length > 0 && (layerState == NONE || !mouseDown)) {
|
|
|
if (mouseDownNotInLayer) {
|
|
|
checkAndSelectDragLayers(e);
|
|
|
} else {
|
|
|
checkAndSelectSingleLayer(e);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
mousePrevX = getCanvesOpsitionX(e);
|
|
|
mousePrevY = getCanvesOpsitionY(e);
|
|
|
|
|
|
}
|
|
|
|
|
|
function checkAndDoMoving(e) {
|
|
|
if (layerState != MOVING) {
|
|
|
return ;
|
|
|
}
|
|
|
if (!mouseDown || mouseDownNotInLayer) {
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
var offsetX = getCanvesOpsitionX(e) - mousePrevX;
|
|
|
var offsetY = getCanvesOpsitionY(e) - mousePrevY;
|
|
|
selectedLayer.offsetX += offsetX;
|
|
|
selectedLayer.offsetY += offsetY;
|
|
|
|
|
|
if (selectedLayer.layerType == 'virtual') {
|
|
|
moveDragSelectedLayers(offsetX, offsetY);
|
|
|
} else {
|
|
|
selectedLayer.resetBorderOffset();
|
|
|
if($.type(callbackSizeOrPositionChange) == 'function') {
|
|
|
callbackSizeOrPositionChange(selectedLayer);
|
|
|
}
|
|
|
}
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
function checkAndDoRotating(e) {
|
|
|
if (layerState != ROTATING) {
|
|
|
return ;
|
|
|
}
|
|
|
if (!mouseDown || mouseDownNotInLayer) {
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
var originX = selectedLayer.offsetX + (selectedLayer.width / 2);
|
|
|
var originY = selectedLayer.offsetY + (selectedLayer.height / 2);
|
|
|
var mouseX = getCanvesOpsitionX(e);
|
|
|
var mouseY = getCanvesOpsitionY(e);
|
|
|
|
|
|
var angle = Math.atan2((mouseY - originY), (mouseX - originX));
|
|
|
angle = parseFloat(angle);
|
|
|
|
|
|
var sourceAngle = Math.PI / 2;
|
|
|
sourceAngle = parseFloat(sourceAngle);
|
|
|
angle = angle + sourceAngle;
|
|
|
|
|
|
selectedLayer.setAngle(angle);
|
|
|
if (selectedLayer.layerType == 'virtual') {
|
|
|
rotatingDragSelectLayers(angle);
|
|
|
} else {
|
|
|
if($.type(callbackSizeOrPositionChange) == 'function') {
|
|
|
callbackSizeOrPositionChange(selectedLayer);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
function checkAndDoScalingLeft(e) {
|
|
|
if (layerState != SCALING_LEFT) {
|
|
|
return ;
|
|
|
}
|
|
|
if (!mouseDown || mouseDownNotInLayer) {
|
|
|
return ;
|
|
|
}
|
|
|
var square = selectedLayer.getSquare();
|
|
|
|
|
|
var leftCenterX = square.a.x + (square.d.x - square.a.x) / 2;
|
|
|
var leftCenterY = square.a.y + (square.d.y - square.a.y) / 2;
|
|
|
|
|
|
var newWidth = getResizeWidthOrHeightNewLength(e, square.b, square.c);
|
|
|
var newRightCenter = buildResizeWidthOrHeightNewFixedDot(newWidth, new Vector(leftCenterX, leftCenterY), square.b, square.c);
|
|
|
|
|
|
selectedLayer.offsetX = newRightCenter.x - newWidth;
|
|
|
selectedLayer.offsetY = newRightCenter.y - selectedLayer.height / 2;
|
|
|
|
|
|
selectedLayer.width = newWidth;
|
|
|
selectedLayer.initLayerInfo();
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
function checkAndDoScalingRight(e) {
|
|
|
if (layerState != SCALING_RIGHT) {
|
|
|
return ;
|
|
|
}
|
|
|
if (!mouseDown || mouseDownNotInLayer) {
|
|
|
return ;
|
|
|
}
|
|
|
var square = selectedLayer.getSquare();
|
|
|
|
|
|
var rightCenterX = square.b.x + (square.c.x - square.b.x) / 2;
|
|
|
var rightCenterY = square.b.y + (square.c.y - square.b.y) / 2;
|
|
|
|
|
|
var newWidth = getResizeWidthOrHeightNewLength(e, square.a, square.d);
|
|
|
var newLeftCenter = buildResizeWidthOrHeightNewFixedDot(newWidth, new Vector(rightCenterX, rightCenterY), square.a, square.d);
|
|
|
|
|
|
selectedLayer.offsetX = newLeftCenter.x;
|
|
|
selectedLayer.offsetY = newLeftCenter.y - selectedLayer.height / 2;
|
|
|
|
|
|
selectedLayer.width = newWidth;
|
|
|
selectedLayer.initLayerInfo();
|
|
|
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
function checkAndDoScalingBottom(e) {
|
|
|
if (layerState != SCALING_BOTTOM) {
|
|
|
return ;
|
|
|
}
|
|
|
if (!mouseDown || mouseDownNotInLayer) {
|
|
|
return ;
|
|
|
}
|
|
|
var square = selectedLayer.getSquare();
|
|
|
|
|
|
var bottomCenterX = square.c.x + (square.d.x - square.c.x) / 2;
|
|
|
var bottomCenterY = square.c.y + (square.d.y - square.c.y) / 2;
|
|
|
|
|
|
var newHeight = getResizeWidthOrHeightNewLength(e, square.a, square.b);
|
|
|
var newTopCenter = buildResizeWidthOrHeightNewFixedDot(newHeight, new Vector(bottomCenterX, bottomCenterY), square.a, square.b);
|
|
|
|
|
|
selectedLayer.offsetX = newTopCenter.x - selectedLayer.width / 2;
|
|
|
selectedLayer.offsetY = newTopCenter.y;
|
|
|
|
|
|
selectedLayer.height = newHeight;
|
|
|
selectedLayer.initLayerInfo();
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
function checkAndDoScalingTop(e) {
|
|
|
if (layerState != SCALING_TOP) {
|
|
|
return ;
|
|
|
}
|
|
|
if (!mouseDown || mouseDownNotInLayer) {
|
|
|
return ;
|
|
|
}
|
|
|
var square = selectedLayer.getSquare();
|
|
|
|
|
|
var topCenterX = square.a.x + (square.b.x - square.a.x) / 2;
|
|
|
var topCenterY = square.a.y + (square.b.y - square.a.y) / 2;
|
|
|
|
|
|
var newHeight = getResizeWidthOrHeightNewLength(e, square.d, square.c);
|
|
|
var newBottomCenter = buildResizeWidthOrHeightNewFixedDot(newHeight, new Vector(topCenterX, topCenterY), square.d, square.c);
|
|
|
|
|
|
selectedLayer.offsetX = newBottomCenter.x - selectedLayer.width / 2;
|
|
|
selectedLayer.offsetY = newBottomCenter.y - newHeight;
|
|
|
|
|
|
selectedLayer.height = newHeight;
|
|
|
selectedLayer.initLayerInfo();
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 当缩放宽或高时,视觉上对边的位置是固定的
|
|
|
*/
|
|
|
function buildResizeWidthOrHeightNewFixedDot(newLength, operateDot, fixedDot1, fixedDot2) {
|
|
|
var fixedCenterX = fixedDot1.x + (fixedDot2.x - fixedDot1.x) / 2;
|
|
|
var fixedCenterY = fixedDot1.y + (fixedDot2.y - fixedDot1.y) / 2;
|
|
|
var angle = Math.atan2(operateDot.y - fixedCenterY, operateDot.x - fixedCenterX);
|
|
|
|
|
|
var newOperateDotX = fixedCenterX + newLength * Math.cos(angle);
|
|
|
var newOperateDotY = fixedCenterY + newLength * Math.sin(angle);
|
|
|
|
|
|
var newOriginX = fixedCenterX + (newOperateDotX - fixedCenterX) / 2;
|
|
|
var newOriginY = fixedCenterY + (newOperateDotY - fixedCenterY) / 2;
|
|
|
|
|
|
return selectedLayer.dot1AroundDot2Roate(new Vector(fixedCenterX, fixedCenterY), new Vector(newOriginX, newOriginY), -selectedLayer.angle);
|
|
|
}
|
|
|
|
|
|
function getResizeWidthOrHeightNewLength(e, fixedDot1, fixedDot2) {
|
|
|
var A = fixedDot1.y - fixedDot2.y;
|
|
|
var B = fixedDot2.x - fixedDot1.x;
|
|
|
var C = fixedDot1.x * fixedDot2.y - fixedDot2.x * fixedDot1.y;
|
|
|
return Math.abs(A * getCanvesOpsitionX(e) + B * getCanvesOpsitionY(e) + C) / Math.sqrt(A*A + B*B);
|
|
|
}
|
|
|
|
|
|
function checkAndDoScalingRightBottom(e) {
|
|
|
if (layerState != SCALING_RIGHT_BOTTOM) {
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
if (!mouseDown || mouseDownNotInLayer) {
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
var square = selectedLayer.getSquare();
|
|
|
var newWidthAndHeight = getResizeNewWidthAndHeight(e, square.d);
|
|
|
|
|
|
var newDotA = buildResizeWidthAndHeightNewFixedDot(e, newWidthAndHeight, square.c, square.a);
|
|
|
selectedLayer.offsetX = newDotA.x;
|
|
|
selectedLayer.offsetY = newDotA.y;
|
|
|
selectedLayer.width = newWidthAndHeight.newWidth;
|
|
|
selectedLayer.height = newWidthAndHeight.newHeight;
|
|
|
selectedLayer.initLayerInfo();
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
function checkAndDoScalingLeftBottom(e) {
|
|
|
if (layerState != SCALING_LEFT_BOTTOM) {
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
if (!mouseDown || mouseDownNotInLayer) {
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
var square = selectedLayer.getSquare();
|
|
|
var newWidthAndHeight = getResizeNewWidthAndHeight(e, square.c);
|
|
|
|
|
|
var newDotB = buildResizeWidthAndHeightNewFixedDot(e, newWidthAndHeight, square.d, square.b);
|
|
|
selectedLayer.offsetX = newDotB.x - newWidthAndHeight.newWidth;
|
|
|
selectedLayer.offsetY = newDotB.y;
|
|
|
selectedLayer.width = newWidthAndHeight.newWidth;
|
|
|
selectedLayer.height = newWidthAndHeight.newHeight;
|
|
|
selectedLayer.initLayerInfo();
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
function checkAndDoScalingRightTop(e) {
|
|
|
if (layerState != SCALING_RIGHT_TOP) {
|
|
|
return ;
|
|
|
}
|
|
|
if (!mouseDown || mouseDownNotInLayer) {
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
var square = selectedLayer.getSquare();
|
|
|
|
|
|
var newWidthAndHeight = getResizeNewWidthAndHeight(e, square.a);
|
|
|
|
|
|
var newDotD = buildResizeWidthAndHeightNewFixedDot(e, newWidthAndHeight, square.b, square.d);
|
|
|
selectedLayer.offsetX = newDotD.x;
|
|
|
selectedLayer.offsetY = newDotD.y - newWidthAndHeight.newHeight;
|
|
|
selectedLayer.width = newWidthAndHeight.newWidth;
|
|
|
selectedLayer.height = newWidthAndHeight.newHeight;
|
|
|
selectedLayer.initLayerInfo();
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
function checkAndDoScalingLeftTop(e) {
|
|
|
if (layerState != SCALING_LEFT_TOP) {
|
|
|
return ;
|
|
|
}
|
|
|
if (!mouseDown || mouseDownNotInLayer) {
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
var square = selectedLayer.getSquare();
|
|
|
var newWidthAndHeight = getResizeNewWidthAndHeight(e, square.b);
|
|
|
|
|
|
var newDotC = buildResizeWidthAndHeightNewFixedDot(e, newWidthAndHeight, square.a, square.c);
|
|
|
selectedLayer.offsetX = newDotC.x - newWidthAndHeight.newWidth;
|
|
|
selectedLayer.offsetY = newDotC.y - newWidthAndHeight.newHeight;
|
|
|
selectedLayer.width = newWidthAndHeight.newWidth;
|
|
|
selectedLayer.height = newWidthAndHeight.newHeight;
|
|
|
selectedLayer.initLayerInfo();
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 同时缩放宽高时,视觉上对角的那个点是不变的
|
|
|
* 此方法用户得到视觉上不变的那个点没旋转之前的坐标
|
|
|
* operateDot 鼠标拖动的那个点
|
|
|
* fixedDot 鼠标拖动点的对角点
|
|
|
*/
|
|
|
function buildResizeWidthAndHeightNewFixedDot(e, newWidthAndHeight, operateDot, fixedDot) {
|
|
|
var newWidth = newWidthAndHeight.newWidth;
|
|
|
var newHeight = newWidthAndHeight.newHeight;
|
|
|
|
|
|
var square = selectedLayer.getSquare();
|
|
|
var origin = square.origin;
|
|
|
var diagonalLineAngle = Math.atan2(operateDot.y - fixedDot.y, operateDot.x - fixedDot.x);
|
|
|
var diagonalLineLengh = Math.sqrt(Math.pow(newWidth, 2) + Math.pow(newHeight, 2));
|
|
|
|
|
|
var newOperateDotX = fixedDot.x + diagonalLineLengh * Math.cos(diagonalLineAngle);
|
|
|
var newOperateDotY = fixedDot.y + diagonalLineLengh * Math.sin(diagonalLineAngle);
|
|
|
|
|
|
var newOriginX = fixedDot.x + (newOperateDotX - fixedDot.x) / 2;
|
|
|
var newOriginY = fixedDot.y + (newOperateDotY - fixedDot.y) / 2;
|
|
|
|
|
|
return selectedLayer.dot1AroundDot2Roate(fixedDot, new Vector(newOriginX, newOriginY), -selectedLayer.angle);
|
|
|
}
|
|
|
|
|
|
function buildResizeWidthAndHeightNewFixedDotOld(e, newWidthAndHeight, operateDot, fixedDot) {
|
|
|
var newWidth = newWidthAndHeight.newWidth;
|
|
|
var newHeight = newWidthAndHeight.newHeight;
|
|
|
|
|
|
var square = selectedLayer.getSquare();
|
|
|
var origin = square.origin;
|
|
|
var diagonalLineAngle = Math.atan2(fixedDot.y - operateDot.y, operateDot.x - fixedDot.x);
|
|
|
var diagonalLineLengh = Math.sqrt(Math.pow(newWidth, 2) + Math.pow(newHeight, 2));
|
|
|
|
|
|
var newOperateDotX = fixedDot.x + diagonalLineLengh * Math.cos(diagonalLineAngle);
|
|
|
var newOperateDotY = fixedDot.y - diagonalLineLengh * Math.sin(diagonalLineAngle);
|
|
|
|
|
|
var newOriginX = fixedDot.x + (newOperateDotX - fixedDot.x) / 2;
|
|
|
var newOriginY = fixedDot.y + (newOperateDotY - fixedDot.y) / 2;
|
|
|
|
|
|
return selectedLayer.dot1AroundDot2Roate(fixedDot, new Vector(newOriginX, newOriginY), -selectedLayer.angle);
|
|
|
}
|
|
|
|
|
|
function getResizeNewWidthAndHeight(e, widthNearDot) {
|
|
|
var newWidth = Math.sqrt(Math.pow(widthNearDot.x - getCanvesOpsitionX(e), 2) + Math.pow(widthNearDot.y - getCanvesOpsitionY(e), 2));
|
|
|
var width = selectedLayer.width;
|
|
|
var height = selectedLayer.height;
|
|
|
if (width <= 0) {
|
|
|
var scale = 100;
|
|
|
} else {
|
|
|
var scale = newWidth/width;
|
|
|
}
|
|
|
var newHeight = selectedLayer.height * scale;
|
|
|
return {
|
|
|
'newWidth' : newWidth,
|
|
|
'newHeight' : newHeight,
|
|
|
};
|
|
|
}
|
|
|
|
|
|
function rotatingDragSelectLayers(angle) {
|
|
|
var temp = angle;
|
|
|
var angle = angle - rotatePrevValue;
|
|
|
rotatePrevValue = temp;
|
|
|
|
|
|
if (dragSelectedIndexs.length <= 1) {
|
|
|
return ;
|
|
|
}
|
|
|
var rotatePosition = selectedLayer.getSquare().origin;
|
|
|
for (var i = 0; i < dragSelectedIndexs.length; i++) {
|
|
|
var layer = layers[dragSelectedIndexs[i]];
|
|
|
layer.rotateOrderAngleAndPosition(rotatePosition, angle);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function moveDragSelectedLayers(offsetX, offsetY) {
|
|
|
if (dragSelectedIndexs.length <= 1) {
|
|
|
return ;
|
|
|
}
|
|
|
for (var i = 0; i < dragSelectedIndexs.length; i++) {
|
|
|
var layer = layers[dragSelectedIndexs[i]];
|
|
|
layer.offsetX += offsetX;
|
|
|
layer.offsetY += offsetY;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function checkAndSelectDragLayers(e) {
|
|
|
var dragSquare = getDragSquare();
|
|
|
if (!dragSquare) {
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
dragSelectedIndexs = new Array();
|
|
|
for (var i = 0; i < layers.length; i++) {
|
|
|
if (layers[i] instanceof LinkLayer) {
|
|
|
continue;
|
|
|
}
|
|
|
if (layers[i].intersectSquare(dragSquare) && layers[i].isVisible()) {
|
|
|
dragSelectedIndexs.push(i);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
function getDragSquare() {
|
|
|
if (!endClickVector || !startClickVector) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
var endX = endClickVector.x;
|
|
|
var endY = endClickVector.y;
|
|
|
var startX = startClickVector.x;
|
|
|
var startY = startClickVector.y;
|
|
|
|
|
|
var minX = (startX < endX) ? startX : endX;
|
|
|
var minY = (startY < endY) ? startY : endY;
|
|
|
|
|
|
var maxX = (startX > endX) ? startX : endX;
|
|
|
var maxY = (startY > endY) ? startY : endY;
|
|
|
|
|
|
var width = maxX - minX;
|
|
|
var height = maxY - minY;
|
|
|
|
|
|
if (width <= 0 || height <= 0) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
|
|
|
return new Square(
|
|
|
new Vector(minX, minY),
|
|
|
new Vector(minX, maxY),
|
|
|
new Vector(maxX, maxY),
|
|
|
new Vector(maxX, minY)
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
function buildVirtualLayerContainSelectLayers() {
|
|
|
if (dragSelectedIndexs.length <= 1) {
|
|
|
return ;
|
|
|
}
|
|
|
if (selectedLayer) {
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
var xArr = new Array();
|
|
|
var yArr = new Array();
|
|
|
for (var i = 0; i < dragSelectedIndexs.length; i++) {
|
|
|
var layer = layers[dragSelectedIndexs[i]];
|
|
|
square = layer.getSquare();
|
|
|
var a = square.a;
|
|
|
var b = square.b;
|
|
|
var c = square.c;
|
|
|
var d = square.d;
|
|
|
|
|
|
xArr.push(a.x);
|
|
|
xArr.push(b.x);
|
|
|
xArr.push(c.x);
|
|
|
xArr.push(d.x);
|
|
|
|
|
|
yArr.push(a.y);
|
|
|
yArr.push(b.y);
|
|
|
yArr.push(c.y);
|
|
|
yArr.push(d.y);
|
|
|
|
|
|
}
|
|
|
|
|
|
var minX = parseInt(Math.min.apply(null, xArr)) - 10;
|
|
|
var maxX = parseInt(Math.max.apply(null, xArr)) + 10;
|
|
|
var minY = parseInt(Math.min.apply(null, yArr)) - 10;
|
|
|
var maxY = parseInt(Math.max.apply(null, yArr)) + 10;
|
|
|
|
|
|
var virtualLayer = new TextLayer("content", {
|
|
|
'fontFamily' : 'SimHei',
|
|
|
'fontSize' : 12,
|
|
|
'fontColor' : 'red',
|
|
|
'fixedWidth' : false,
|
|
|
});
|
|
|
virtualLayer.offsetX = minX;
|
|
|
virtualLayer.offsetY = minY;
|
|
|
virtualLayer.width = maxX - minX;
|
|
|
virtualLayer.height = maxY - minY;
|
|
|
virtualLayer.layerType = 'virtual';
|
|
|
|
|
|
selectedLayer = virtualLayer;
|
|
|
selectedIndex = -1;
|
|
|
}
|
|
|
|
|
|
function checkAndSelectSingleLayer(e) {
|
|
|
if (checkAndGetLayerState(e)) {
|
|
|
cursorStyle = canvas.style.cursor;
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
cursorStyle = canvas.style.cursor;
|
|
|
var hasSelect = checkAndSelectLayer(e);
|
|
|
if (!hasSelect && mouseDown) {
|
|
|
mouseDownNotInLayer = true;
|
|
|
selectedLayer = null;
|
|
|
rotatePrevValue = 0;
|
|
|
selectedIndex = null;
|
|
|
if($.type(callbackCanvasCancelSelectLayer) == 'function') {
|
|
|
callbackCanvasCancelSelectLayer();
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!hasSelect) {
|
|
|
cursorStyle = 'default';
|
|
|
redrawCanvas();
|
|
|
}
|
|
|
|
|
|
if (mouseDown) {
|
|
|
dragSelectedIndexs = new Array();
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
function checkAndSelectLayer(e) {
|
|
|
for (var i = 0; i < layers.length; i++) {
|
|
|
if (!layers[i].isVisible()) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
if (!layers[i].intersect(getCanvesOpsitionX(e), getCanvesOpsitionY(e))) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
if (mouseDown) {
|
|
|
selectedLayer = layers[i];
|
|
|
selectedIndex = i;
|
|
|
|
|
|
if($.type(callbackCanvasSelectLayer) == 'function') {
|
|
|
callbackCanvasSelectLayer();
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
layerState = mouseDown ? MOVING : NONE;
|
|
|
cursorStyle = 'move';
|
|
|
|
|
|
drawMarker(layers[i], i);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
function checkAndGetLayerState(e) {
|
|
|
if (!selectedLayer) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (isResizeLeftTopArea(getCanvesOpsitionX(e), getCanvesOpsitionY(e), selectedLayer)) {
|
|
|
canvas.style.cursor = getResizeCursorStyle(SCALING_LEFT_TOP, selectedLayer.angle);
|
|
|
layerState = mouseDown ? SCALING_LEFT_TOP : NONE;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (isResizeTopArea(getCanvesOpsitionX(e), getCanvesOpsitionY(e), selectedLayer)) {
|
|
|
canvas.style.cursor = getResizeCursorStyle(SCALING_TOP, selectedLayer.angle);
|
|
|
layerState = mouseDown ? SCALING_TOP : NONE;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (isResizeRightTopArea(getCanvesOpsitionX(e), getCanvesOpsitionY(e), selectedLayer)) {
|
|
|
canvas.style.cursor = getResizeCursorStyle(SCALING_RIGHT_TOP, selectedLayer.angle);
|
|
|
layerState = mouseDown ? SCALING_RIGHT_TOP : NONE;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (isResizeRightArea(getCanvesOpsitionX(e), getCanvesOpsitionY(e), selectedLayer)) {
|
|
|
canvas.style.cursor = getResizeCursorStyle(SCALING_RIGHT, selectedLayer.angle);
|
|
|
layerState = mouseDown ? SCALING_RIGHT : NONE;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (isResizeRightBottomArea(getCanvesOpsitionX(e), getCanvesOpsitionY(e), selectedLayer)) {
|
|
|
canvas.style.cursor = getResizeCursorStyle(SCALING_RIGHT_BOTTOM, selectedLayer.angle);
|
|
|
layerState = mouseDown ? SCALING_RIGHT_BOTTOM : NONE;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (isResizeBottomArea(getCanvesOpsitionX(e), getCanvesOpsitionY(e), selectedLayer)) {
|
|
|
canvas.style.cursor = getResizeCursorStyle(SCALING_BOTTOM, selectedLayer.angle);
|
|
|
layerState = mouseDown ? SCALING_BOTTOM : NONE;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (isResizeLeftBottomArea(getCanvesOpsitionX(e), getCanvesOpsitionY(e), selectedLayer)) {
|
|
|
canvas.style.cursor = getResizeCursorStyle(SCALING_LEFT_BOTTOM, selectedLayer.angle);
|
|
|
layerState = mouseDown ? SCALING_LEFT_BOTTOM : NONE;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (isResizeLeftArea(getCanvesOpsitionX(e), getCanvesOpsitionY(e), selectedLayer)) {
|
|
|
canvas.style.cursor = getResizeCursorStyle(SCALING_LEFT, selectedLayer.angle);
|
|
|
layerState = mouseDown ? SCALING_LEFT : NONE;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (isRotatingArea(getCanvesOpsitionX(e), getCanvesOpsitionY(e), selectedLayer)) {
|
|
|
canvas.style.cursor = 'pointer';
|
|
|
layerState = mouseDown ? ROTATING : NONE;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
if (selectedLayer.intersect(getCanvesOpsitionX(e), getCanvesOpsitionY(e))) {
|
|
|
canvas.style.cursor = 'move';
|
|
|
layerState = mouseDown ? MOVING : NONE;
|
|
|
if (selectedLayer.layerType == 'virtual') {
|
|
|
return true;
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
function getResizeCursorStyle(layerState, angle) {
|
|
|
var resizeStyleMap = new Array();
|
|
|
resizeStyleMap[SCALING_LEFT_TOP] = 'se-resize';
|
|
|
resizeStyleMap[SCALING_TOP] = 's-resize';
|
|
|
resizeStyleMap[SCALING_RIGHT_TOP] = 'ne-resize';
|
|
|
resizeStyleMap[SCALING_RIGHT] = 'w-resize';
|
|
|
resizeStyleMap[SCALING_RIGHT_BOTTOM] = 'se-resize';
|
|
|
resizeStyleMap[SCALING_BOTTOM] = 's-resize';
|
|
|
resizeStyleMap[SCALING_LEFT_BOTTOM] = 'ne-resize';
|
|
|
resizeStyleMap[SCALING_LEFT] = 'w-resize';
|
|
|
|
|
|
if (!resizeStyleMap[layerState]) {
|
|
|
return 'default';
|
|
|
}
|
|
|
|
|
|
//四舍五入
|
|
|
var angleSkip = angle * 4 / Math.PI;
|
|
|
angleSkip = angleSkip > 0 ? angleSkip + 0.5 : angleSkip - 0.5;
|
|
|
var skipKey = parseInt(angleSkip);
|
|
|
|
|
|
var styleKey = layerState + skipKey;
|
|
|
if (styleKey > SCALING_LEFT) {
|
|
|
styleKey = styleKey - SCALING_LEFT + SCALING_LEFT_TOP - 1;
|
|
|
}
|
|
|
if (styleKey < SCALING_LEFT_TOP) {
|
|
|
styleKey = styleKey + SCALING_LEFT - SCALING_LEFT_TOP;
|
|
|
}
|
|
|
|
|
|
return resizeStyleMap[styleKey];
|
|
|
}
|
|
|
|
|
|
function getCanvesOpsitionX(e) {
|
|
|
return (e.pageX - canvasOffsetX) / canvesBodyScale;
|
|
|
}
|
|
|
|
|
|
function getCanvesOpsitionY(e) {
|
|
|
return (e.pageY - canvasOffsetY) / canvesBodyScale;
|
|
|
}
|
|
|
|
|
|
function checkVectorInCircleArea(vectorX, vectorY, r, alignPoint, angle) {
|
|
|
var circleX = 0;
|
|
|
var circleY = 0;
|
|
|
var x1 = circleX - r;
|
|
|
var y1 = circleY - r;
|
|
|
|
|
|
var x2 = circleX + r;
|
|
|
var y2 = circleY - r;
|
|
|
|
|
|
var x3 = circleX + r;
|
|
|
var y3 = circleY + r;
|
|
|
|
|
|
var x4 = circleX - r;
|
|
|
var y4 = circleY + r;
|
|
|
|
|
|
var square = new Square(
|
|
|
new Vector(x1, y1),
|
|
|
new Vector(x2, y2),
|
|
|
new Vector(x3, y3),
|
|
|
new Vector(x4, y4));
|
|
|
square.rotate(angle);
|
|
|
square.alignOrigin(alignPoint);
|
|
|
|
|
|
return square.intersect(new Vector(vectorX, vectorY));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 左上角缩放
|
|
|
*/
|
|
|
function isResizeLeftTopArea(mX, mY, layer) {
|
|
|
if (layer instanceof TextLayer) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return checkVectorInCircleArea(mX, mY, RESIZE_ARC_RADIUS * 2, layer.getSquare().a, layer.angle);
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 向上拉伸
|
|
|
*/
|
|
|
function isResizeTopArea(mX, mY, layer) {
|
|
|
if (layer instanceof TextLayer) {
|
|
|
return false;
|
|
|
}
|
|
|
if (layer.linkShape == 'circle') {
|
|
|
return false;
|
|
|
}
|
|
|
var square = layer.getSquare();
|
|
|
var alignPointX = square.a.x + (square.b.x - square.a.x) / 2;
|
|
|
var alignPointY = square.a.y + (square.b.y - square.a.y) / 2;
|
|
|
|
|
|
return checkVectorInCircleArea(mX, mY, RESIZE_ARC_RADIUS * 2, new Vector(alignPointX, alignPointY), layer.angle);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
*右上缩放
|
|
|
*/
|
|
|
function isResizeRightTopArea(mX, mY, layer) {
|
|
|
if (layer instanceof TextLayer) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return checkVectorInCircleArea(mX, mY, RESIZE_ARC_RADIUS * 2, layer.getSquare().b, layer.angle);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 向右缩放
|
|
|
*/
|
|
|
function isResizeRightArea(mX, mY, layer) {
|
|
|
if (layer instanceof TextLayer && !layer.allowResetWidth) {
|
|
|
return false;
|
|
|
}
|
|
|
if (layer.linkShape == 'circle') {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
var square = layer.getSquare();
|
|
|
var alignPointX = square.b.x + (square.c.x - square.b.x) / 2;
|
|
|
var alignPointY = square.b.y + (square.c.y - square.b.y) / 2;
|
|
|
|
|
|
return checkVectorInCircleArea(mX, mY, RESIZE_ARC_RADIUS * 2, new Vector(alignPointX, alignPointY), layer.angle);
|
|
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 右下缩放
|
|
|
*/
|
|
|
function isResizeRightBottomArea(mX, mY, layer) {
|
|
|
if (layer instanceof TextLayer) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return checkVectorInCircleArea(mX, mY, RESIZE_ARC_RADIUS * 2, layer.getSquare().c, layer.angle);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 向下缩放
|
|
|
*/
|
|
|
function isResizeBottomArea(mX, mY, layer) {
|
|
|
if (layer instanceof TextLayer) {
|
|
|
return false;
|
|
|
}
|
|
|
if (layer.linkShape == 'circle') {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
var square = layer.getSquare();
|
|
|
var alignPointX = square.d.x + (square.c.x - square.d.x) / 2;
|
|
|
var alignPointY = square.d.y + (square.c.y - square.d.y) / 2;
|
|
|
|
|
|
return checkVectorInCircleArea(mX, mY, RESIZE_ARC_RADIUS * 2, new Vector(alignPointX, alignPointY), layer.angle);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 左下缩放
|
|
|
*/
|
|
|
function isResizeLeftBottomArea(mX, mY, layer) {
|
|
|
if (layer instanceof TextLayer) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return checkVectorInCircleArea(mX, mY, RESIZE_ARC_RADIUS * 2, layer.getSquare().d, layer.angle);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 向左缩放
|
|
|
*/
|
|
|
function isResizeLeftArea(mX, mY, layer) {
|
|
|
//特殊文本不允许左缩放
|
|
|
if (layer instanceof TextLayer && !layer.allowResetWidth) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (layer.linkShape == 'circle') {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
var square = layer.getSquare();
|
|
|
var alignPointX = square.d.x + (square.a.x - square.d.x) / 2;
|
|
|
var alignPointY = square.d.y + (square.a.y - square.d.y) / 2;
|
|
|
|
|
|
return checkVectorInCircleArea(mX, mY, RESIZE_ARC_RADIUS * 2, new Vector(alignPointX, alignPointY), layer.angle);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 旋转按钮区间
|
|
|
*/
|
|
|
function isRotatingArea(mX, mY, layer) {
|
|
|
if (layer instanceof LinkLayer) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
var square = layer.getSquare();
|
|
|
var newLength = layer.height + ROTATE_DISTANCE;
|
|
|
|
|
|
var bottomCenterX = square.c.x + (square.d.x - square.c.x) / 2;
|
|
|
var bottomCenterY = square.c.y + (square.d.y - square.c.y) / 2;
|
|
|
var topCenterX = square.a.x + (square.b.x - square.a.x) / 2;
|
|
|
var topCenterY = square.a.y + (square.b.y - square.a.y) / 2;
|
|
|
|
|
|
var angle = Math.atan2(topCenterY - bottomCenterY, topCenterX - bottomCenterX);
|
|
|
var alignPointX = bottomCenterX + newLength * Math.cos(angle);
|
|
|
var alignPointY = bottomCenterY + newLength * Math.sin(angle);
|
|
|
|
|
|
return checkVectorInCircleArea(mX, mY, ROTATE_ARC_RADIUS, new Vector(alignPointX, alignPointY), layer.angle);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
function BaseLayer() {
|
|
|
this.offsetX = 0;
|
|
|
this.offsetY = 0;
|
|
|
this.layerSubType = 'layerSubType';
|
|
|
this.opacity = 1;
|
|
|
this.visible = true;
|
|
|
this.shadow = false;
|
|
|
this.compositeOperation = "source-over";
|
|
|
this.angle = 0;
|
|
|
this.title = "";
|
|
|
this.layerType = '';
|
|
|
|
|
|
this.getLayerType = function () {
|
|
|
return this.layerType;
|
|
|
}
|
|
|
|
|
|
this.isVisible = function() {
|
|
|
return this.visible;
|
|
|
}
|
|
|
this.toggleVisible = function() {
|
|
|
this.visible = !this.visible;
|
|
|
}
|
|
|
|
|
|
this.hasShadow = function() {
|
|
|
return this.shadow;
|
|
|
}
|
|
|
this.toggleShadow = function() {
|
|
|
this.shadow = !this.shadow;
|
|
|
}
|
|
|
this.setShadow = function(shadow) {
|
|
|
this.shadow = shadow;
|
|
|
}
|
|
|
|
|
|
this.getOpacity = function() {
|
|
|
return this.opacity;
|
|
|
}
|
|
|
this.setOpacity = function(opacity) {
|
|
|
this.opacity = opacity;
|
|
|
}
|
|
|
|
|
|
this.setCompositeOperation = function(compositeOperation) {
|
|
|
this.compositeOperation = compositeOperation;
|
|
|
}
|
|
|
this.getCompositeOperation = function() {
|
|
|
return this.compositeOperation;
|
|
|
}
|
|
|
|
|
|
this.getCanvas = function() {
|
|
|
this.redraw();
|
|
|
return this.canvas;
|
|
|
}
|
|
|
|
|
|
this.intersect = function(x, y) {
|
|
|
var square = new Square(
|
|
|
new Vector(this.offsetX, this.offsetY),
|
|
|
new Vector(this.offsetX + this.width, this.offsetY),
|
|
|
new Vector(this.offsetX + this.width, this.offsetY + this.height),
|
|
|
new Vector(this.offsetX, this.offsetY + this.height));
|
|
|
|
|
|
square.rotate(this.angle);
|
|
|
|
|
|
return square.intersect(new Vector(x, y));
|
|
|
}
|
|
|
|
|
|
this.intersectSquare = function (squareDst) {
|
|
|
var square = new Square(
|
|
|
new Vector(this.offsetX, this.offsetY),
|
|
|
new Vector(this.offsetX + this.width, this.offsetY),
|
|
|
new Vector(this.offsetX + this.width, this.offsetY + this.height),
|
|
|
new Vector(this.offsetX, this.offsetY + this.height));
|
|
|
|
|
|
square.rotate(this.angle);
|
|
|
return (squareDst.intersectSquare(square) || square.intersectSquare(squareDst));
|
|
|
}
|
|
|
|
|
|
this.resetBorderOffset = function () {
|
|
|
var newOffsetX = parseFloat(this.offsetX);
|
|
|
var newOffsetY = parseFloat(this.offsetY);
|
|
|
|
|
|
var newOffsetXAbs = Math.abs(newOffsetX);
|
|
|
var newOffsetYAbs = Math.abs(newOffsetY);
|
|
|
|
|
|
if (newOffsetXAbs < 2) {
|
|
|
this.offsetX = 0;
|
|
|
}
|
|
|
if (newOffsetYAbs < 2) {
|
|
|
this.offsetY = 0;
|
|
|
}
|
|
|
|
|
|
if (86 < newOffsetX && 90 > newOffsetX) {
|
|
|
this.offsetX = 88;
|
|
|
}
|
|
|
var offsetRight = newOffsetX + this.width
|
|
|
if (offsetRight > 798 && offsetRight < 802) {
|
|
|
this.offsetX = 800 - this.width;
|
|
|
}
|
|
|
|
|
|
if (offsetRight > 710 && offsetRight < 714) {
|
|
|
this.offsetX = 712 - this.width;
|
|
|
}
|
|
|
var offsetBottom = newOffsetY + this.height;
|
|
|
if (offsetBottom > 798 && offsetBottom < 802) {
|
|
|
this.offsetY = 800 - this.height;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
this.getSquare = function() {
|
|
|
var square = this.getSquareNotRotate();
|
|
|
square.rotate(this.angle);
|
|
|
return square;
|
|
|
}
|
|
|
|
|
|
this.getSquareNotRotate = function () {
|
|
|
var square = new Square(
|
|
|
new Vector(this.offsetX, this.offsetY),
|
|
|
new Vector(this.offsetX + this.width, this.offsetY),
|
|
|
new Vector(this.offsetX + this.width, this.offsetY + this.height),
|
|
|
new Vector(this.offsetX, this.offsetY + this.height));
|
|
|
return square;
|
|
|
}
|
|
|
|
|
|
//让图层围绕某一点旋转
|
|
|
this.rotateOrderAngleAndPosition = function (position, angle) {
|
|
|
//获取b点
|
|
|
var square = this.getSquare();
|
|
|
var b = square.b;
|
|
|
//将b点围绕position旋转旋转angle度
|
|
|
|
|
|
b = this.dot1AroundDot2Roate(b, position, angle);
|
|
|
//同理将a点围绕position旋转旋转angle度
|
|
|
|
|
|
var a = square.a;
|
|
|
a = this.dot1AroundDot2Roate(a, position, angle);
|
|
|
|
|
|
//将矩形abcd中点旋转
|
|
|
var origin = square.origin;
|
|
|
origin = this.dot1AroundDot2Roate(origin, position, angle);
|
|
|
|
|
|
//线段ab相对于a点延伸出向右的射线的夹角,就是矩形abcd相对矩形中点的旋转角度
|
|
|
var angle = Math.atan2((b.y - a.y), (b.x - a.x));
|
|
|
var a = this.dot1AroundDot2Roate(a, origin, -angle);
|
|
|
this.offsetX = a.x;
|
|
|
this.offsetY = a.y;
|
|
|
this.angle = angle;
|
|
|
}
|
|
|
|
|
|
//点dot1围绕点dot2旋转
|
|
|
this.dot1AroundDot2Roate = function (dot1, dot2, angle) {
|
|
|
var radius = Math.sqrt(Math.pow(dot2.x - dot1.x, 2) + Math.pow(dot2.y - dot1.y, 2));
|
|
|
var dot1Angle = Math.atan2((dot1.y - dot2.y), (dot1.x - dot2.x));
|
|
|
dot1.x = dot2.x + radius * Math.cos(angle + dot1Angle);
|
|
|
dot1.y = dot2.y + radius * Math.sin(angle + dot1Angle);
|
|
|
|
|
|
return dot1;
|
|
|
}
|
|
|
|
|
|
this.setAngle = function(angle) {
|
|
|
this.angle = parseFloat(angle);
|
|
|
}
|
|
|
this.getAngle = function() {
|
|
|
return this.angle;
|
|
|
}
|
|
|
|
|
|
this.setTitle = function(title) {
|
|
|
this.title = title;
|
|
|
}
|
|
|
this.getTitle = function() {
|
|
|
return this.title;
|
|
|
}
|
|
|
|
|
|
this.redraw = function() {
|
|
|
var startX = this.width / 2 - this.width;
|
|
|
var startY = this.height / 2 - this.height;
|
|
|
|
|
|
//this.context.clearRect(startX, startY, this.canvas.width, this.canvas.height);
|
|
|
//this.context.drawImage(this.img, startX, startY, this.width, this.height);
|
|
|
}
|
|
|
|
|
|
this.getImageData = function () {
|
|
|
var startX = this.width / 2 - this.width;
|
|
|
var startY = this.height / 2 - this.height;
|
|
|
|
|
|
var newCanvas = document.createElement('canvas');
|
|
|
newCanvas.width = this.width;
|
|
|
newCanvas.height = this.height;
|
|
|
|
|
|
var newCanvas2d = newCanvas.getContext('2d');
|
|
|
|
|
|
newCanvas2d.globalAlpha = this.opacity;
|
|
|
newCanvas2d.globalCompositeOperation = this.compositeOperation;
|
|
|
|
|
|
newCanvas2d.save();
|
|
|
|
|
|
newCanvas2d.fillStyle="#0000ff";
|
|
|
newCanvas2d.fillRect(0,0,this.width,this.height);
|
|
|
|
|
|
var translateX = this.width / 2;
|
|
|
var translateY = this.height / 2;
|
|
|
|
|
|
newCanvas2d.translate(translateX, translateY);
|
|
|
newCanvas2d.rotate(this.angle);
|
|
|
|
|
|
|
|
|
newCanvas2d.drawImage(this.canvas, -translateX, -translateY);
|
|
|
newCanvas2d.restore();
|
|
|
|
|
|
return newCanvas.toDataURL("image/png");
|
|
|
}
|
|
|
};
|
|
|
|
|
|
function Layer(img) {
|
|
|
this.layerType = 'img';
|
|
|
this.img = img;
|
|
|
this.img.crossOrigin = "*";
|
|
|
this.width = img.naturalWidth;
|
|
|
this.height = img.naturalHeight;
|
|
|
this.naturalWidth = img.naturalWidth;
|
|
|
this.naturalHeight = img.naturalHeight;
|
|
|
this.scale = 100;
|
|
|
|
|
|
this.imgUrl = '';
|
|
|
this.blendColor = '';
|
|
|
this.canvas = document.createElement('canvas');
|
|
|
this.canvas.width = this.width;
|
|
|
this.canvas.height = this.height;
|
|
|
this.context = this.canvas.getContext('2d');
|
|
|
this.context.save();
|
|
|
this.context.translate(this.width / 2, this.height / 2);
|
|
|
|
|
|
this.setImgUrl = function (imgUrl) {
|
|
|
this.imgUrl = imgUrl;
|
|
|
}
|
|
|
|
|
|
this.getImage = function() {
|
|
|
return this.img;
|
|
|
}
|
|
|
|
|
|
this.getScale = function () {
|
|
|
if (this.naturalWidth == 0) {
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
return parseInt((this.width * 100) / this.naturalWidth);
|
|
|
}
|
|
|
|
|
|
this.getNaturalWidth = function () {
|
|
|
return this.naturalWidth;
|
|
|
}
|
|
|
|
|
|
this.setWidthAndHeightByScale = function (scale) {
|
|
|
var scale = parseInt(scale);
|
|
|
this.scale = scale;
|
|
|
this.context.restore();
|
|
|
|
|
|
this.width = parseInt(this.naturalWidth * scale / 100);
|
|
|
this.height = parseInt(this.naturalHeight * scale / 100);
|
|
|
|
|
|
this.canvas.width = this.width;
|
|
|
this.canvas.height = this.height;
|
|
|
|
|
|
this.context.translate(this.width / 2, this.height / 2);
|
|
|
this.redraw();
|
|
|
}
|
|
|
|
|
|
this.initLayerInfo = function () {
|
|
|
this.canvas.width = this.width;
|
|
|
this.canvas.height = this.height;
|
|
|
this.context.translate(this.width / 2, this.height / 2);
|
|
|
}
|
|
|
|
|
|
this.redraw = function() {
|
|
|
var startX = this.width / 2 - this.width;
|
|
|
var startY = this.height / 2 - this.height;
|
|
|
|
|
|
this.context.clearRect(startX, startY, this.canvas.width, this.canvas.height);
|
|
|
this.context.drawImage(this.img, startX, startY, this.width, this.height);
|
|
|
this.doBlendColor();
|
|
|
}
|
|
|
|
|
|
this.doBlendColor = function() {
|
|
|
if (this.blendColor.length < 1) {
|
|
|
return ;
|
|
|
}
|
|
|
|
|
|
var pixels=this.context.getImageData(0, 0, this.width,this.height);
|
|
|
var data = pixels.data;
|
|
|
|
|
|
var colorCompose = this.getRedGreenBlueFromColorStr(this.blendColor);
|
|
|
if (!colorCompose) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
red = parseInt(colorCompose.red);
|
|
|
green = parseInt(colorCompose.green);
|
|
|
blue = parseInt(colorCompose.blue);
|
|
|
if (red < 2 && green < 2 && blue < 2) {
|
|
|
this.blendColor = '';
|
|
|
return ;
|
|
|
}
|
|
|
for (var i=0; i<data.length; i+=4) {
|
|
|
if (doBlendColorV2) {
|
|
|
var newRed = Math.min(data[i] + red, 256);
|
|
|
var newGreen = Math.min(data[i + 1] + green, 256);
|
|
|
var newBlue = Math.min(data[i + 2] + blue, 256);
|
|
|
} else {
|
|
|
var newRed = 255 - Math.sqrt(Math.pow((255-data[i]),2) + Math.pow((255-red), 2));
|
|
|
var newGreen = 255 - Math.sqrt(Math.pow((255-data[i+1]),2) + Math.pow((255-green), 2));
|
|
|
var newBlue = 255 - Math.sqrt(Math.pow((255-data[i+2]),2) + Math.pow((255-blue), 2));
|
|
|
}
|
|
|
|
|
|
data[i] = newRed;
|
|
|
data[i+1] = newGreen;
|
|
|
data[i+2] = newBlue;
|
|
|
}
|
|
|
|
|
|
this.context.putImageData(pixels, 0, 0);
|
|
|
}
|
|
|
|
|
|
this.getRedGreenBlueFromColorStr = function (colorStr) {
|
|
|
//colorStr is hex
|
|
|
var colorCompose = {};
|
|
|
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(colorStr);
|
|
|
if (result) {
|
|
|
colorCompose.red = parseInt(result[1], 16);
|
|
|
colorCompose.green = parseInt(result[2], 16);
|
|
|
colorCompose.blue = parseInt(result[3], 16);
|
|
|
return colorCompose;
|
|
|
}
|
|
|
|
|
|
var result = /^#?([a-f\d]{1})([a-f\d]{1})([a-f\d]{1})$/i.exec(colorStr);
|
|
|
if (result) {
|
|
|
colorCompose.red = parseInt(result[1] + result[1], 16);
|
|
|
colorCompose.green = parseInt(result[2] + result[2], 16);
|
|
|
colorCompose.blue = parseInt(result[3] + result[2], 16);
|
|
|
return colorCompose;
|
|
|
}
|
|
|
|
|
|
var result = colorStr.substring(colorStr.indexOf('(') + 1,colorStr.lastIndexOf(')')).split(/,\s*/);
|
|
|
if (result && result.length > 2) {
|
|
|
colorCompose.red = parseInt(result[0]);
|
|
|
colorCompose.green = parseInt(result[1]);
|
|
|
colorCompose.blue = parseInt(result[2]);
|
|
|
return colorCompose;
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
this.brightness = function() {
|
|
|
var pixels=this.context.getImageData(0, 0, this.width,this.height);
|
|
|
var d = pixels.data;
|
|
|
for (var i=0; i<d.length; i+=4) {
|
|
|
d[i] += 100;
|
|
|
d[i+1] +=100;
|
|
|
d[i+2] += 100;
|
|
|
}
|
|
|
ctx.putImageData(pixels,0,0);
|
|
|
}
|
|
|
};
|
|
|
Layer.prototype = new BaseLayer();
|
|
|
|
|
|
function LinkLayer() {
|
|
|
this.layerType = 'link';
|
|
|
this.layerSubType = 'link';
|
|
|
this.linkShape = 'rectangle';
|
|
|
this.width = 100;
|
|
|
this.height = 100;
|
|
|
this.linkUrl = '';
|
|
|
|
|
|
this.canvas = document.createElement('canvas');
|
|
|
this.context = this.canvas.getContext('2d');
|
|
|
this.canvas.width = this.width;
|
|
|
this.canvas.height = this.height;
|
|
|
|
|
|
this.redraw = function() {
|
|
|
this.initLayerInfo();
|
|
|
|
|
|
if (this.linkShape == 'rectangle') {
|
|
|
this.redrawRectgle();
|
|
|
}
|
|
|
|
|
|
if (this.linkShape == 'circle') {
|
|
|
this.redrawCircle();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
this.redrawRectgle = function () {
|
|
|
var startX = -this.canvas.width / 2;
|
|
|
var startY = -this.canvas.height / 2;
|
|
|
var width = this.canvas.width;
|
|
|
var height = this.canvas.height;
|
|
|
this.context.clearRect(startX, startY, width, height);
|
|
|
|
|
|
this.context.fillStyle = 'rgba(26,75,171,0.1)';
|
|
|
this.context.fillRect(startX, startY, width, height); //填充的四个参数(x,y,width,height)
|
|
|
}
|
|
|
|
|
|
this.redrawCircle = function () {
|
|
|
var startX = -this.canvas.width / 2;
|
|
|
var startY = -this.canvas.height / 2;
|
|
|
var width = this.canvas.width;
|
|
|
var height = this.canvas.height;
|
|
|
this.context.clearRect(startX, startY, width, height);
|
|
|
|
|
|
this.context.beginPath();
|
|
|
this.context.arc(0, 0, width / 2, 0, 2 * Math.PI);
|
|
|
this.context.fillStyle = 'rgba(26,75,171,0.1)';
|
|
|
this.context.fill();
|
|
|
this.context.closePath();
|
|
|
}
|
|
|
|
|
|
this.initLayerInfo = function () {
|
|
|
this.canvas.width = this.width;
|
|
|
this.canvas.height = this.height;
|
|
|
this.context.translate(this.width / 2, this.height / 2);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
LinkLayer.prototype = new BaseLayer();
|
|
|
|
|
|
function TextLayer(content, style) {
|
|
|
var style = style || {};
|
|
|
this.layerType = 'text';
|
|
|
this.style = style;
|
|
|
this.layerSubType = 'normal';
|
|
|
this.lineHeightScale = 1.2;
|
|
|
this.content = content.toString();
|
|
|
this.allowResetWidth = style.fixedWidth ? true : false;
|
|
|
|
|
|
this.fontFamily = style.fontFamily;
|
|
|
this.fontSize = parseInt(style.fontSize);
|
|
|
this.fontColor = style.fontColor;
|
|
|
this.bold = style.bold ? style.bold : '0';
|
|
|
this.italic = style.italic ? style.italic : '0';
|
|
|
this.underline = style.underline ? style.underline : '0';
|
|
|
this.strikethrough = style.strikethrough ? style.strikethrough : '0';
|
|
|
|
|
|
this.hidePriceConfig = {};
|
|
|
this.formatPriceConfig = {};
|
|
|
this.discountPriceConfig = {};
|
|
|
this.textAlignPriceConfig = {};
|
|
|
this.fullMinusConfig = {};
|
|
|
this.priceCountTypeConfig = {};
|
|
|
|
|
|
this.canvas = document.createElement('canvas');
|
|
|
this.context = this.canvas.getContext('2d');
|
|
|
|
|
|
this.context.fillStyle = this.fontColor;
|
|
|
this.context.textBaseline = "alphabetic";
|
|
|
|
|
|
this.joinFont = function(fontSize, fontFamily) {
|
|
|
var font = '';
|
|
|
if (this.bold == '1') {
|
|
|
font += 'bold ';
|
|
|
}
|
|
|
if (this.italic == '1') {
|
|
|
font += 'italic ';
|
|
|
}
|
|
|
var fontSize = fontSize ? parseInt(fontSize) : this.fontSize;
|
|
|
var fontFamily = fontFamily ? fontFamily : this.fontFamily;
|
|
|
font += fontSize + 'px ' + fontFamily;
|
|
|
return font;
|
|
|
}
|
|
|
|
|
|
if (style.fixedWidth && style.fixedWidth > 1) {
|
|
|
this.width = parseInt(style.fixedWidth);
|
|
|
this.contentList = getContentList(this.content, this.joinFont(), this.allowResetWidth, this.width);
|
|
|
} else {
|
|
|
this.contentList = getContentList(this.content, this.joinFont(), this.allowResetWidth, this.width);
|
|
|
this.width = getLayerWidth(this.contentList, this.joinFont());
|
|
|
}
|
|
|
|
|
|
this.height = getLayerHeight(this.contentList, this.fontSize, this.layerSubType, this.lineHeightScale);
|
|
|
this.canvas.width = this.width;
|
|
|
this.canvas.height = this.height;
|
|
|
|
|
|
this.context.save();
|
|
|
this.context.translate(this.width / 2, this.height / 2);
|
|
|
|
|
|
this.setWidth = function (width) {
|
|
|
this.width = width;
|
|
|
this.initLayerInfo();
|
|
|
}
|
|
|
|
|
|
this.setLineHeightScale = function (lineHeightScale) {
|
|
|
this.lineHeightScale = lineHeightScale;
|
|
|
this.initLayerInfo()
|
|
|
}
|
|
|
|
|
|
this.setContent = function (content) {
|
|
|
this.content = content;
|
|
|
this.initLayerInfo();
|
|
|
}
|
|
|
|
|
|
this.setFontFamily = function (fontFamily) {
|
|
|
this.fontFamily = fontFamily;
|
|
|
this.initLayerInfo();
|
|
|
}
|
|
|
|
|
|
this.setFontSize = function (fontSize) {
|
|
|
fontSize = parseInt(fontSize);
|
|
|
this.fontSize = fontSize;
|
|
|
this.initLayerInfo();
|
|
|
}
|
|
|
|
|
|
this.setBold = function (bold) {
|
|
|
this.bold = bold;
|
|
|
this.initLayerInfo();
|
|
|
}
|
|
|
|
|
|
this.setItalic = function (italic) {
|
|
|
this.italic = italic;
|
|
|
this.initLayerInfo();
|
|
|
}
|
|
|
|
|
|
this.setUnderline = function (underline) {
|
|
|
this.underline = underline;
|
|
|
this.initLayerInfo();
|
|
|
}
|
|
|
|
|
|
this.setStrikethrough = function (strikethrough) {
|
|
|
this.strikethrough = strikethrough;
|
|
|
this.initLayerInfo();
|
|
|
}
|
|
|
|
|
|
this.setHidePriceConfig = function(config) {
|
|
|
this.hidePriceConfig = config;
|
|
|
}
|
|
|
|
|
|
this.setFormatPriceConfig = function(config) {
|
|
|
this.formatPriceConfig = config;
|
|
|
}
|
|
|
|
|
|
this.setDiscountPriceConfig = function(config) {
|
|
|
this.discountPriceConfig = config;
|
|
|
}
|
|
|
|
|
|
this.setTextAlignPriceConfig = function(config) {
|
|
|
this.textAlignPriceConfig = config;
|
|
|
}
|
|
|
|
|
|
this.setFullMinusConfig = function(config) {
|
|
|
this.fullMinusConfig = config;
|
|
|
}
|
|
|
|
|
|
this.setPriceCountTypeConfig = function (config) {
|
|
|
this.priceCountTypeConfig = config;
|
|
|
}
|
|
|
|
|
|
this.redraw = function() {
|
|
|
this.initLayerInfo();
|
|
|
this.context.font = this.joinFont();
|
|
|
this.context.fillStyle = this.fontColor;
|
|
|
|
|
|
this.context.clearRect(-this.canvas.width, -this.canvas.height, 2*this.canvas.width, 2*this.canvas.height);
|
|
|
if ($.inArray(this.layerSubType, priceLayerSubTypeArr) === -1) {
|
|
|
this.context.textBaseline = "top";
|
|
|
var startX = this.width / 2 - this.width;
|
|
|
var startY = this.height / 2 - this.height + 10;
|
|
|
} else {
|
|
|
this.context.textBaseline = "alphabetic";
|
|
|
var startX = this.width / 2 - this.width;
|
|
|
var startY = this.height / 2 - this.height/20;
|
|
|
}
|
|
|
|
|
|
this.context.clearRect(startX, startY, this.canvas.width, this.canvas.height);
|
|
|
|
|
|
var length = this.contentList.length;
|
|
|
var lineHeight = this.fontSize * this.lineHeightScale;
|
|
|
|
|
|
for (var i = 0; i < length; i++) {
|
|
|
var content = this.contentList[i];
|
|
|
if (content.length < 1) {
|
|
|
startY += lineHeight;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
this.context.fillText(content, startX, startY);
|
|
|
|
|
|
var realContentWidth = getLayerRealWidthByContent(content, this.joinFont());
|
|
|
if (this.underline == '1') {
|
|
|
if (this.context.textBaseline == "top") {
|
|
|
var lineStartY = startY + this.fontSize;
|
|
|
} else if (this.context.textBaseline == "alphabetic") {
|
|
|
var lineStartY = startY;
|
|
|
}
|
|
|
this.drawLine(startX, lineStartY, startX + realContentWidth, lineStartY);
|
|
|
}
|
|
|
if (this.strikethrough == '1') {
|
|
|
if (this.context.textBaseline == "top") {
|
|
|
var lineStartY = startY + this.fontSize / 2;
|
|
|
} else if (this.context.textBaseline == "alphabetic") {
|
|
|
var lineStartY = startY - this.fontSize / 2 + this.fontSize/20;
|
|
|
}
|
|
|
this.drawLine(startX, lineStartY, startX + realContentWidth, lineStartY);
|
|
|
}
|
|
|
|
|
|
startY += lineHeight;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
this.drawLine = function(startX, startY, endX, endY) {
|
|
|
this.context.beginPath();
|
|
|
this.context.lineWidth = 2;
|
|
|
this.context.moveTo(startX, startY);
|
|
|
this.context.lineTo(endX, endY);
|
|
|
this.context.strokeStyle = this.fontColor;
|
|
|
this.context.stroke();
|
|
|
this.context.closePath();
|
|
|
}
|
|
|
|
|
|
this.initLayerInfo = function () {
|
|
|
this.contentList = getContentList(this.content, this.joinFont(), this.allowResetWidth, this.width);
|
|
|
|
|
|
if (!this.allowResetWidth) {
|
|
|
this.width = getLayerWidth(this.contentList, this.joinFont());
|
|
|
}
|
|
|
this.height = getLayerHeight(this.contentList, this.fontSize, this.layerSubType, this.lineHeightScale);
|
|
|
|
|
|
this.canvas.width = this.width;
|
|
|
this.canvas.height = this.height;
|
|
|
|
|
|
this.context.restore();
|
|
|
this.context.save();
|
|
|
this.context.translate(this.width / 2, this.height / 2);
|
|
|
}
|
|
|
|
|
|
function getLayerWidth(contentList, font) {
|
|
|
var length = contentList.length;
|
|
|
var maxWidth = 0;
|
|
|
for (var i = 0; i < length; i++) {
|
|
|
var content = contentList[i];
|
|
|
if (content.length < 1) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
var width = getLayerRealWidthByContent(content, font);
|
|
|
maxWidth = maxWidth ? maxWidth : width;
|
|
|
maxWidth = (width > maxWidth) ? width : maxWidth;
|
|
|
}
|
|
|
//有时字体没载入,导致宽度太小
|
|
|
return parseInt(maxWidth + 30);
|
|
|
}
|
|
|
|
|
|
function getLayerRealWidthByContent(content, font) {
|
|
|
var context = document.createElement('canvas').getContext('2d');
|
|
|
context.font = font;
|
|
|
return context.measureText(content).width;
|
|
|
}
|
|
|
|
|
|
function getLayerHeight(contentList, fontSize, layerSubType, lineHeightScale) {
|
|
|
var lineHeight = fontSize;
|
|
|
if ($.inArray(layerSubType, priceLayerSubTypeArr) === -1) {
|
|
|
var lineHeight = fontSize * lineHeightScale;
|
|
|
}
|
|
|
|
|
|
var length = contentList.length;
|
|
|
var height = lineHeight * length;
|
|
|
|
|
|
if ($.inArray(layerSubType, priceLayerSubTypeArr) === -1) {
|
|
|
height = height + 20;
|
|
|
}
|
|
|
|
|
|
return height;
|
|
|
}
|
|
|
|
|
|
function getContentList(content, font, allowResetWidth, width) {
|
|
|
var contentList = splitContentToContentList(content);
|
|
|
|
|
|
if (allowResetWidth) {
|
|
|
contentList = adjustContentListByMaxWidth(contentList, font, width);
|
|
|
}
|
|
|
|
|
|
return contentList;
|
|
|
}
|
|
|
|
|
|
//换行是英文时会把英文给切了
|
|
|
function adjustContentListByMaxWidth(contentList, font, width) {
|
|
|
var context = document.createElement('canvas').getContext('2d');
|
|
|
context.font = font;
|
|
|
|
|
|
var contentListNew = [];
|
|
|
for (var i = 0; i < contentList.length; i++) {
|
|
|
var content = contentList[i];
|
|
|
if (content.trim().lenth < 1) {
|
|
|
contentListNew.push('');
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
//根据二分法切割字符串
|
|
|
var splitLength = content.length;
|
|
|
var contentListArr = [];
|
|
|
var testStr = '';
|
|
|
for (var j = 0; j < content.length; j++) {
|
|
|
var endChars = content[j];
|
|
|
testStr += endChars;
|
|
|
|
|
|
if (context.measureText(testStr).width > width) {
|
|
|
testStr = testStr.length > 1 ? testStr.slice(0, testStr.length - 1) : testStr;
|
|
|
contentListNew.push(testStr);
|
|
|
testStr = testStr.length > 1 ? endChars : '';
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (testStr) {
|
|
|
contentListNew.push(testStr);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return contentListNew;
|
|
|
|
|
|
}
|
|
|
|
|
|
function splitContentToContentList(content) {
|
|
|
var contentListNew = [];
|
|
|
var contentList = content.split('\n');
|
|
|
var isHeader = true;
|
|
|
var lineBreakCount = 0;
|
|
|
for (var i = 0; i < contentList.length; i++) {
|
|
|
var contentSmall = contentList[i];
|
|
|
//丢弃开头换行符
|
|
|
var cntIsEmpty = (contentSmall.replace(/(^s*)|(s*$)/g, "").length == 0);
|
|
|
if (isHeader && cntIsEmpty) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
isHeader = false;
|
|
|
if (cntIsEmpty) {
|
|
|
lineBreakCount++;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
//丢弃尾部换行符
|
|
|
while (lineBreakCount > 0) {
|
|
|
contentListNew.push('');
|
|
|
lineBreakCount--;
|
|
|
}
|
|
|
|
|
|
contentListNew.push(contentSmall);
|
|
|
}
|
|
|
|
|
|
return contentListNew;
|
|
|
}
|
|
|
|
|
|
};
|
|
|
TextLayer.prototype = new BaseLayer();
|
|
|
|
|
|
function Square(a, b, c, d) {
|
|
|
this.a = a;
|
|
|
this.b = b;
|
|
|
this.c = c;
|
|
|
this.d = d;
|
|
|
this.origin = centerSquareOrigin(a,b,c,d);
|
|
|
|
|
|
this.intersect = function(mouse) {
|
|
|
return (!intersectWithLine(this.origin, mouse, this.a, this.b) &&
|
|
|
!intersectWithLine(this.origin, mouse, this.b, this.c) &&
|
|
|
!intersectWithLine(this.origin, mouse, this.c, this.d) &&
|
|
|
!intersectWithLine(this.origin, mouse, this.d, this.a));
|
|
|
}
|
|
|
|
|
|
//判断两个矩形是否相交
|
|
|
this.intersectSquare = function (square) {
|
|
|
var dstA = square.a;
|
|
|
var dstB = square.b;
|
|
|
var dstC = square.c;
|
|
|
var dstD = square.d;
|
|
|
var check = (this.intersect(dstA)) || (this.intersect(dstB)) || (this.intersect(dstC)) || (this.intersect(dstD));
|
|
|
return check;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.rotate = function(angle) {
|
|
|
var angle = parseFloat(angle);
|
|
|
|
|
|
var radius = Math.sqrt(Math.pow(this.origin.x - this.a.x, 2) + Math.pow(this.origin.y - this.a.y, 2));
|
|
|
|
|
|
var aAngle = Math.atan2((this.a.y - this.origin.y), (this.a.x - this.origin.x));
|
|
|
var bAngle = Math.atan2((this.b.y - this.origin.y), (this.b.x - this.origin.x));
|
|
|
var cAngle = Math.atan2((this.c.y - this.origin.y), (this.c.x - this.origin.x));
|
|
|
var dAngle = Math.atan2((this.d.y - this.origin.y), (this.d.x - this.origin.x));
|
|
|
|
|
|
this.a.x = this.origin.x + radius * Math.cos(angle + aAngle);
|
|
|
this.a.y = this.origin.y + radius * Math.sin(angle + aAngle);
|
|
|
this.b.x = this.origin.x + radius * Math.cos(angle + bAngle);
|
|
|
this.b.y = this.origin.y + radius * Math.sin(angle + bAngle);
|
|
|
this.c.x = this.origin.x + radius * Math.cos(angle + cAngle);
|
|
|
this.c.y = this.origin.y + radius * Math.sin(angle + cAngle);
|
|
|
this.d.x = this.origin.x + radius * Math.cos(angle + dAngle);
|
|
|
this.d.y = this.origin.y + radius * Math.sin(angle + dAngle);
|
|
|
|
|
|
}
|
|
|
|
|
|
this.alignBottomRight = function(alignPoint) {
|
|
|
var diff = new Vector(alignPoint.x - this.c.x, alignPoint.y - this.c.y);
|
|
|
|
|
|
this.a = this.a.add(diff);
|
|
|
this.b = this.b.add(diff);
|
|
|
this.c = this.c.add(diff);
|
|
|
this.d = this.d.add(diff);
|
|
|
this.origin = centerSquareOrigin(this.a, this.b, this.c, this.d);
|
|
|
}
|
|
|
|
|
|
this.alignTopRight = function(alignPoint) {
|
|
|
var diff = new Vector(alignPoint.x - this.b.x, alignPoint.y - this.b.y);
|
|
|
|
|
|
this.a = this.a.add(diff);
|
|
|
this.b = this.b.add(diff);
|
|
|
this.c = this.c.add(diff);
|
|
|
this.d = this.d.add(diff);
|
|
|
this.origin = centerSquareOrigin(this.a, this.b, this.c, this.d);
|
|
|
}
|
|
|
|
|
|
this.alignOrigin = function(alignPoint) {
|
|
|
var diff = new Vector(alignPoint.x - this.origin.x, alignPoint.y - this.origin.y);
|
|
|
|
|
|
this.a = this.a.add(diff);
|
|
|
this.b = this.b.add(diff);
|
|
|
this.c = this.c.add(diff);
|
|
|
this.d = this.d.add(diff);
|
|
|
this.origin = centerSquareOrigin(this.a, this.b, this.c, this.d);
|
|
|
}
|
|
|
|
|
|
var epsilon = 10e-6;
|
|
|
|
|
|
function centerSquareOrigin(a, b, c, d) {
|
|
|
p = a;
|
|
|
r = c.subtract(a);
|
|
|
q = b;
|
|
|
s = d.subtract(b);
|
|
|
|
|
|
rCrossS = cross(r, s);
|
|
|
if(rCrossS <= epsilon && rCrossS >= -1 * epsilon){
|
|
|
return;
|
|
|
}
|
|
|
t = cross(q.subtract(p), s)/rCrossS;
|
|
|
u = cross(q.subtract(p), r)/rCrossS;
|
|
|
if (0 <= u && u <= 1 && 0 <= t && t <= 1){
|
|
|
intPoint = p.add(r.scalarMult(t));
|
|
|
return new Vector(intPoint.x, intPoint.y);
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
function consoleLogPosition(a, index) {
|
|
|
ZcLog.log("x" + index);
|
|
|
var x = a.x;
|
|
|
ZcLog.log(x);
|
|
|
|
|
|
ZcLog.log("y" + index);
|
|
|
var y = a.y;
|
|
|
ZcLog.log(y);
|
|
|
|
|
|
}
|
|
|
|
|
|
function cross(v1, v2) {
|
|
|
return v1.x * v2.y - v2.x * v1.y;
|
|
|
}
|
|
|
|
|
|
function intersectWithLine(l1p1, l1p2, l2p1, l2p2) {
|
|
|
p = l1p1;
|
|
|
r = l1p2.subtract(l1p1);
|
|
|
q = l2p1;
|
|
|
s = l2p2.subtract(l2p1);
|
|
|
|
|
|
rCrossS = cross(r, s);
|
|
|
if(rCrossS <= epsilon && rCrossS >= -1 * epsilon){
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
t = cross(q.subtract(p), s)/rCrossS;
|
|
|
u = cross(q.subtract(p), r)/rCrossS;
|
|
|
if(0 <= u && u <= 1 && 0 <= t && t <= 1){
|
|
|
return true;
|
|
|
} else{
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* http://bloggingmath.wordpress.com/2009/05/29/line-segment-intersection/
|
|
|
*/
|
|
|
function Vector(x, y) {
|
|
|
this.x = x;
|
|
|
this.y = y;
|
|
|
|
|
|
this.scalarMult = function(scalar){
|
|
|
return new Vector(this.x * scalar, this.y * scalar);
|
|
|
}
|
|
|
this.dot = function(v2) {
|
|
|
return this.x * v2.x + this.y * v2.y;
|
|
|
};
|
|
|
this.perp = function() {
|
|
|
return new Vector(-1 * this.y, this.x);
|
|
|
};
|
|
|
this.subtract = function(v2) {
|
|
|
return this.add(v2.scalarMult(-1));//new Vector(this.x - v2.x, this.y - v2.y);
|
|
|
};
|
|
|
this.add = function(v2) {
|
|
|
return new Vector(this.x + v2.x, this.y + v2.y);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
function Detector() {
|
|
|
var baseFonts = ['monospace', 'sans-serif', 'serif'];
|
|
|
var testString = "mmmmmmmmmmlli";
|
|
|
var testSize = '72px';
|
|
|
var h = document.getElementsByTagName("body")[0];
|
|
|
var s = document.createElement("span");
|
|
|
s.style.fontSize = testSize;
|
|
|
s.innerHTML = testString;
|
|
|
var defaultWidth = {};
|
|
|
var defaultHeight = {};
|
|
|
for (var index in baseFonts) {
|
|
|
s.style.fontFamily = baseFonts[index];
|
|
|
h.appendChild(s);
|
|
|
defaultWidth[baseFonts[index]] = s.offsetWidth;
|
|
|
defaultHeight[baseFonts[index]] = s.offsetHeight;
|
|
|
h.removeChild(s);
|
|
|
}
|
|
|
|
|
|
function detect(font) {
|
|
|
var detected = false;
|
|
|
for (var index in baseFonts) {
|
|
|
s.style.fontFamily = font + ',' + baseFonts[index];
|
|
|
h.appendChild(s);
|
|
|
var matched = (s.offsetWidth != defaultWidth[baseFonts[index]] || s.offsetHeight != defaultHeight[baseFonts[index]]);
|
|
|
h.removeChild(s);
|
|
|
detected = detected || matched;
|
|
|
}
|
|
|
return detected;
|
|
|
}
|
|
|
|
|
|
this.detect = detect;
|
|
|
}; |