Browse Source

Merge pull request #2357 from wimrijnders/PR28

Readied 3d camera orientation code for merge into develop branch
codeClimate
yotamberk 8 years ago
committed by GitHub
parent
commit
52b7474c3c
2 changed files with 94 additions and 26 deletions
  1. +45
    -1
      lib/graph3d/Camera.js
  2. +49
    -25
      lib/graph3d/Graph3d.js

+ 45
- 1
lib/graph3d/Camera.js View File

@ -16,6 +16,8 @@ function Camera() {
this.armRotation.horizontal = 0; this.armRotation.horizontal = 0;
this.armRotation.vertical = 0; this.armRotation.vertical = 0;
this.armLength = 1.7; this.armLength = 1.7;
this.cameraOffset = new Point3d();
this.offsetMultiplier = 0.6;
this.cameraLocation = new Point3d(); this.cameraLocation = new Point3d();
this.cameraRotation = new Point3d(0.5*Math.PI, 0, 0); this.cameraRotation = new Point3d(0.5*Math.PI, 0, 0);
@ -23,6 +25,36 @@ function Camera() {
this.calculateCameraOrientation(); this.calculateCameraOrientation();
} }
/**
* Set offset camera in camera coordinates
* @param {Number} x offset by camera horisontal
* @param {Number} y offset by camera vertical
*/
Camera.prototype.setOffset = function(x, y) {
var abs = Math.abs,
sign = Math.sign,
mul = this.offsetMultiplier,
border = this.armLength * mul;
if (abs(x) > border) {
x = sign(x) * border;
}
if (abs(y) > border) {
y = sign(y) * border;
}
this.cameraOffset.x = x;
this.cameraOffset.y = y;
this.calculateCameraOrientation();
};
/**
* Get camera offset by horizontal and vertical
* @return {Point3d} x - horizontal offset, y - vertical offset, z - not used
*/
Camera.prototype.getOffset = function(x, y) {
return this.cameraOffset;
};
/** /**
* Set the location (origin) of the arm * Set the location (origin) of the arm
* @param {Number} x Normalized value of x * @param {Number} x Normalized value of x
@ -89,6 +121,7 @@ Camera.prototype.setArmLength = function(length) {
if (this.armLength < 0.71) this.armLength = 0.71; if (this.armLength < 0.71) this.armLength = 0.71;
if (this.armLength > 5.0) this.armLength = 5.0; if (this.armLength > 5.0) this.armLength = 5.0;
this.setOffset(this.cameraOffset.x, this.cameraOffset.y);
this.calculateCameraOrientation(); this.calculateCameraOrientation();
}; };
@ -130,6 +163,17 @@ Camera.prototype.calculateCameraOrientation = function() {
this.cameraRotation.x = Math.PI/2 - this.armRotation.vertical; this.cameraRotation.x = Math.PI/2 - this.armRotation.vertical;
this.cameraRotation.y = 0; this.cameraRotation.y = 0;
this.cameraRotation.z = -this.armRotation.horizontal; this.cameraRotation.z = -this.armRotation.horizontal;
var xa = this.cameraRotation.x;
var ya = this.cameraRotation.y;
var za = this.cameraRotation.z;
var dx = this.cameraOffset.x;
var dy = this.cameraOffset.y;
var sin = Math.sin, cos = Math.cos;
this.cameraLocation.x = this.cameraLocation.x + dx * cos(za) + dy * - sin(za) * cos(xa);
this.cameraLocation.y = this.cameraLocation.y + dx * sin(za) + dy * cos(za) * cos(xa);
this.cameraLocation.z = this.cameraLocation.z + dy * sin(xa);
}; };
module.exports = Camera;
module.exports = Camera;

+ 49
- 25
lib/graph3d/Graph3d.js View File

@ -1888,6 +1888,19 @@ Graph3d.prototype._redrawDataGraph = function() {
// End methods for drawing points per graph style. // End methods for drawing points per graph style.
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
/**
* Store startX, startY and startOffset for mouse operations
*
* @param {Event} event The event that occurred
*/
Graph3d.prototype._storeMousePosition = function(event) {
// get mouse position (different code for IE and all other browsers)
this.startMouseX = getMouseX(event);
this.startMouseY = getMouseY(event);
this._startCameraOffset = this.camera.getOffset();
};
/** /**
* Start a moving operation inside the provided parent element * Start a moving operation inside the provided parent element
@ -1907,9 +1920,7 @@ Graph3d.prototype._onMouseDown = function(event) {
this.leftButtonDown = event.which ? (event.which === 1) : (event.button === 1); this.leftButtonDown = event.which ? (event.which === 1) : (event.button === 1);
if (!this.leftButtonDown && !this.touchDown) return; if (!this.leftButtonDown && !this.touchDown) return;
// get mouse position (different code for IE and all other browsers)
this.startMouseX = getMouseX(event);
this.startMouseY = getMouseY(event);
this._storeMousePosition(event);
this.startStart = new Date(this.start); this.startStart = new Date(this.start);
this.startEnd = new Date(this.end); this.startEnd = new Date(this.end);
@ -1940,31 +1951,44 @@ Graph3d.prototype._onMouseMove = function (event) {
// calculate change in mouse position // calculate change in mouse position
var diffX = parseFloat(getMouseX(event)) - this.startMouseX; var diffX = parseFloat(getMouseX(event)) - this.startMouseX;
var diffY = parseFloat(getMouseY(event)) - this.startMouseY; var diffY = parseFloat(getMouseY(event)) - this.startMouseY;
// move with ctrl or rotate by other
if (event && event.ctrlKey === true) {
// calculate change in mouse position
var scaleX = this.frame.clientWidth * 0.5;
var scaleY = this.frame.clientHeight * 0.5;
var offXNew = (this._startCameraOffset.x || 0) - ((diffX / scaleX) * this.camera.armLength) * 0.8;
var offYNew = (this._startCameraOffset.y || 0) + ((diffY / scaleY) * this.camera.armLength) * 0.8;
this.camera.setOffset(offXNew, offYNew);
this._storeMousePosition(event);
} else {
var horizontalNew = this.startArmRotation.horizontal + diffX / 200;
var verticalNew = this.startArmRotation.vertical + diffY / 200;
var snapAngle = 4; // degrees
var snapValue = Math.sin(snapAngle / 360 * 2 * Math.PI);
// snap horizontally to nice angles at 0pi, 0.5pi, 1pi, 1.5pi, etc...
// the -0.001 is to take care that the vertical axis is always drawn at the left front corner
if (Math.abs(Math.sin(horizontalNew)) < snapValue) {
horizontalNew = Math.round(horizontalNew / Math.PI) * Math.PI - 0.001;
}
if (Math.abs(Math.cos(horizontalNew)) < snapValue) {
horizontalNew = (Math.round(horizontalNew / Math.PI - 0.5) + 0.5) * Math.PI - 0.001;
}
var horizontalNew = this.startArmRotation.horizontal + diffX / 200;
var verticalNew = this.startArmRotation.vertical + diffY / 200;
var snapAngle = 4; // degrees
var snapValue = Math.sin(snapAngle / 360 * 2 * Math.PI);
// snap horizontally to nice angles at 0pi, 0.5pi, 1pi, 1.5pi, etc...
// the -0.001 is to take care that the vertical axis is always drawn at the left front corner
if (Math.abs(Math.sin(horizontalNew)) < snapValue) {
horizontalNew = Math.round((horizontalNew / Math.PI)) * Math.PI - 0.001;
}
if (Math.abs(Math.cos(horizontalNew)) < snapValue) {
horizontalNew = (Math.round((horizontalNew/ Math.PI - 0.5)) + 0.5) * Math.PI - 0.001;
}
// snap vertically to nice angles
if (Math.abs(Math.sin(verticalNew)) < snapValue) {
verticalNew = Math.round((verticalNew / Math.PI)) * Math.PI;
}
if (Math.abs(Math.cos(verticalNew)) < snapValue) {
verticalNew = (Math.round((verticalNew/ Math.PI - 0.5)) + 0.5) * Math.PI;
// snap vertically to nice angles
if (Math.abs(Math.sin(verticalNew)) < snapValue) {
verticalNew = Math.round(verticalNew / Math.PI) * Math.PI;
}
if (Math.abs(Math.cos(verticalNew)) < snapValue) {
verticalNew = (Math.round(verticalNew / Math.PI - 0.5) + 0.5) * Math.PI;
}
this.camera.setArmRotation(horizontalNew, verticalNew);
} }
this.camera.setArmRotation(horizontalNew, verticalNew);
this.redraw(); this.redraw();
// fire a cameraPositionChange event // fire a cameraPositionChange event

Loading…
Cancel
Save