canvas-camera-2d
Advanced tools
Comparing version 0.1.0 to 0.4.0
@@ -0,3 +1,17 @@ | ||
**v0.4.0** | ||
- Add rotation by ALT + mouse dragging | ||
- Remove zoom by ALT + mouse dragging | ||
**v0.3.0** | ||
- **[Breaking change]** the camera must now be configured using `camera.config({ ... })`. | ||
- Change to prettier code style. | ||
**v0.2.0** | ||
- Allow fixing the camera position when `camera.isFixed === true`. | ||
**v0.1.0** | ||
- First working version with pan and zoom. Note that rotation doesn't work yet. |
@@ -18,28 +18,22 @@ (function (global, factory) { | ||
if ( ref === void 0 ) ref = {}; | ||
var initDistance = ref.distance; if ( initDistance === void 0 ) initDistance = 1.0; | ||
var initPan = ref.pan; if ( initPan === void 0 ) initPan = true; | ||
var initPanSpeed = ref.panSpeed; if ( initPanSpeed === void 0 ) initPanSpeed = 1; | ||
var initRotate = ref.rotate; if ( initRotate === void 0 ) initRotate = true; | ||
var initRotateSpeed = ref.rotateSpeed; if ( initRotateSpeed === void 0 ) initRotateSpeed = 1; | ||
var initTarget = ref.target; if ( initTarget === void 0 ) initTarget = []; | ||
var initZoom = ref.zoom; if ( initZoom === void 0 ) initZoom = true; | ||
var initZoomSpeed = ref.zoomSpeed; if ( initZoomSpeed === void 0 ) initZoomSpeed = 1; | ||
var distance = ref.distance; if ( distance === void 0 ) distance = 1.0; | ||
var target = ref.target; if ( target === void 0 ) target = []; | ||
var isFixed = ref.isFixed; if ( isFixed === void 0 ) isFixed = false; | ||
var isPan = ref.isPan; if ( isPan === void 0 ) isPan = true; | ||
var panSpeed = ref.panSpeed; if ( panSpeed === void 0 ) panSpeed = 1; | ||
var isRotate = ref.isRotate; if ( isRotate === void 0 ) isRotate = true; | ||
var rotateSpeed = ref.rotateSpeed; if ( rotateSpeed === void 0 ) rotateSpeed = 1; | ||
var isZoom = ref.isZoom; if ( isZoom === void 0 ) isZoom = true; | ||
var zoomSpeed = ref.zoomSpeed; if ( zoomSpeed === void 0 ) zoomSpeed = 1; | ||
var pan = initPan; | ||
var panSpeed = initPanSpeed; | ||
var rotate = initRotate; | ||
var rotateSpeed = initRotateSpeed; | ||
var zoom = initZoom; | ||
var zoomSpeed = initZoomSpeed; | ||
var camera = createCamera({ initTarget: initTarget, initDistance: initDistance }); | ||
var camera = createCamera({ target: target, distance: distance }); | ||
var isChanged = false; | ||
var mousePosition = createMousePosition(canvas); | ||
var mousePressed = createMousePressed(canvas); | ||
var scroll = createScroll(canvas, zoom); | ||
var scroll = createScroll(canvas, isZoom); | ||
var getGlPos = function (x, y, w, h) { | ||
// Get relative WebGL position | ||
var relX = -1 + (x / w * 2); | ||
var relY = 1 + (y / h * -2); | ||
var relX = -1 + (x / w) * 2; | ||
var relY = 1 + (y / h) * -2; | ||
// Homogeneous vector | ||
@@ -53,3 +47,5 @@ var v = [relX, relY, 1]; | ||
var tick = function () { | ||
var alt = createKeyPressed('<alt>'); | ||
if (isFixed) { return undefined; } | ||
var alt = createKeyPressed("<alt>"); | ||
var height = canvas.height / window.devicePixelRatio; | ||
@@ -59,19 +55,20 @@ var width = canvas.width / window.devicePixelRatio; | ||
if (pan && mousePressed.left && !alt) { | ||
if (isPan && mousePressed.left && !alt) { | ||
// To pan 1:1 we need to half the width and height because the uniform | ||
// coordinate system goes from -1 to 1. | ||
camera.pan([ | ||
panSpeed * (mousePosition[0] - mousePosition.prev[0]) / width * 2, | ||
panSpeed * (mousePosition[1] - mousePosition.prev[1]) / height * 2 ]); | ||
((panSpeed * (mousePosition[0] - mousePosition.prev[0])) / width) * 2, | ||
((panSpeed * (mousePosition[1] - mousePosition.prev[1])) / height) * 2 | ||
]); | ||
isChanged = true; | ||
} | ||
if (zoom && scroll[1]) { | ||
if (isZoom && scroll[1]) { | ||
// Target == viewport center | ||
var target = camera.target; | ||
var oldDist = camera.distance; | ||
var newDist = zoomSpeed * camera.distance * Math.exp(scroll[1] / height); | ||
var dZ = zoomSpeed * Math.exp(scroll[1] / height); | ||
var newDist = oldDist * dZ; | ||
var dDist = newDist / oldDist; | ||
var recipDDist = 1 - dDist; | ||
var recipDDist = 1 - newDist / oldDist; | ||
@@ -92,8 +89,4 @@ // Get the relative WebGL coordinates of the mouse | ||
camera.lookAt( | ||
[ | ||
target[0] - dX * recipDDist, | ||
target[1] - dY * recipDDist ], | ||
newDist | ||
); | ||
camera.pan([dX * recipDDist, -dY * recipDDist]); | ||
camera.zoom(dZ); | ||
@@ -103,7 +96,17 @@ isChanged = true; | ||
if (zoom && (mousePressed.middle || (mousePressed.left && alt))) { | ||
var d = mousePosition[1] - mousePosition.prev[1]; | ||
if (!d) { return undefined; } | ||
if (isRotate && (mousePressed.left && alt)) { | ||
var wh = width / 2; | ||
var hh = height / 2; | ||
var x1 = mousePosition.prev[0] - wh; | ||
var y1 = hh - mousePosition.prev[1]; | ||
var x2 = mousePosition[0] - wh; | ||
var y2 = hh - mousePosition[1]; | ||
// Angle between the start and end mouse position with respect to the | ||
// viewport center | ||
var radians = glMatrix.vec2.angle([x1, y1], [x2, y2]); | ||
// Determine the orientation | ||
var cross = x1 * y2 - x2 * y1; | ||
camera.distance *= zoomSpeed * Math.exp(d / height); | ||
camera.rotate(rotateSpeed * radians * Math.sign(cross)); | ||
isChanged = true; | ||
@@ -128,31 +131,40 @@ } | ||
var config = function (ref) { | ||
if ( ref === void 0 ) ref = {}; | ||
var newIsFixed = ref.isFixed; | ||
var newIsPan = ref.isPan; | ||
var newPanSpeed = ref.panSpeed; | ||
var newIsRotate = ref.isRotate; | ||
var newRotateSpeed = ref.rotateSpeed; | ||
var newIsZoom = ref.isZoom; | ||
var newZoomSpeed = ref.zoomSpeed; | ||
if (typeof newIsFixed !== "undefined") { | ||
isFixed = newIsFixed; | ||
} | ||
if (typeof newIsPan !== "undefined") { | ||
isPan = newIsFixed; | ||
} | ||
if (typeof newPanSpeed !== "undefined" && +newPanSpeed > 0) { | ||
panSpeed = newPanSpeed; | ||
} | ||
if (typeof newIsRotate !== "undefined") { | ||
isRotate = newIsRotate; | ||
} | ||
if (typeof newRotateSpeed !== "undefined" && +newRotateSpeed > 0) { | ||
rotateSpeed = newRotateSpeed; | ||
} | ||
if (typeof newIsZoom !== "undefined") { | ||
isZoom = newIsZoom; | ||
} | ||
if (typeof newZoomSpeed !== "undefined" && +newZoomSpeed > 0) { | ||
zoomSpeed = newZoomSpeed; | ||
} | ||
}; | ||
camera.config = config; | ||
camera.dispose = dispose; | ||
camera.getGlPos = getGlPos; | ||
camera.tick = tick; | ||
camera.getGlPos = getGlPos; | ||
camera.dispose = dispose; | ||
Object.defineProperty(camera, 'isPan', { | ||
get: function () { return pan; }, | ||
set: function (newPan) { pan = !!newPan; }, | ||
}); | ||
Object.defineProperty(camera, 'panSpeed', { | ||
get: function () { return panSpeed; }, | ||
set: function (newPanSpeed) { panSpeed = +newPanSpeed > 0 ? +newPanSpeed : panSpeed; }, | ||
}); | ||
Object.defineProperty(camera, 'isRotate', { | ||
get: function () { return rotate; }, | ||
set: function (newRotate) { rotate = !!newRotate; }, | ||
}); | ||
Object.defineProperty(camera, 'rotateSpeed', { | ||
get: function () { return rotateSpeed; }, | ||
set: function (newRotateSpeed) { rotateSpeed = +newRotateSpeed > 0 ? +newRotateSpeed : rotateSpeed; }, | ||
}); | ||
Object.defineProperty(camera, 'isZoom', { | ||
get: function () { return zoom; }, | ||
set: function (newZoom) { zoom = !!newZoom; }, | ||
}); | ||
Object.defineProperty(camera, 'zoomSpeed', { | ||
get: function () { return zoomSpeed; }, | ||
set: function (newZoomSpeed) { zoomSpeed = +newZoomSpeed > 0 ? +newZoomSpeed : zoomSpeed; }, | ||
}); | ||
return camera; | ||
@@ -159,0 +171,0 @@ }; |
@@ -1,1 +0,1 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("camera-2d-simple"),require("gl-matrix"),require("key-pressed"),require("mouse-position"),require("mouse-pressed"),require("scroll-speed")):"function"==typeof define&&define.amd?define(["camera-2d-simple","gl-matrix","key-pressed","mouse-position","mouse-pressed","scroll-speed"],t):e.canvasCamera2d=t(e.createCamera2d,e.glMatrix,e.createKeyPressed,e.createMousePosition,e.createMousePressed,e.createScroll)}(this,function(e,t,r,i,o,n){"use strict";e=e&&e.hasOwnProperty("default")?e.default:e,r=r&&r.hasOwnProperty("default")?r.default:r,i=i&&i.hasOwnProperty("default")?i.default:i,o=o&&o.hasOwnProperty("default")?o.default:o,n=n&&n.hasOwnProperty("default")?n.default:n;return function(a,d){void 0===d&&(d={});var s=d.distance;void 0===s&&(s=1);var u=d.pan;void 0===u&&(u=!0);var f=d.panSpeed;void 0===f&&(f=1);var c=d.rotate;void 0===c&&(c=!0);var p=d.rotateSpeed;void 0===p&&(p=1);var l=d.target;void 0===l&&(l=[]);var v=d.zoom;void 0===v&&(v=!0);var m=d.zoomSpeed;void 0===m&&(m=1);var P=u,y=f,g=c,h=p,O=v,w=m,x=e({initTarget:l,initDistance:s}),b=!1,j=i(a),S=o(a),q=n(a,O),M=function(e,r,i,o){var n=[e/i*2-1,1+r/o*-2,1];return t.vec3.transformMat3(n,n,x.transformation),n.slice(0,2)};return x.tick=function(){var e=r("<alt>"),t=a.height/window.devicePixelRatio,i=a.width/window.devicePixelRatio;if(b=!1,P&&S.left&&!e&&(x.pan([y*(j[0]-j.prev[0])/i*2,y*(j[1]-j.prev[1])/t*2]),b=!0),O&&q[1]){var o=x.target,n=x.distance,d=w*x.distance*Math.exp(q[1]/t),s=1-d/n,u=M(j[0],j[1],i,t),f=u[0],c=u[1],p=o[0]-f,l=o[1]-c;x.lookAt([o[0]-p*s,o[1]-l*s],d),b=!0}if(O&&(S.middle||S.left&&e)){var v=j[1]-j.prev[1];if(!v)return;x.distance*=w*Math.exp(v/t),b=!0}return q.flush(),j.flush(),b},x.getGlPos=M,x.dispose=function(){q.dispose(),S.dispose(),j.dispose(),x=void 0,q=void 0,S=void 0,j=void 0},Object.defineProperty(x,"isPan",{get:function(){return P},set:function(e){P=!!e}}),Object.defineProperty(x,"panSpeed",{get:function(){return y},set:function(e){y=+e>0?+e:y}}),Object.defineProperty(x,"isRotate",{get:function(){return g},set:function(e){g=!!e}}),Object.defineProperty(x,"rotateSpeed",{get:function(){return h},set:function(e){h=+e>0?+e:h}}),Object.defineProperty(x,"isZoom",{get:function(){return O},set:function(e){O=!!e}}),Object.defineProperty(x,"zoomSpeed",{get:function(){return w},set:function(e){w=+e>0?+e:w}}),x}}); | ||
!function(e,i){"object"==typeof exports&&"undefined"!=typeof module?module.exports=i(require("camera-2d-simple"),require("gl-matrix"),require("key-pressed"),require("mouse-position"),require("mouse-pressed"),require("scroll-speed")):"function"==typeof define&&define.amd?define(["camera-2d-simple","gl-matrix","key-pressed","mouse-position","mouse-pressed","scroll-speed"],i):e.canvasCamera2d=i(e.createCamera2d,e.glMatrix,e.createKeyPressed,e.createMousePosition,e.createMousePressed,e.createScroll)}(this,function(e,i,o,r,t,a){"use strict";e=e&&e.hasOwnProperty("default")?e.default:e,o=o&&o.hasOwnProperty("default")?o.default:o,r=r&&r.hasOwnProperty("default")?r.default:r,t=t&&t.hasOwnProperty("default")?t.default:t,a=a&&a.hasOwnProperty("default")?a.default:a;return function(d,s){void 0===s&&(s={});var n=s.distance;void 0===n&&(n=1);var v=s.target;void 0===v&&(v=[]);var u=s.isFixed;void 0===u&&(u=!1);var p=s.isPan;void 0===p&&(p=!0);var f=s.panSpeed;void 0===f&&(f=1);var l=s.isRotate;void 0===l&&(l=!0);var c=s.rotateSpeed;void 0===c&&(c=1);var m=s.isZoom;void 0===m&&(m=!0);var h=s.zoomSpeed;void 0===h&&(h=1);var P=e({target:v,distance:n}),g=!1,y=r(d),w=t(d),x=a(d,m),S=function(e,o,r,t){var a=[e/r*2-1,1+o/t*-2,1];return i.vec3.transformMat3(a,a,P.transformation),a.slice(0,2)};return P.config=function(e){void 0===e&&(e={});var i=e.isFixed,o=e.isPan,r=e.panSpeed,t=e.isRotate,a=e.rotateSpeed,d=e.isZoom,s=e.zoomSpeed;void 0!==i&&(u=i),void 0!==o&&(p=i),void 0!==r&&+r>0&&(f=r),void 0!==t&&(l=t),void 0!==a&&+a>0&&(c=a),void 0!==d&&(m=d),void 0!==s&&+s>0&&(h=s)},P.dispose=function(){x.dispose(),w.dispose(),y.dispose(),P=void 0,x=void 0,w=void 0,y=void 0},P.getGlPos=S,P.tick=function(){if(!u){var e=o("<alt>"),r=d.height/window.devicePixelRatio,t=d.width/window.devicePixelRatio;if(g=!1,p&&w.left&&!e&&(P.pan([f*(y[0]-y.prev[0])/t*2,f*(y[1]-y.prev[1])/r*2]),g=!0),m&&x[1]){var a=P.target,s=P.distance,n=h*Math.exp(x[1]/r),v=1-s*n/s,q=S(y[0],y[1],t,r),M=q[0],O=q[1],R=a[0]-M,k=a[1]-O;P.pan([R*v,-k*v]),P.zoom(n),g=!0}if(l&&w.left&&e){var z=t/2,C=r/2,F=y.prev[0]-z,Z=C-y.prev[1],b=y[0]-z,j=C-y[1],G=i.vec2.angle([F,Z],[b,j]),K=F*j-b*Z;P.rotate(c*G*Math.sign(K)),g=!0}return x.flush(),y.flush(),g}},P}}); |
{ | ||
"name": "canvas-camera-2d", | ||
"version": "0.1.0", | ||
"version": "0.4.0", | ||
"description": "A canvas wrapper for a 2D camera", | ||
@@ -15,2 +15,4 @@ "author": "Fritz Lekschas", | ||
"module": "src/index.js", | ||
"unpkg": "dist/canvas-camera-2d.min.js", | ||
"jsdelivr": "dist/canvas-camera-2d.min.js", | ||
"files": [ | ||
@@ -23,3 +25,4 @@ "src/index.js", | ||
"build": "rollup -c", | ||
"lint": "eslint src/index.js rollup.config.js", | ||
"lint": "eslint src rollup.config.js", | ||
"precommit": "pretty-quick --staged", | ||
"prepublishOnly": "npm run lint", | ||
@@ -31,3 +34,3 @@ "prerelease": "rm -rf dist/*; npm run build; zip -r dist.zip dist", | ||
"dependencies": { | ||
"camera-2d-simple": "^1.0.0", | ||
"camera-2d-simple": "^1.2.0", | ||
"gl-matrix": "^2.8.1", | ||
@@ -40,3 +43,3 @@ "key-pressed": "flekschas/key-pressed", | ||
"peerDependencies": { | ||
"camera-2d-simple": "^1.0.0", | ||
"camera-2d-simple": "^1.2.0", | ||
"key-pressed": "flekschas/key-pressed", | ||
@@ -48,10 +51,10 @@ "mouse-position": "^2.1.0", | ||
"devDependencies": { | ||
"eslint": "^5.4.0", | ||
"eslint-config-airbnb": "^17.1.0", | ||
"eslint-plugin-import": "^2.14.0", | ||
"eslint-plugin-jsx-a11y": "^6.1.1", | ||
"eslint-plugin-react": "^7.11.1", | ||
"rollup": "^0.64.1", | ||
"rollup-plugin-buble": "^0.19.2", | ||
"rollup-plugin-terser": "^1.0.1" | ||
"eslint": "^5.7.0", | ||
"eslint-config-prettier": "^v3.1.0", | ||
"husky": "^1.1.2", | ||
"prettier": "1.14.3", | ||
"pretty-quick": "^1.8.0", | ||
"rollup": "^0.66.6", | ||
"rollup-plugin-buble": "^0.19.4", | ||
"rollup-plugin-terser": "^3.0.0" | ||
}, | ||
@@ -58,0 +61,0 @@ "homepage": "https://github.com/flekschas/canvas-camera-2d", |
# Canvas Warpper for 2D Camera | ||
[](https://www.npmjs.com/package/canvas-camera-2d) | ||
[](https://nodejs.org/api/documentation.html#documentation_stability_index) | ||
[](https://travis-ci.org/flekschas/canvas-camera-2d) | ||
[](https://unpkg.com/canvas-camera-2d) | ||
[](https://github.com/prettier/prettier) | ||
[](https://flekschas.github.io/regl-scatterplot/) | ||
> A wrapper for [camera-2d](https://github.com/flekschas/camera-2d) that supports pan, zoom, and rotate. | ||
@@ -7,13 +14,16 @@ | ||
* Pan - Left click and hold + mouse move | ||
* Zoom - Scroll or Alt + Left click and hold with vertical mouse move | ||
* Rotate - Right click or Control + Left click | ||
- Pan - Left click and hold + mouse move | ||
- Zoom - Scroll or Alt + Left click and hold with vertical mouse move | ||
- Rotate - Right click or Control + Left click | ||
Based heavily on | ||
[orbit-camera](http://github.com/mikolalysenko/orbit-camera). | ||
Based heavily on [orbit-camera](http://github.com/mikolalysenko/orbit-camera). | ||
Also see: | ||
- [regl-scatterplot](https://github.com/flekschas/regl-scatterplot) for an application and a [demo](https://flekschas.github.io/regl-scatterplot/). | ||
## API | ||
```javascript | ||
import canvasCamera2d from 'canvas-camera-2d'; | ||
import canvasCamera2d from "canvas-camera-2d"; | ||
``` | ||
@@ -27,10 +37,12 @@ | ||
* `distance`: initial distance of the camera. Defaults to `1.0`. | ||
* `target`: x, y position the camera is looking in GL coordinates. Defaults to`[0, 0]`. | ||
* `pan`: if `true` panning is enabled. Defaults to `true`. | ||
* `panSpeed`: initial panning speed. Defaults to `1`. | ||
* `pan`: if `true` panning is enabled. Defaults to `true`. | ||
* `panSpeed`: initial panning speed. Defaults to `1`. | ||
* `zoom`: if `true` zooming is enabled. Defaults to `true`. | ||
* `zoomSpeed`: initial zooming speed. Defaults to `1`. | ||
- `distance`: initial distance of the camera. [dtype: float, default: `1.0`] | ||
- `target`: x, y position the camera is looking in GL coordinates. [dtype: array of floats, default: `[0.0, 0.0]`] | ||
- `rotation`: rotation in radians around the z axis. [dtype: float, default: `0.0`] | ||
- `isFixed`: if `true` panning, rotating, and zooming is disabled. [dtype: bool, default: `false`] | ||
- `isPan`: if `true` panning is enabled. [dtype: bool, default: `true`] | ||
- `panSpeed`: initial panning speed. [dtype: float, default: `1.0`] | ||
- `isRotate`: if `true` rotation is enabled. [dtype: bool, default: `true`] | ||
- `rotateSpeed`: initial panning speed. [dtype: float, default: `1.0`] | ||
- `isZoom`: if `true` zooming is enabled. [dtype: bool, default: `true`] | ||
- `zoomSpeed`: initial zooming speed. [dtype: float, default: `1.0`] | ||
@@ -49,6 +61,6 @@ **Returns** a new 2d camera object. | ||
* `x`: relative x position in pixel coordinates. | ||
* `y`: relative y position in pixel coordinates. | ||
* `w`: width of the canvas object. | ||
* `h`: height of the canvas object. | ||
- `x`: relative x position in pixel coordinates. | ||
- `y`: relative y position in pixel coordinates. | ||
- `w`: width of the canvas object. | ||
- `h`: height of the canvas object. | ||
@@ -61,24 +73,12 @@ **Returns** `[relX, relY]` the WebGL position of `x` and `y`. | ||
### camera.isPan | ||
### camera.config(options) | ||
Get and set panning. | ||
Configure the canvas camera. `options` accepts the following options: | ||
### camera.panSpeed | ||
Get and set pan speed. | ||
### camera.isRotate | ||
Get and set rotation. | ||
### camera.rotateSpeed | ||
Get and set rotation speed. | ||
### camera.isZoom | ||
Get and set zooming. | ||
### camera.zoomSpeed | ||
Get and set zoom speed. | ||
- `isFixed`: if `true` panning, rotating, and zooming is disabled. [default: `false`] | ||
- `isPan`: if `true` panning is enabled. [dtype: bool, default: `true`] | ||
- `panSpeed`: panning speed. [dtype: float, default: `1.0`] | ||
- `isRotate`: if `true` rotation is enabled. [dtype: bool, default: `true`] | ||
- `rotateSpeed`: rotation speed. [dtype: float, default: `1.0`] | ||
- `isZoom`: if `true` zooming is enabled. [dtype: bool, default: `true`] | ||
- `zoomSpeed`: zooming speed. [dtype: float, default: `1.0`] |
155
src/index.js
@@ -1,7 +0,7 @@ | ||
import createCamera from 'camera-2d-simple'; | ||
import { vec3 } from 'gl-matrix'; | ||
import createKeyPressed from 'key-pressed'; | ||
import createMousePosition from 'mouse-position'; | ||
import createMousePressed from 'mouse-pressed'; | ||
import createScroll from 'scroll-speed'; | ||
import createCamera from "camera-2d-simple"; | ||
import { vec2, vec3 } from "gl-matrix"; | ||
import createKeyPressed from "key-pressed"; | ||
import createMousePosition from "mouse-position"; | ||
import createMousePressed from "mouse-pressed"; | ||
import createScroll from "scroll-speed"; | ||
@@ -11,29 +11,23 @@ const canvas2dCamera = ( | ||
{ | ||
distance: initDistance = 1.0, | ||
pan: initPan = true, | ||
panSpeed: initPanSpeed = 1, | ||
rotate: initRotate = true, | ||
rotateSpeed: initRotateSpeed = 1, | ||
target: initTarget = [], | ||
zoom: initZoom = true, | ||
zoomSpeed: initZoomSpeed = 1, | ||
} = {}, | ||
distance = 1.0, | ||
target = [], | ||
isFixed = false, | ||
isPan = true, | ||
panSpeed = 1, | ||
isRotate = true, | ||
rotateSpeed = 1, | ||
isZoom = true, | ||
zoomSpeed = 1 | ||
} = {} | ||
) => { | ||
let pan = initPan; | ||
let panSpeed = initPanSpeed; | ||
let rotate = initRotate; | ||
let rotateSpeed = initRotateSpeed; | ||
let zoom = initZoom; | ||
let zoomSpeed = initZoomSpeed; | ||
let camera = createCamera({ initTarget, initDistance }); | ||
let camera = createCamera({ target, distance }); | ||
let isChanged = false; | ||
let mousePosition = createMousePosition(canvas); | ||
let mousePressed = createMousePressed(canvas); | ||
let scroll = createScroll(canvas, zoom); | ||
let scroll = createScroll(canvas, isZoom); | ||
const getGlPos = (x, y, w, h) => { | ||
// Get relative WebGL position | ||
const relX = -1 + (x / w * 2); | ||
const relY = 1 + (y / h * -2); | ||
const relX = -1 + (x / w) * 2; | ||
const relY = 1 + (y / h) * -2; | ||
// Homogeneous vector | ||
@@ -47,3 +41,5 @@ const v = [relX, relY, 1]; | ||
const tick = () => { | ||
const alt = createKeyPressed('<alt>'); | ||
if (isFixed) return undefined; | ||
const alt = createKeyPressed("<alt>"); | ||
const height = canvas.height / window.devicePixelRatio; | ||
@@ -53,8 +49,8 @@ const width = canvas.width / window.devicePixelRatio; | ||
if (pan && mousePressed.left && !alt) { | ||
if (isPan && mousePressed.left && !alt) { | ||
// To pan 1:1 we need to half the width and height because the uniform | ||
// coordinate system goes from -1 to 1. | ||
camera.pan([ | ||
panSpeed * (mousePosition[0] - mousePosition.prev[0]) / width * 2, | ||
panSpeed * (mousePosition[1] - mousePosition.prev[1]) / height * 2, | ||
((panSpeed * (mousePosition[0] - mousePosition.prev[0])) / width) * 2, | ||
((panSpeed * (mousePosition[1] - mousePosition.prev[1])) / height) * 2 | ||
]); | ||
@@ -64,9 +60,9 @@ isChanged = true; | ||
if (zoom && scroll[1]) { | ||
if (isZoom && scroll[1]) { | ||
// Target == viewport center | ||
const { target, distance: oldDist } = camera; | ||
const newDist = zoomSpeed * camera.distance * Math.exp(scroll[1] / height); | ||
const dZ = zoomSpeed * Math.exp(scroll[1] / height); | ||
const newDist = oldDist * dZ; | ||
const dDist = newDist / oldDist; | ||
const recipDDist = 1 - dDist; | ||
const recipDDist = 1 - newDist / oldDist; | ||
@@ -78,3 +74,3 @@ // Get the relative WebGL coordinates of the mouse | ||
width, | ||
height, | ||
height | ||
); | ||
@@ -86,9 +82,4 @@ | ||
camera.lookAt( | ||
[ | ||
target[0] - dX * recipDDist, | ||
target[1] - dY * recipDDist, | ||
], | ||
newDist, | ||
); | ||
camera.pan([dX * recipDDist, -dY * recipDDist]); | ||
camera.zoom(dZ); | ||
@@ -98,7 +89,17 @@ isChanged = true; | ||
if (zoom && (mousePressed.middle || (mousePressed.left && alt))) { | ||
const d = mousePosition[1] - mousePosition.prev[1]; | ||
if (!d) return undefined; | ||
if (isRotate && (mousePressed.left && alt)) { | ||
const wh = width / 2; | ||
const hh = height / 2; | ||
const x1 = mousePosition.prev[0] - wh; | ||
const y1 = hh - mousePosition.prev[1]; | ||
const x2 = mousePosition[0] - wh; | ||
const y2 = hh - mousePosition[1]; | ||
// Angle between the start and end mouse position with respect to the | ||
// viewport center | ||
const radians = vec2.angle([x1, y1], [x2, y2]); | ||
// Determine the orientation | ||
const cross = x1 * y2 - x2 * y1; | ||
camera.distance *= zoomSpeed * Math.exp(d / height); | ||
camera.rotate(rotateSpeed * radians * Math.sign(cross)); | ||
isChanged = true; | ||
@@ -123,31 +124,39 @@ } | ||
const config = ({ | ||
isFixed: newIsFixed, | ||
isPan: newIsPan, | ||
panSpeed: newPanSpeed, | ||
isRotate: newIsRotate, | ||
rotateSpeed: newRotateSpeed, | ||
isZoom: newIsZoom, | ||
zoomSpeed: newZoomSpeed | ||
} = {}) => { | ||
if (typeof newIsFixed !== "undefined") { | ||
isFixed = newIsFixed; | ||
} | ||
if (typeof newIsPan !== "undefined") { | ||
isPan = newIsFixed; | ||
} | ||
if (typeof newPanSpeed !== "undefined" && +newPanSpeed > 0) { | ||
panSpeed = newPanSpeed; | ||
} | ||
if (typeof newIsRotate !== "undefined") { | ||
isRotate = newIsRotate; | ||
} | ||
if (typeof newRotateSpeed !== "undefined" && +newRotateSpeed > 0) { | ||
rotateSpeed = newRotateSpeed; | ||
} | ||
if (typeof newIsZoom !== "undefined") { | ||
isZoom = newIsZoom; | ||
} | ||
if (typeof newZoomSpeed !== "undefined" && +newZoomSpeed > 0) { | ||
zoomSpeed = newZoomSpeed; | ||
} | ||
}; | ||
camera.config = config; | ||
camera.dispose = dispose; | ||
camera.getGlPos = getGlPos; | ||
camera.tick = tick; | ||
camera.getGlPos = getGlPos; | ||
camera.dispose = dispose; | ||
Object.defineProperty(camera, 'isPan', { | ||
get: () => pan, | ||
set: (newPan) => { pan = !!newPan; }, | ||
}); | ||
Object.defineProperty(camera, 'panSpeed', { | ||
get: () => panSpeed, | ||
set: (newPanSpeed) => { panSpeed = +newPanSpeed > 0 ? +newPanSpeed : panSpeed; }, | ||
}); | ||
Object.defineProperty(camera, 'isRotate', { | ||
get: () => rotate, | ||
set: (newRotate) => { rotate = !!newRotate; }, | ||
}); | ||
Object.defineProperty(camera, 'rotateSpeed', { | ||
get: () => rotateSpeed, | ||
set: (newRotateSpeed) => { rotateSpeed = +newRotateSpeed > 0 ? +newRotateSpeed : rotateSpeed; }, | ||
}); | ||
Object.defineProperty(camera, 'isZoom', { | ||
get: () => zoom, | ||
set: (newZoom) => { zoom = !!newZoom; }, | ||
}); | ||
Object.defineProperty(camera, 'zoomSpeed', { | ||
get: () => zoomSpeed, | ||
set: (newZoomSpeed) => { zoomSpeed = +newZoomSpeed > 0 ? +newZoomSpeed : zoomSpeed; }, | ||
}); | ||
return camera; | ||
@@ -154,0 +163,0 @@ }; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
19744
289
3
Updatedcamera-2d-simple@^1.2.0