1 /*
  2     Copyright 2008,2009
  3         Matthias Ehmann,
  4         Michael Gerhaeuser,
  5         Carsten Miller,
  6         Bianca Valentin,
  7         Alfred Wassermann,
  8         Peter Wilfahrt
  9 
 10     This file is part of JSXGraph.
 11 
 12     JSXGraph is free software: you can redistribute it and/or modify
 13     it under the terms of the GNU Lesser General Public License as published by
 14     the Free Software Foundation, either version 3 of the License, or
 15     (at your option) any later version.
 16 
 17     JSXGraph is distributed in the hope that it will be useful,
 18     but WITHOUT ANY WARRANTY; without even the implied warranty of
 19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 20     GNU Lesser General Public License for more details.
 21 
 22     You should have received a copy of the GNU Lesser General Public License
 23     along with JSXGraph.  If not, see <http://www.gnu.org/licenses/>.
 24 
 25 */
 26 
 27 /**
 28  * @fileoverview In this file the geometry element Image is defined.
 29  * @author graphjs
 30  * @version 0.1
 31  */
 32 
 33 /**
 34  * Construct and handle images
 35  * @class Image:
 36  * It inherits from @see GeometryElement.
 37  * @constructor
 38  * @return A new geometry element Image
 39  */
 40 JXG.Image = function (board, url, coordinates, size, layer, id, name, el) {
 41     //this.constructor();
 42     this.type = JXG.OBJECT_TYPE_IMAGE;
 43     this.elementClass = JXG.OBJECT_CLASS_OTHER;                
 44     this.transformations = [];
 45 
 46     this.init(board, id, name);
 47     //this.coords = new JXG.Coords(JXG.COORDS_BY_USER, coordinates, this.board);
 48     this.initialCoords = new JXG.Coords(JXG.COORDS_BY_USER, coordinates, this.board);  // Still needed?
 49 
 50     this.X = JXG.createFunction(coordinates[0],this.board,'');
 51     this.Y = JXG.createFunction(coordinates[1],this.board,'');
 52     this.W = JXG.createFunction(size[0],this.board,'');
 53     this.H = JXG.createFunction(size[1],this.board,'');
 54     this.coords = new JXG.Coords(JXG.COORDS_BY_USER, [this.X(),this.Y()], this.board);
 55     this.updateCoords = new Function('','this.coords.setCoordinates(JXG.COORDS_BY_USER,[this.X(),this.Y()]);');
 56     this.updateSize = new Function('','this.coords.setCoordinates(JXG.COORDS_BY_USER,[this.W(),this.H()]);');
 57     this.usrSize = [this.W(), this.H()];
 58     this.size = [this.usrSize[0]*board.stretchX,this.usrSize[1]*board.stretchY];
 59     this.url = url;
 60     /**
 61      * Set the display layer.
 62      */
 63     if (layer == null) layer = board.options.layer['image'];
 64     this.layer = layer;
 65     this.parent = el;
 66     this.visProp['visible'] = true;
 67 
 68     this.id = this.board.setId(this, 'Im');
 69 
 70     this.board.renderer.drawImage(this);
 71     if(!this.visProp['visible']) {
 72        this.board.renderer.hide(this);
 73     }
 74 };
 75 
 76 JXG.Image.prototype = new JXG.GeometryElement;
 77 
 78 /**
 79  * Empty function (for the moment). It is needed for highlighting, a feature not used for images right now.
 80  * @param {int} x Coordinate in x direction, screen coordinates.
 81  * @param {int} y Coordinate in y direction, screen coordinates.
 82  * @return Always returns false
 83  */
 84 JXG.Image.prototype.hasPoint = function (x,y) {
 85     return false;
 86 };
 87 
 88 /**
 89  * Recalculate the coordinates of lower left corner and the width amd the height.
 90  * @private
 91  */
 92 JXG.Image.prototype.update = function () {
 93     if (this.needsUpdate) {
 94         this.updateCoords();
 95         this.usrSize = [this.W(), this.H()];
 96         this.size = [this.usrSize[0]*this.board.stretchX,this.usrSize[1]*this.board.stretchY];
 97         this.updateTransform();
 98     }
 99     return this;
100 };
101 
102 /**
103  * Send an update request to the renderer.
104  */
105 JXG.Image.prototype.updateRenderer = function () {
106     if (this.needsUpdate) {
107         this.board.renderer.updateImage(this);
108         this.needsUpdate = false;
109     }
110     return this;
111 };
112 
113 JXG.Image.prototype.updateTransform = function () {
114     if (this.transformations.length==0) {
115         return;
116     }
117     for (var i=0;i<this.transformations.length;i++) {
118         this.transformations[i].update();
119     }
120 };
121 
122 JXG.Image.prototype.addTransform = function (transform) {
123     if (JXG.isArray(transform)) {
124         for (var i=0;i<transform.length;i++) {
125             this.transformations.push(transform[i]);
126         }
127     } else {
128         this.transformations.push(transform);
129     }
130 };
131 
132 /**
133  * @class Displays an image. 
134  * @pseudo
135  * @description Shows an image. The image can be supplied as an URL or an base64 encoded inline image 
136  * like "data:image/png;base64, /9j/4AAQSkZJRgA..." or a function returning an URL: function(){ return 'xxx.png; }.
137  * @constructor
138  * @name Image
139  * @type JXG.Image
140  * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.
141  * @param {String_Array_Array} url, [position of the top left vertice], [width,height] 
142  * @example
143  * var im = board.create('image', ['http://geonext.uni-bayreuth.de/fileadmin/geonext/design/images/logo.gif', [-3,1],[5,5]]);
144  *
145  * </pre><div id="9850cda0-7ea0-4750-981c-68bacf9cca57" style="width: 400px; height: 400px;"></div>
146  * <script type="text/javascript">
147  *   var image_board = JXG.JSXGraph.initBoard('9850cda0-7ea0-4750-981c-68bacf9cca57', {boundingbox: [-4, 4, 4, -4], axis: false, showcopyright: false, shownavigation: false});
148  *   var image_im = image_board.create('image', ['http://jsxgraph.uni-bayreuth.de/distrib/images/uccellino.jpg', [-3,1],[5,5]]);
149  * </script><pre>
150  */
151 JXG.createImage = function(board, parents, atts) {
152     var url;
153     if (atts==null) {
154         atts = {};
155     } else if (atts['imageString']!=null) {
156         url = atts['imageString'];
157     }
158     if (typeof atts['layer'] == 'undefined') {
159         atts['layer'] = null;
160     }
161     return new JXG.Image(board, parents[0], parents[1], parents[2], atts['layer'], false, false);
162 };
163 
164 JXG.JSXGraph.registerElement('image', JXG.createImage);
165