|
|
"use strict";
|
|
|
|
|
|
/*
|
|
|
Copyright [2014] [Diagramo]
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
you may not use this file except in compliance with the License.
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
See the License for the specific language governing permissions and
|
|
|
limitations under the License.
|
|
|
*/
|
|
|
|
|
|
/**
|
|
|
*This class offers support to add images to Diagramo engine
|
|
|
*It supports PNG, GIF, PNG and SVG support.
|
|
|
*Opera (up to 11.50 at least) does not support SVG nice. @see <a href="http://my.opera.com/community/forums/topic.dml?id=1052572">http://my.opera.com/community/forums/topic.dml?id=1052572</a>
|
|
|
*
|
|
|
*@this {ImageFrame}
|
|
|
*@constructor
|
|
|
*
|
|
|
*@param {String} url - the URL to load the image from
|
|
|
*@param {Number} x - the x coordinates of the center of the image
|
|
|
*@param {Number} y - the y coordinates of the center of the image
|
|
|
*@param {Boolean} scale - true if image should be able to scan, false otherwise.
|
|
|
*@param {Number} frameWidth - the frame width
|
|
|
*@param {Number} frameHeight - the frame height
|
|
|
*
|
|
|
*@author Alex
|
|
|
*@see /documets/specs/imageframe_specs.jpg and /documets/specs/imageframe_specs2.jpg
|
|
|
*
|
|
|
*TODO: Source editor - a new popup window with 3 options (url, data, upload) and upon closing set image's src
|
|
|
**/
|
|
|
function ImageFrame(url, x, y, scale, frameWidth, frameHeight){
|
|
|
|
|
|
/**Keeps track if the image was loaded*/
|
|
|
this.loaded = false;
|
|
|
|
|
|
/**We will keep the initial point (as base line) and another point just above it - similar to a vector.
|
|
|
*
|
|
|
* * (x, y-20)
|
|
|
* |
|
|
|
* |
|
|
|
* |
|
|
|
* * - - - * (x+20, y)
|
|
|
* (x, y)
|
|
|
*
|
|
|
*So when the image is transformed we will only transform the vector and get the new angle (if needed)
|
|
|
*from it*/
|
|
|
this.vector = [new Point(x,y),new Point(x,y-20), new Point(x+20, y)];
|
|
|
|
|
|
|
|
|
|
|
|
/**Keeps track if contraints are present or set (ex: frameWidth or frameHeight )*/
|
|
|
this.constraints = false;
|
|
|
|
|
|
/**The the frame width*/
|
|
|
this.frameWidth = frameWidth;
|
|
|
if(frameWidth){
|
|
|
this.constraints = true;
|
|
|
}
|
|
|
else{
|
|
|
//this.frameWidth = ImageFrame.DEFAULT_WIDTH;
|
|
|
//throw "ImageFrame.js->constructor()->frameWidth not set";
|
|
|
}
|
|
|
|
|
|
|
|
|
/**The the frame height*/
|
|
|
this.frameHeight = frameHeight;
|
|
|
if(frameHeight){
|
|
|
this.constraints = true;
|
|
|
}
|
|
|
else{
|
|
|
//this.frameHeight = ImageFrame.DEFAULT_HEIGHT;
|
|
|
//throw "ImageFrame.js->constructor()->frameHeight not set";
|
|
|
}
|
|
|
|
|
|
/**Trigger or not the scalling of the image, after transformations*/
|
|
|
this.scale = scale;
|
|
|
|
|
|
/**Tell if we need to keep ratio of the image. Ignored. Set to true by default*/
|
|
|
this.keepRatio = true;
|
|
|
|
|
|
/**The URL from where the image will be loaded.
|
|
|
* We need to keep it also as a member to be serialized
|
|
|
* (as the Image object is not serialized :( by JSON)
|
|
|
**/
|
|
|
this.url = url;
|
|
|
|
|
|
|
|
|
/**The JavaScript Image object. It seems that Serialization for Image, with JSON, in Chrome
|
|
|
* is a little broken so we need custom serializers
|
|
|
* see toJSON() method
|
|
|
* */
|
|
|
this.image = new Image();
|
|
|
|
|
|
this.setUrl(url);
|
|
|
|
|
|
/**
|
|
|
* TODO: remove it
|
|
|
* Used to display visual debug information. If set on true it will display interesting stuff (for a developer)
|
|
|
* @deprecated - use Diagramo.debug instead
|
|
|
* */
|
|
|
this.debug = false;
|
|
|
|
|
|
/**The style of the Image. Kinda fake/default value*/
|
|
|
//TODO: do we really need to keep this?
|
|
|
this.style = new Style();
|
|
|
//
|
|
|
// //this.url = '';
|
|
|
/**The type of the object. Used in deserialization*/
|
|
|
this.oType = 'ImageFrame';
|
|
|
}
|
|
|
|
|
|
ImageFrame.DEFAULT_WIDTH = 10;
|
|
|
ImageFrame.DEFAULT_HEIGHT = 10;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**Creates a {ImageFrame} out of JSON parsed object
|
|
|
*@param {JSONObject} o - the JSON parsed object
|
|
|
*@return {ImageFrame} a newly constructed ImageFrame
|
|
|
*@author Alex Gheorghiu <alex@scriptoid.com>
|
|
|
**/
|
|
|
ImageFrame.load = function(o){
|
|
|
var newImageFrame = new ImageFrame();
|
|
|
|
|
|
//default: newImageFrame.loaded
|
|
|
newImageFrame.vector = Point.loadArray(o.vector);
|
|
|
//not needed: newImage.image
|
|
|
newImageFrame.constraints = o.constraints;
|
|
|
newImageFrame.frameHeight = o.frameHeight;
|
|
|
newImageFrame.frameWidth = o.frameWidth;
|
|
|
newImageFrame.scale = o.scale;
|
|
|
newImageFrame.keepRatio = o.keepRatio;
|
|
|
newImageFrame.setUrl(o.url);
|
|
|
//not needed: newImage.style
|
|
|
newImageFrame.debug = o.debug;
|
|
|
//not needed: newImage.type
|
|
|
|
|
|
//TODO: not good to load it twice (in constructor and now again)
|
|
|
|
|
|
return newImageFrame;
|
|
|
}
|
|
|
|
|
|
|
|
|
/* Basic methods we need to implement
|
|
|
* -paint:void
|
|
|
* -tranform(matrix):void
|
|
|
* -contains(x, y):boolean
|
|
|
* -equals(object):boolean
|
|
|
* -toString():String
|
|
|
* -clone():object - this is a deep clone
|
|
|
* -getBounds():[number, number, number, number]
|
|
|
* -near(distance):boolean - This should be used to test if a click is close to a primitive/figure
|
|
|
* -getPoints():Array - returns an array of points, so that a figure can implement contains
|
|
|
* -getStyleInfo():Style - returns the different styles that can be used by any shape
|
|
|
*/
|
|
|
ImageFrame.prototype = {
|
|
|
constructor : ImageFrame,
|
|
|
|
|
|
/**
|
|
|
*Called by JSON.stringify() method. We need to use this as Chrome simply cease to execute the JS
|
|
|
*whenever an Image is found.
|
|
|
*
|
|
|
*Note:
|
|
|
*Also it seems that @link <a href="http://code.google.com/p/json-sans-eval/">http://code.google.com/p/json-sans-eval/</a>
|
|
|
*treat this issue fine....but not used much...so mentioned only for informal.
|
|
|
*
|
|
|
*Note:
|
|
|
*"If the stringify method sees an object that contains a toJSON method,
|
|
|
*it calls that method, and stringifies the value returned. This allows an
|
|
|
*object to determine its own JSON representation."
|
|
|
*
|
|
|
*@see <a href="http://www.json.org/js.html">http://www.json.org/js.html</a>
|
|
|
**/
|
|
|
toJSON : function() {
|
|
|
//return JSON.stringify(this, ['loaded', 'oType']);
|
|
|
//return JSON.stringify(this);
|
|
|
|
|
|
return function (anImageFrame){
|
|
|
return {
|
|
|
loaded : anImageFrame.loaded,
|
|
|
vector : anImageFrame.vector,
|
|
|
constraints : anImageFrame.constraints,
|
|
|
frameWidth : anImageFrame.frameWidth,
|
|
|
frameHeight : anImageFrame.frameHeight,
|
|
|
scale : anImageFrame.scale,
|
|
|
keepRatio : anImageFrame.keepRatio,
|
|
|
url : anImageFrame.url,
|
|
|
debug : anImageFrame.debug,
|
|
|
style : anImageFrame.style,
|
|
|
oType : anImageFrame.oType
|
|
|
}
|
|
|
}(this);
|
|
|
},
|
|
|
|
|
|
|
|
|
/**
|
|
|
*This will load the image asynchronously
|
|
|
*@param {String} url - the URL used to load image from
|
|
|
*
|
|
|
*Note: It does not work with SVG under Opera 10.x @link <a href="http://my.opera.com/community/forums/topic.dml?id=1052572">http://my.opera.com/community/forums/topic.dml?id=1052572</a>
|
|
|
**/
|
|
|
setUrl : function(url){
|
|
|
Log.info("ImageFrame.setUrl() : " + url);
|
|
|
if(url){ //trigger only if URL is set
|
|
|
this.url = url;
|
|
|
this.loaded = false;
|
|
|
|
|
|
//we need to reacreate the Image again as IE9 will mess up the width and heigh of the image
|
|
|
this.image = new Image();
|
|
|
|
|
|
//Read this http://www.thefutureoftheweb.com/blog/image-onload-isnt-being-called
|
|
|
this.image.onload = function(anImageFrame){
|
|
|
return function(){
|
|
|
anImageFrame.loaded = true;
|
|
|
Log.info("ImageFrame.setUrl(): image finally loaded! :)");
|
|
|
|
|
|
Log.info('ImageFrame.setUrl(): image width:' + anImageFrame.image.width + ' height:' + anImageFrame.image.height);
|
|
|
|
|
|
//in case no frame set use image's dimensions
|
|
|
if(anImageFrame.constraints){
|
|
|
//nothing, we will keep current width and height
|
|
|
Log.info("Constrains present");
|
|
|
}
|
|
|
else{
|
|
|
Log.info("Original image loaded. Image height: " + anImageFrame.image.height + " width: " + anImageFrame.image.width)
|
|
|
if(!anImageFrame.constraints){ //if no constraints than load the image naturally
|
|
|
anImageFrame.frameHeight = anImageFrame.image.height;
|
|
|
anImageFrame.frameWidth = anImageFrame.image.width;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//force a repain - ouch!
|
|
|
Log.info("ImageFrame.setUrl(): force repaint");
|
|
|
draw();
|
|
|
}
|
|
|
} (this);
|
|
|
|
|
|
//attach an error handler
|
|
|
this.image.onerror = function(anImageFrame){
|
|
|
return function (){
|
|
|
Log.error("Error with image. URL: " + anImageFrame.url + " loaded: " + anImageFrame.loaded);
|
|
|
}
|
|
|
} (this);
|
|
|
|
|
|
//trigger loading
|
|
|
this.image.src = url;
|
|
|
}
|
|
|
},
|
|
|
|
|
|
|
|
|
/**We do not have to wait for an image to load to display it's URL
|
|
|
*We can return the image's URL even if the image is not fully loaded/downloaded
|
|
|
*@return {String} - the URL of the image or empty string ('') if no image URL present
|
|
|
**/
|
|
|
getUrl : function(){
|
|
|
if(this.image.src){
|
|
|
return this.image.src;
|
|
|
}
|
|
|
else{
|
|
|
return '';
|
|
|
}
|
|
|
},
|
|
|
|
|
|
|
|
|
/**Paint the Image into the canvas context
|
|
|
*@param {Context} context - the 2D context of the canvas
|
|
|
**/
|
|
|
paint : function(context){
|
|
|
if(this.loaded){
|
|
|
context.save();
|
|
|
//get rotation angle
|
|
|
var angle = Util.getAngle(this.vector[0],this.vector[1]);
|
|
|
|
|
|
//make the rotation
|
|
|
context.translate(this.vector[0].x, this.vector[0].y);
|
|
|
context.rotate(angle);
|
|
|
context.translate(-this.vector[0].x, -this.vector[0].y);
|
|
|
Log.group("A paint");
|
|
|
Log.info("ImageFrame.paint(): frameWidth: " + this.frameWidth + " frameHeight: " + this.frameHeight);
|
|
|
Log.info("ImageFrame.paint(): image.width: " + this.image.width + " image.height: " + this.image.height);
|
|
|
|
|
|
//scale image
|
|
|
var wRatio = this.frameWidth / this.image.width ;
|
|
|
var vRatio = this.frameHeight / this.image.height;
|
|
|
|
|
|
//use minimum ratio
|
|
|
var ratio = Math.min(wRatio, vRatio);
|
|
|
Log.info("ImageFrame.paint(): wRatio: " + wRatio + " vRatio: " + vRatio + " ratio: " + ratio);
|
|
|
|
|
|
//find new scalled width and height
|
|
|
var imgScaledWidth = this.image.width * ratio;
|
|
|
var imgScaleHeight = this.image.height * ratio;
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD>ͼƬƽ<C6AC><C6BD><EFBFBD><EFBFBD>ʾ
|
|
|
imgScaledWidth = this.frameWidth;
|
|
|
imgScaleHeight = this.frameHeight;
|
|
|
Log.info("ImageFrame.paint(): imgScaledWidth: " + imgScaledWidth + " imgScaleHeight: " + imgScaleHeight);
|
|
|
|
|
|
//draw image
|
|
|
context.drawImage(this.image,
|
|
|
this.vector[0].x - imgScaledWidth / 2,
|
|
|
this.vector[0].y - imgScaleHeight / 2,
|
|
|
imgScaledWidth,
|
|
|
imgScaleHeight);
|
|
|
|
|
|
Log.groupEnd();
|
|
|
context.restore();
|
|
|
}
|
|
|
},
|
|
|
|
|
|
|
|
|
/**Transform image
|
|
|
*@param {Array} matrix - the 3x3 transformation matrix
|
|
|
**/
|
|
|
transform : function(matrix){
|
|
|
//vector's dimensions before transformation
|
|
|
var vectorWidth = Math.sqrt( Math.pow(this.vector[0].x - this.vector[1].x, 2) + Math.pow(this.vector[0].y - this.vector[1].y, 2) );
|
|
|
var vectorHeight = Math.sqrt( Math.pow(this.vector[0].x - this.vector[2].x, 2) + Math.pow(this.vector[0].y - this.vector[2].y, 2) );
|
|
|
|
|
|
//transform vector
|
|
|
this.vector[0].transform(matrix);
|
|
|
this.vector[1].transform(matrix);
|
|
|
this.vector[2].transform(matrix);
|
|
|
|
|
|
//if scale is allowed we will do it
|
|
|
if(this.scale){
|
|
|
|
|
|
//vector's NEW dimensions
|
|
|
var vectorWidth2 = Math.sqrt( Math.pow(this.vector[0].x - this.vector[1].x, 2) + Math.pow(this.vector[0].y - this.vector[1].y, 2) );
|
|
|
var vectorHeight2 = Math.sqrt( Math.pow(this.vector[0].x - this.vector[2].x, 2) + Math.pow(this.vector[0].y - this.vector[2].y, 2) );
|
|
|
|
|
|
//find the grow/shrink ratio
|
|
|
var vRatio = vectorWidth2 / vectorWidth;
|
|
|
var hRatio = vectorHeight2 / vectorHeight;
|
|
|
|
|
|
//update the frameset
|
|
|
this.frameHeight *= vRatio;
|
|
|
this.frameWidth *= hRatio;
|
|
|
|
|
|
//now we have constraints
|
|
|
if(vRatio != 1 || hRatio != 1){
|
|
|
this.constraints = true;
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
|
|
|
|
|
|
/**
|
|
|
*Get the angle around the compas between the vector and North direction
|
|
|
*@return {Number} - the angle in radians
|
|
|
*@see /documentation/specs/angle_around_compass.jpg
|
|
|
*@author alex@scriptoid.com
|
|
|
**/
|
|
|
getAngle: function(){
|
|
|
return Util.getAngle(this.vector[0], this.vector[1]);
|
|
|
},
|
|
|
|
|
|
|
|
|
/**Returns the bounds the ImageFrame might have if in normal space (not rotated)
|
|
|
*We will keep it as a Polygon
|
|
|
*@return {Polygon} - a 4 points Polygon
|
|
|
**/
|
|
|
getNormalBounds:function(){
|
|
|
|
|
|
var poly = new Polygon();
|
|
|
|
|
|
if(this.frameWidth && this.frameHeight){ //until the image is loaded we do no not have dimensions set
|
|
|
poly.addPoint(new Point(this.vector[0].x - this.frameWidth/2, this.vector[0].y - this.frameHeight/2));
|
|
|
poly.addPoint(new Point(this.vector[0].x + this.frameWidth/2, this.vector[0].y - this.frameHeight/2));
|
|
|
poly.addPoint(new Point(this.vector[0].x + this.frameWidth/2, this.vector[0].y + this.frameHeight/2));
|
|
|
poly.addPoint(new Point(this.vector[0].x - this.frameWidth/2, this.vector[0].y + this.frameHeight/2));
|
|
|
}
|
|
|
else{ //fake/temporary bounds
|
|
|
poly.addPoint(new Point(this.vector[0].x - ImageFrame.DEFAULT_WIDTH / 2, this.vector[0].y - ImageFrame.DEFAULT_HEIGHT / 2));
|
|
|
poly.addPoint(new Point(this.vector[0].x + ImageFrame.DEFAULT_WIDTH / 2, this.vector[0].y - ImageFrame.DEFAULT_HEIGHT / 2));
|
|
|
poly.addPoint(new Point(this.vector[0].x + ImageFrame.DEFAULT_WIDTH / 2, this.vector[0].y + ImageFrame.DEFAULT_HEIGHT / 2));
|
|
|
poly.addPoint(new Point(this.vector[0].x - ImageFrame.DEFAULT_WIDTH / 2, this.vector[0].y + ImageFrame.DEFAULT_HEIGHT / 2));
|
|
|
}
|
|
|
|
|
|
return poly;
|
|
|
},
|
|
|
|
|
|
|
|
|
/**Tests if the Image contains a point defined by x and y
|
|
|
*@param {Number} x - the x coordinates of the point
|
|
|
*@param {Number} y - the y coordinates of the point
|
|
|
*@return {Boolean} true - if contains, false otherwise
|
|
|
**/
|
|
|
contains: function(x,y){
|
|
|
var contains = false;
|
|
|
|
|
|
if(this.loaded){
|
|
|
var angle = this.getAngle();
|
|
|
|
|
|
var nBounds = this.getNormalBounds();
|
|
|
|
|
|
nBounds.transform( Matrix.translationMatrix(-this.vector[0].x, -this.vector[0].y) );
|
|
|
nBounds.transform(Matrix.rotationMatrix(angle));
|
|
|
nBounds.transform(Matrix.translationMatrix(this.vector[0].x, this.vector[0].y));
|
|
|
|
|
|
try{
|
|
|
contains = nBounds.contains(x,y);
|
|
|
}catch(ex){
|
|
|
Log.error("ImageFrame->contains(error): " + ex);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return contains;
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
*Returns the bounds - in transformed space - of the Image
|
|
|
*@return {Array} - returns [minX, minY, maxX, maxY] - bounds, where all points are in the bounds.
|
|
|
*/
|
|
|
getBounds : function (){
|
|
|
var angle = Util.getAngle(this.vector[0],this.vector[1]);
|
|
|
|
|
|
var nBounds = this.getNormalBounds(); //as Polygon
|
|
|
|
|
|
nBounds.transform(Matrix.translationMatrix(-this.vector[0].x, -this.vector[0].y) );
|
|
|
nBounds.transform(Matrix.rotationMatrix(angle));
|
|
|
nBounds.transform(Matrix.translationMatrix(this.vector[0].x, this.vector[0].y));
|
|
|
|
|
|
return nBounds.getBounds();
|
|
|
},
|
|
|
|
|
|
|
|
|
/**
|
|
|
*Fake method as Image does not have the concept of points (yet?!)
|
|
|
*But we will forward to the bounds {@link Polygon}
|
|
|
*@return {Array} - an array of {@link Polygon}s
|
|
|
**/
|
|
|
getPoints : function (){
|
|
|
var angle = Util.getAngle(this.vector[0],this.vector[1]);
|
|
|
|
|
|
var nBounds = this.getNormalBounds(); //as Polygon
|
|
|
|
|
|
nBounds.transform(Matrix.translationMatrix(-this.vector[0].x, -this.vector[0].y) );
|
|
|
nBounds.transform(Matrix.rotationMatrix(angle));
|
|
|
nBounds.transform(Matrix.translationMatrix(this.vector[0].x, this.vector[0].y));
|
|
|
|
|
|
return nBounds.getPoints();
|
|
|
},
|
|
|
|
|
|
/**This function returns a deed clone of current {ImageFrame}
|
|
|
*@return {ImageFrame} - the cloned ImageFrame
|
|
|
**/
|
|
|
clone:function(){
|
|
|
//make a new object
|
|
|
var cImg = new ImageFrame();
|
|
|
|
|
|
//copy what we can
|
|
|
cImg.frameHeight = this.frameHeight;
|
|
|
cImg.frameWidth = this.frameWidth;
|
|
|
cImg.keepRatio = this.keepRatio;
|
|
|
cImg.constraints = this.constraints;
|
|
|
cImg.vector = Point.cloneArray(this.vector) ;
|
|
|
|
|
|
//reset the URL so that the cImg.image will be loaded with new URL
|
|
|
cImg.setUrl(this.url);
|
|
|
|
|
|
return cImg;
|
|
|
},
|
|
|
|
|
|
/**
|
|
|
*Export the image to SVG
|
|
|
*@return {String} the SVG representation of the Image
|
|
|
*
|
|
|
Example of what image should generate
|
|
|
@example
|
|
|
<g transform = "rotate(10, 160, 50)">
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="320" height="100"> <!--I think x = 0 and y = 0 by default @see http://apike.ca/prog_svg_patterns.html-->
|
|
|
<rect x="10" y="10" height="3" width="3" style="stroke: #006600; fill: #DDDDDD"/>
|
|
|
<image x="20" y="20" width="300" height="80" xlink:href="http://diagramo.com/assets/images/logo.gif" />
|
|
|
</svg>
|
|
|
</g>
|
|
|
@see http://tutorials.jenkov.com/svg/g-element.html ("SVG: g element")
|
|
|
**/
|
|
|
toSVG : function (){
|
|
|
var svg = '';
|
|
|
|
|
|
if(this.loaded){
|
|
|
var angle = this.getAngle() * 180 / Math.PI;
|
|
|
// var angle = this.getAngle() * 180 / Math.PI;
|
|
|
|
|
|
svg += "\n" + repeat("\t", INDENTATION) + '<g transform="rotate (' + angle + ', ' + this.vector[0].x + ', ' + this.vector[0].y + ')">';
|
|
|
INDENTATION++;
|
|
|
// svg += "\n" + repeat("\t", INDENTATION) + '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">';
|
|
|
|
|
|
|
|
|
Log.group("A paint");
|
|
|
Log.info("ImageFrame.toSVG(): frameWidth: " + this.frameWidth + " frameHeight: " + this.frameHeight);
|
|
|
Log.info("ImageFrame.toSVG(): image.width: " + this.image.width + " image.height: " + this.image.height);
|
|
|
|
|
|
//scale image
|
|
|
var wRatio = this.frameWidth / this.image.width ;
|
|
|
var vRatio = this.frameHeight / this.image.height;
|
|
|
var ratio = Math.min(wRatio, vRatio);
|
|
|
Log.info("ImageFrame.toSVG(): wRatio: " + wRatio + " vRatio: " + vRatio + " ratio: " + ratio);
|
|
|
|
|
|
var imgScaledWidth = this.image.width * ratio;
|
|
|
var imgScaleHeight = this.image.height * ratio;
|
|
|
Log.info("ImageFrame.toSVG(): imgScaledWidth: " + imgScaledWidth + " imgScaleHeight: " + imgScaleHeight);
|
|
|
|
|
|
// context.drawImage(this.image, this.vector[0].x - this.frameWidth / 2,
|
|
|
// this.vector[0].y - this.frameHeight / 2, this.frameWidth, this.frameHeight);
|
|
|
|
|
|
var imageX = this.vector[0].x - imgScaledWidth / 2;
|
|
|
var imageY = this.vector[0].y - imgScaleHeight / 2;
|
|
|
|
|
|
// INDENTATION++;
|
|
|
svg += "\n" + repeat("\t", INDENTATION) + '<image x="' + imageX + '" y="' + imageY +'" width="' + imgScaledWidth + '" height="' + imgScaleHeight + '" xlink:href="' + this.getUrl() + '" />';
|
|
|
// INDENTATION--;
|
|
|
Log.groupEnd();
|
|
|
|
|
|
// svg += "\n" + repeat("\t", INDENTATION) + '</svg>';
|
|
|
INDENTATION--;
|
|
|
svg += "\n" + repeat("\t", INDENTATION) + '</g>';
|
|
|
}
|
|
|
|
|
|
return svg;
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
/*
|
|
|
* "Static" method used for importing images
|
|
|
* @param {String} url - the URL of the image. Pay attention to come from same base URL as the application
|
|
|
* @param {Number} x - X coordinates of the figure
|
|
|
* @param {Number} y - Y coordinates of the figure
|
|
|
* @author Artyom, Alex
|
|
|
* */
|
|
|
ImageFrame.figure_InsertedImage = function(url, x, y)
|
|
|
{
|
|
|
// create new figure
|
|
|
var f = new Figure("InsertedImage");
|
|
|
f.style.fillStyle = FigureDefaults.fillStyle;
|
|
|
f.style.strokeStyle = FigureDefaults.strokeStyle;
|
|
|
|
|
|
// figure's part with image
|
|
|
var ifig = new ImageFrame(url, x, y, true);
|
|
|
f.addPrimitive(ifig);
|
|
|
|
|
|
// set callback to get image's natural size and use it for new figure
|
|
|
ifig.image.addEventListener("load", function (){
|
|
|
|
|
|
// image size
|
|
|
var imageWidth = ifig.image.width;
|
|
|
var imageHeight = ifig.image.height;
|
|
|
|
|
|
//Text
|
|
|
f.properties.push(new BuilderProperty('Text', 'primitives.1.str', BuilderProperty.TYPE_TEXT));
|
|
|
f.properties.push(new BuilderProperty('Text Size', 'primitives.1.size', BuilderProperty.TYPE_TEXT_FONT_SIZE));
|
|
|
f.properties.push(new BuilderProperty('Font', 'primitives.1.font', BuilderProperty.TYPE_TEXT_FONT_FAMILY));
|
|
|
f.properties.push(new BuilderProperty('Alignment', 'primitives.1.align', BuilderProperty.TYPE_TEXT_FONT_ALIGNMENT));
|
|
|
f.properties.push(new BuilderProperty('Text Underlined', 'primitives.1.underlined', BuilderProperty.TYPE_TEXT_UNDERLINED));
|
|
|
f.properties.push(new BuilderProperty('Text Color', 'primitives.1.style.fillStyle', BuilderProperty.TYPE_COLOR));
|
|
|
|
|
|
f.properties.push(new BuilderProperty('URL', 'url', BuilderProperty.TYPE_URL));
|
|
|
|
|
|
var t2 = new Text(FigureDefaults.textStr, x, y + imageHeight / 2 + FigureDefaults.textSize * 2, FigureDefaults.textFont, FigureDefaults.textSize);
|
|
|
t2.style.fillStyle = FigureDefaults.textColor;
|
|
|
f.addPrimitive(t2);
|
|
|
|
|
|
ifig.frameHeight = imageHeight + FigureDefaults.textSize;
|
|
|
|
|
|
//Connection Points
|
|
|
CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x + imageWidth / 2, y), ConnectionPoint.TYPE_FIGURE);
|
|
|
CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x - imageWidth / 2, y), ConnectionPoint.TYPE_FIGURE);
|
|
|
CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x, y - imageHeight / 2), ConnectionPoint.TYPE_FIGURE);
|
|
|
CONNECTOR_MANAGER.connectionPointCreate(f.id, new Point(x, y + imageHeight / 2 + FigureDefaults.textSize * 3), ConnectionPoint.TYPE_FIGURE);
|
|
|
|
|
|
f.finalise();
|
|
|
draw();
|
|
|
}, false);
|
|
|
|
|
|
f.finalise();
|
|
|
return f;
|
|
|
}; |