Mercurial > hg > digilib
view client/digitallibrary/jquery/dlGeometry.js @ 629:6b24ad042d7b jquery
last and next page works now
implemented redisplay function (only tested with fullscreen)
parameters that are changed need to be in data.queryParams to get in the url on redisplay
author | robcast |
---|---|
date | Tue, 18 Jan 2011 21:30:03 +0100 |
parents | b930fa64c684 |
children | a2aadf44a454 8f76bd79648e |
line wrap: on
line source
/* digilib geometry classes * should be integrated into jquery.digilib.js */ var dlGeometry = function() { /* * Size class */ var size = function (w, h) { var that = { width : parseFloat(w), height : parseFloat(h) }; that.equals = function(other) { return (this.width === other.width && this.height === other.height); }; that.toString = function() { return (this.width + "x" + this.height); }; return that; }; /* * Position class */ var position = function (x, y) { var that = { x : parseFloat(x), y : parseFloat(y) }; that.equals = function(other) { return (this.x === other.x && this.y === other.y); }; that.toString = function() { return (this.x + "," + this.y); }; return that; }; /* * Rectangle class */ var rectangle = function (x, y, w, h) { var that = {}; if (typeof x === "object") { // assume x and y are Position that = { x : x.x, y : x.y, width : y.x - x.x, height : y.y - x.y }; } else { that = { x : parseFloat(x), y : parseFloat(y), width : parseFloat(w), height : parseFloat(h) }; } // returns a copy of this Rectangle that.copy = function() { return rectangle(this.x, this.y, this.width, this.height); }; // returns the position of this Rectangle that.getPosition = function() { return position(this.x, this.y); }; // returns the upper left corner position that.getPt1 = that.getPosition; // returns the lower right corner position of this Rectangle that.getPt2 = function() { return position(this.x + this.width, this.y + this.height); }; // sets the upper left corner to position pos that.setPt1 = function(pos) { this.x = pos.x; this.y = pos.y; return this; }; that.setPt2 = function(pos) { // sets the lower right corner to position pos this.width = pos.x - this.x; this.height = pos.y - this.y; return this; }; that.getCenter = function() { // returns the center position of this Rectangle return position(this.x + this.width / 2, this.y + this.height / 2); }; that.setCenter = function(pos) { // moves this Rectangle's center to position pos this.x = pos.x - this.width / 2; this.y = pos.y - this.height / 2; return this; }; that.getSize = function() { // returns the size of this Rectangle return size(this.width, this.height); }; that.equals = function(other) { // equal props var eq = (this.x === other.x && this.y === other.y && this.width === other.width); return eq; }; that.getArea = function() { // returns the area of this Rectangle return (this.width * this.height); }; that.normalize = function() { // eliminates negative width and height var p = this.getPt2(); this.x = Math.min(this.x, p.x); this.y = Math.min(this.y, p.y); this.width = Math.abs(this.width); this.height = Math.abs(this.height); return this; }; that.containsPosition = function(pos) { // returns if Position "pos" lies inside of this rectangle var ct = ((pos.x >= this.x) && (pos.y >= this.y) && (pos.x <= this.x + this.width) && (pos.y <= this.y + this.width)); return ct; }; that.containsRect = function(rect) { // returns if rectangle "rect" is contained in this rectangle return (this.containsPosition(rect.getPt1()) && this.containsPosition(rect.getPt2())); }; that.stayInside = function(rect) { // changes this rectangle's x/y values so it stays inside of rectangle rect // keeping the proportions if (this.x < rect.x) { this.x = rect.x; } if (this.y < rect.y) { this.y = rect.y; } if (this.x + this.width > rect.x + rect.width) { this.x = rect.x + rect.width - this.width; } if (this.y + this.height > rect.y + rect.height) { this.y = rect.y + rect.height - this.height; } return this; }; that.clipTo = function(rect) { // clips this rectangle so it stays inside of rectangle rect var p1 = rect.getPt1(); var p2 = rect.getPt2(); var this2 = this.getPt2(); this.setPt1(position(Math.max(this.x, p1.x), Math.max(this.y, p1.y))); this.setPt2(position(Math.min(this2.x, p2.x), Math.min(this2.y, p2.y))); return this; }; that.intersect = function(rect) { // returns the intersection of the given Rectangle and this one // FIX ME: not really, it should return null if there is no overlap var sec = rect.copy(); if (sec.x < this.x) { sec.width = sec.width - (this.x - sec.x); sec.x = this.x; } if (sec.y < this.y) { sec.height = sec.height - (this.y - sec.y); sec.y = this.y; } if (sec.x + sec.width > this.x + this.width) { sec.width = (this.x + this.width) - sec.x; } if (sec.y + sec.height > this.y + this.height) { sec.height = (this.y + this.height) - sec.y; } return sec; }; that.fit = function(rect) { // returns a Rectangle that fits into this one (by moving first) var sec = rect.copy(); sec.x = Math.max(sec.x, this.x); sec.y = Math.max(sec.y, this.x); if (sec.x + sec.width > this.x + this.width) { sec.x = this.x + this.width - sec.width; } if (sec.y + sec.height > this.y + this.height) { sec.y = this.y + this.height - sec.height; } return sec.intersect(this); }; that.toString = function() { return this.width+"x"+this.height+"@"+this.x+","+this.y; }; return that; }; /* * Transform class * * defines a class of affine transformations */ var transform = function (spec) { var that = jQuery.extend({ m00 : 1.0, m01 : 0.0, m02 : 0.0, m10 : 0.0, m11 : 1.0, m20 : 0.0, m12 : 0.0, m21 : 0.0, m22 : 1.0 }, spec); that.concat = function(traf) { // add Transform traf to this Transform for (var i = 0; i < 3; i++) { for (var j = 0; j < 3; j++) { var c = 0.0; for (var k = 0; k < 3; k++) { c += traf["m"+i+k] * this["m"+k+j]; } this["m"+i+j] = c; } } return this; }; that.transform = function(rect) { // returns transformed Rectangle or Position with this Transform applied var x = this.m00 * rect.x + this.m01 * rect.y + this.m02; var y = this.m10 * rect.x + this.m11 * rect.y + this.m12; if (rect.width) { // transform the other corner points var pt2 = rect.getPt2(); var x2 = this.m00 * pt2.x + this.m01 * pt2.y + this.m02; var y2 = this.m10 * pt2.x + this.m11 * pt2.y + this.m12; var width = x2 - x; var height = y2 - y; return rectangle(x, y, width, height); } return position(x, y); }; that.invtransform = function(rect) { // returns transformed Rectangle or Position with the inverse of this Transform applied var det = this.m00 * this.m11 - this.m01 * this.m10; var x = (this.m11 * rect.x - this.m01 * rect.y - this.m11 * this.m02 + this.m01 * this.m12) / det; var y = (- this.m10 * rect.x + this.m00 * rect.y + this.m10 * this.m02 - this.m00 * this.m12) / det; if (rect.width) { // transform the other corner points var pt2 = rect.getPt2(); var x2 = (this.m11 * pt2.x - this.m01 * pt2.y - this.m11 * this.m02 + this.m01 * this.m12) / det; var y2 = (- this.m10 * pt2.x + this.m00 * pt2.y + this.m10 * this.m02 - this.m00 * this.m12) / det; var width = x2 - x; var height = y2 - y; return rectangle(x, y, width, height); } return position(x, y); }; that.getRotation = transform.getRotation; that.getTranslation = transform.getTranslation; that.getScale = transform.getScale; return that; }; transform.getRotation = function (angle, pos) { // returns a Transform that is a rotation by angle degrees around [pos.x, pos.y] if (angle !== 0) { var t = 2.0 * Math.PI * parseFloat(angle) / 360.0; var traf = { m00 : Math.cos(t), m01 : - Math.sin(t), m10 : Math.sin(t), m11 : Math.cos(t), m02 : pos.x - pos.x * Math.cos(t) + pos.y * Math.sin(t), m12 : pos.y - pos.x * Math.sin(t) - pos.y * Math.cos(t) }; return transform(traf); } return transform(); }; transform.getTranslation = function (pos) { // returns a Transform that is a translation by [pos.x, pos,y] var traf = { m02 : pos.x, m12 : pos.y }; return transform(traf); }; transform.getScale = function (size) { // returns a Transform that is a scale by [size.width, size.height] var traf = { m00 : size.width, m11 : size.height }; return transform(traf); }; // export functions var that = { size : size, position : position, rectangle : rectangle, transform : transform }; return that; };