/* * MouseModulator * Version 1.0, 12/11/2001 * * Copyright (c) 2001 by Netzministerium.de * Written by Till Nagel and René Sander. * Distributed under the terms of the GNU Lesser General Public. (See licence.txt for details) */ /* * Constructs a MouseModulator. * This modulator returns a transformation matrix depending on mouse interactions. * * When a mouseUp event occurs the rotation will fade to null (spins the object). * * Parameters: * String name - the name of the variable storing this object * e.g. var myMouseModulator = new MouseModulator("myMouseModulator"); * int mode - the interaction mode of the modulator, use MouseModulator.MODE_xxx * constants here. You can rotate around x and y (MODE_ROTATE), just on of them * (MODE_ROTATE_X and MODE_ROTATE_Y), or move the model (MODE_MOVE). * * Returns: * MouseModulator - a new MouseModulator instance */ function MouseModulator(name, mode) { // the name of the variable storing this object this.name = name; // interaction mode this.mode = mode ? mode : MouseModulator.MODE_ROTATE; this.matrix = new Matrix(); // mouse coordinates this.mouseX = 0; this.mouseY = 0; // to store old mouse coordinates this.oldX = 0; this.oldY = 0; this.oldX2 = 0; this.oldY2 = 0; // flag to show if the mouse is down this.isDown = false; // responsible for deceleration this.decSteps = 0; // spinning speed this.spinDX = 0; this.spinDY = 0; this.getMatrix = MouseModulatorGetMatrix; this.animate = MouseModulatorAnimate; this.render = MouseModulatorRender; this.move = MouseModulatorMove; this.up = MouseModulatorUp; this.down = MouseModulatorDown; return this; } /* * Constants specifying the possible interaction modes. * Use these when setting the modulator's mode, e.g. * myMouseModulator.setMode(MouseModulator.MODE_ROTATE); */ MouseModulator.MODE_ROTATE = 0; MouseModulator.MODE_MOVE = 1; MouseModulator.MODE_ROTATE_X = 2; MouseModulator.MODE_ROTATE_Y = 3; /* * Returns the (rotation) matrix to transform with. * * Returns: * Matrix - The matrix to transform with. */ function MouseModulatorGetMatrix() { // #1 WORKS m = this.matrix; // m = this.matrix.getCopy(); // would be no difference this.matrix = new Matrix(); return m; // #2 doesn't work // because of the two render()-calls. one direct in animate() to spin. // and a triggered call in move() to rotate the mouse when dragging. // it is triggered to decouple mouse events and // looped call of the main animate method in the using application. // ** return this.matrix; } /* * MouseModulator.animate * Updates the modulator's matrix according to mouse movements. */ function MouseModulatorAnimate() { // spins the model if (this.decSteps > 1) { // decreases by factor 0.9 this.decSteps *= 0.9; this.spinDX *= 0.9; this.spinDY *= 0.9; this.render(this.spinDX, this.spinDY); } else { if (this.isDown) { // resets spinning speed (the difference of two old mouse positions) // each animate call because there is no event mouseNotMove. this.oldX2 = this.oldX; this.oldY2 = this.oldY; } } } /* * MouseModulator.up * The mouseUp eventhandler. Pass the event object e when calling * this method in the page's event handler. * * Parameters * Event e - the event object, just pass this on from your original handler */ function MouseModulatorUp(e) { // gets the speed (the difference of two old mouse positions) // at the moment of mouseUp this.decSteps = 100; this.spinDX = (this.oldX - this.oldX2) / 20; this.spinDY = (this.oldY2 - this.oldY) / 20; // starts spinning this.animate(); // stores old coordinates (mouseX and mouseY are set in mouseMove() ) this.oldX = this.mouseX; this.oldY = this.mouseY; // to prohibit moveHandler to render this.isDown = false; } /* * MouseModulator.down * The mouseDown eventhandler. Pass the event object e when calling * this method in the page's event handler. * * Parameters * Event e - the event object, just pass this on from your original handler */ function MouseModulatorDown(e) { if (ns || ie || ns6) { this.mouseX = (ns || ns6) ? e.pageX : event.x; this.mouseY = (ns || ns6) ? e.pageY : event.y; } // stores old coordinates this.oldX = this.mouseX; this.oldY = this.mouseY; this.decSteps = 0; // to allow moveHandler to render this.isDown = true; } /* * MouseModulator.move * The mouseMove eventhandler. Pass the event object e when calling * this method in the page's event handler. * * Parameters * Event e - the event object, just pass this on from your original handler */ // MouseModulator.prototype.move = function(e) { function MouseModulatorMove(e) { // Just calculates new phi if mouse is down if (this.isDown) { // gets mouse coordinates if (ns || ie || ns6) { this.mouseX = (ns || ns6) ? e.pageX : event.x; this.mouseY = (ns || ns6) ? e.pageY : event.y; } //status = "mX=" + mouseX + ", mY=" + mouseY + ", oldX=" + this.oldX + ", oldY=" + this.oldY; // calculates phi (rotation degree) var dX = ((this.mouseX - this.oldX) / 20) // Math.max( Math.min(((mouseX - oldX) / 20), 0.1), -0.1); var dY = ((this.oldY - this.mouseY) / 20) //Math.max( Math.min(((oldY - mouseY) / 20), 0.1), -0.1); // stores the old coordinates (see MouseModulatorUp) this.oldX2 = this.oldX; this.oldY2 = this.oldY; // stores the new coordinates this.oldX = this.mouseX; this.oldY = this.mouseY; // pings render method setTimeout(this.name + ".render(" + dX + "," + dY + ")", 1); //this.render(dX, dY); } } /* * MouseModulator.render * In the render method, the modulator's matrix * is computed using the current control values. * * The way the connected object can be rotated * and/or moved depends on the interaction mode. * * Paramters * int dX - x distance amount * int dY - y distance amount */ function MouseModulatorRender(dX, dY) { // As Netscape 4.x cannot handle case statements // with variables (!), we're using plain numbers // instead of the respective MouseModulator.MODE_XXX constants. switch (this.mode) { // Rotate and Spin // MouseModulator.MODE_ROTATE == 0 case 0 : var mx = new Matrix(); mx.rotateX(dY); mx.rotateY(dX); this.matrix = mx; break; // Rotate and Spin X // MouseModulator.MODE_ROTATE_X == 2 case 2 : mx = new Matrix(); // correct, because changing the y coordinate gives you // the amount of rotation (which is done along the x-axis) mx.rotateX(dY); this.matrix = mx; break; // Rotate and Spin Y // MouseModulator.MODE_ROTATE_Y == 3 case 3 : mx = new Matrix(); mx.rotateY(dX); this.matrix = mx; break; // Move and Slide // MouseModulator.MODE_MOVE == 1 case 1 : mt = new Matrix(); mt.translate(dX*20, -dY*20, 0); this.matrix = mt ; break; default : } }