canvas-camera-2d
Advanced tools
Comparing version 0.4.0 to 0.5.0
@@ -0,1 +1,6 @@ | ||
**v0.5.0** | ||
- Update camera-2d-simple to `v2` and adjust code | ||
- Allow setting the rotation on create | ||
**v0.4.0** | ||
@@ -2,0 +7,0 @@ |
@@ -5,6 +5,6 @@ (function (global, factory) { | ||
(global.canvasCamera2d = factory(global.createCamera2d,global.glMatrix,global.createKeyPressed,global.createMousePosition,global.createMousePressed,global.createScroll)); | ||
}(this, (function (createCamera,glMatrix,createKeyPressed,createMousePosition,createMousePressed,createScroll) { 'use strict'; | ||
}(this, (function (createCamera,glMatrix,isKeyPressed,createMousePosition,createMousePressed,createScroll) { 'use strict'; | ||
createCamera = createCamera && createCamera.hasOwnProperty('default') ? createCamera['default'] : createCamera; | ||
createKeyPressed = createKeyPressed && createKeyPressed.hasOwnProperty('default') ? createKeyPressed['default'] : createKeyPressed; | ||
isKeyPressed = isKeyPressed && isKeyPressed.hasOwnProperty('default') ? isKeyPressed['default'] : isKeyPressed; | ||
createMousePosition = createMousePosition && createMousePosition.hasOwnProperty('default') ? createMousePosition['default'] : createMousePosition; | ||
@@ -20,3 +20,4 @@ createMousePressed = createMousePressed && createMousePressed.hasOwnProperty('default') ? createMousePressed['default'] : createMousePressed; | ||
var distance = ref.distance; if ( distance === void 0 ) distance = 1.0; | ||
var target = ref.target; if ( target === void 0 ) target = []; | ||
var target = ref.target; if ( target === void 0 ) target = [0, 0]; | ||
var rotation = ref.rotation; if ( rotation === void 0 ) rotation = 0; | ||
var isFixed = ref.isFixed; if ( isFixed === void 0 ) isFixed = false; | ||
@@ -30,3 +31,5 @@ var isPan = ref.isPan; if ( isPan === void 0 ) isPan = true; | ||
var camera = createCamera({ target: target, distance: distance }); | ||
var scratch = new Float32Array(16); | ||
var camera = createCamera(target, distance, rotation); | ||
var isChanged = false; | ||
@@ -37,2 +40,7 @@ var mousePosition = createMousePosition(canvas); | ||
var height = canvas.height / window.devicePixelRatio; | ||
var width = canvas.width / window.devicePixelRatio; | ||
var isAlt = false; | ||
var getGlPos = function (x, y, w, h) { | ||
@@ -43,5 +51,7 @@ // Get relative WebGL position | ||
// Homogeneous vector | ||
var v = [relX, relY, 1]; | ||
var v = [relX, relY, 1, 1]; | ||
// Compute inverse view matrix | ||
var viewInv = glMatrix.mat4.invert(scratch, camera.view); | ||
// Translate vector | ||
glMatrix.vec3.transformMat3(v, v, camera.transformation); | ||
glMatrix.vec4.transformMat4(v, v, viewInv); | ||
return v.slice(0, 2); | ||
@@ -51,10 +61,8 @@ }; | ||
var tick = function () { | ||
if (isFixed) { return undefined; } | ||
if (isFixed) { return false; } | ||
var alt = createKeyPressed("<alt>"); | ||
var height = canvas.height / window.devicePixelRatio; | ||
var width = canvas.width / window.devicePixelRatio; | ||
isAlt = isKeyPressed("<alt>"); | ||
isChanged = false; | ||
if (isPan && mousePressed.left && !alt) { | ||
if (isPan && mousePressed.left && !isAlt) { | ||
// To pan 1:1 we need to half the width and height because the uniform | ||
@@ -64,3 +72,3 @@ // coordinate system goes from -1 to 1. | ||
((panSpeed * (mousePosition[0] - mousePosition.prev[0])) / width) * 2, | ||
((panSpeed * (mousePosition[1] - mousePosition.prev[1])) / height) * 2 | ||
((panSpeed * (mousePosition.prev[1] - mousePosition[1])) / height) * 2 | ||
]); | ||
@@ -71,31 +79,14 @@ isChanged = true; | ||
if (isZoom && scroll[1]) { | ||
// Target == viewport center | ||
var target = camera.target; | ||
var oldDist = camera.distance; | ||
var dZ = zoomSpeed * Math.exp(scroll[1] / height); | ||
var newDist = oldDist * dZ; | ||
var recipDDist = 1 - newDist / oldDist; | ||
// Get normalized device coordinates (NDC) | ||
var xNdc = -1 + (mousePosition[0] / width) * 2; | ||
var yNdc = 1 + (mousePosition[1] / height) * -2; | ||
// Get the relative WebGL coordinates of the mouse | ||
var ref = getGlPos( | ||
mousePosition[0], | ||
mousePosition[1], | ||
width, | ||
height | ||
); | ||
var relX = ref[0]; | ||
var relY = ref[1]; | ||
camera.scale(1 / dZ, [xNdc, yNdc]); | ||
// X and Y distance between the center and the mouse | ||
var dX = target[0] - relX; | ||
var dY = target[1] - relY; | ||
camera.pan([dX * recipDDist, -dY * recipDDist]); | ||
camera.zoom(dZ); | ||
isChanged = true; | ||
} | ||
if (isRotate && (mousePressed.left && alt)) { | ||
if (isRotate && (mousePressed.left && isAlt)) { | ||
var wh = width / 2; | ||
@@ -138,34 +129,26 @@ var hh = height / 2; | ||
var newIsPan = ref.isPan; | ||
var newIsRotate = ref.isRotate; | ||
var newIsZoom = ref.isZoom; | ||
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; | ||
} | ||
isFixed = newIsFixed || isFixed; | ||
isPan = newIsPan || isPan; | ||
isRotate = newIsRotate || isRotate; | ||
isZoom = newIsZoom || isZoom; | ||
panSpeed = +newPanSpeed > 0 ? newPanSpeed : panSpeed; | ||
rotateSpeed = +newRotateSpeed > 0 ? newRotateSpeed : rotateSpeed; | ||
zoomSpeed = +newZoomSpeed > 0 ? newZoomSpeed : zoomSpeed; | ||
}; | ||
var refresh = function () { | ||
height = canvas.height / window.devicePixelRatio; | ||
width = canvas.width / window.devicePixelRatio; | ||
}; | ||
camera.config = config; | ||
camera.dispose = dispose; | ||
camera.getGlPos = getGlPos; | ||
camera.refresh = refresh; | ||
camera.tick = tick; | ||
@@ -172,0 +155,0 @@ |
@@ -1,1 +0,1 @@ | ||
!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}}); | ||
!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,r,o,t,a){"use strict";e=e&&e.hasOwnProperty("default")?e.default:e,r=r&&r.hasOwnProperty("default")?r.default:r,o=o&&o.hasOwnProperty("default")?o.default:o,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=[0,0]);var u=s.rotation;void 0===u&&(u=0);var p=s.isFixed;void 0===p&&(p=!1);var l=s.isPan;void 0===l&&(l=!0);var f=s.panSpeed;void 0===f&&(f=1);var c=s.isRotate;void 0===c&&(c=!0);var m=s.rotateSpeed;void 0===m&&(m=1);var h=s.isZoom;void 0===h&&(h=!0);var w=s.zoomSpeed;void 0===w&&(w=1);var P=new Float32Array(16),x=e(v,n,u),y=!1,g=o(d),S=t(d),q=a(d,h),M=d.height/window.devicePixelRatio,R=d.width/window.devicePixelRatio,O=!1;return x.config=function(e){void 0===e&&(e={});var i=e.isFixed,r=e.isPan,o=e.isRotate,t=e.isZoom,a=e.panSpeed,d=e.rotateSpeed,s=e.zoomSpeed;p=i||p,l=r||l,c=o||c,h=t||h,f=+a>0?a:f,m=+d>0?d:m,w=+s>0?s:w},x.dispose=function(){q.dispose(),S.dispose(),g.dispose(),x=void 0,q=void 0,S=void 0,g=void 0},x.getGlPos=function(e,r,o,t){var a=[e/o*2-1,1+r/t*-2,1,1],d=i.mat4.invert(P,x.view);return i.vec4.transformMat4(a,a,d),a.slice(0,2)},x.refresh=function(){M=d.height/window.devicePixelRatio,R=d.width/window.devicePixelRatio},x.tick=function(){if(p)return!1;if(O=r("<alt>"),y=!1,l&&S.left&&!O&&(x.pan([f*(g[0]-g.prev[0])/R*2,f*(g.prev[1]-g[1])/M*2]),y=!0),h&&q[1]){var e=w*Math.exp(q[1]/M),o=g[0]/R*2-1,t=1+g[1]/M*-2;x.scale(1/e,[o,t]),y=!0}if(c&&S.left&&O){var a=R/2,d=M/2,s=g.prev[0]-a,n=d-g.prev[1],v=g[0]-a,u=d-g[1],P=i.vec2.angle([s,n],[v,u]),k=s*u-v*n;x.rotate(m*P*Math.sign(k)),y=!0}return q.flush(),g.flush(),y},x}}); |
{ | ||
"name": "canvas-camera-2d", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"description": "A canvas wrapper for a 2D camera", | ||
@@ -32,3 +32,3 @@ "author": "Fritz Lekschas", | ||
"dependencies": { | ||
"camera-2d-simple": "^1.2.0", | ||
"camera-2d-simple": "^2.0.0-rc1", | ||
"gl-matrix": "^2.8.1", | ||
@@ -41,3 +41,3 @@ "key-pressed": "flekschas/key-pressed", | ||
"peerDependencies": { | ||
"camera-2d-simple": "^1.2.0", | ||
"camera-2d-simple": "^2.0.0-rc1", | ||
"key-pressed": "flekschas/key-pressed", | ||
@@ -44,0 +44,0 @@ "mouse-position": "^2.1.0", |
@@ -18,3 +18,3 @@ # Canvas Warpper for 2D Camera | ||
Based heavily on [orbit-camera](http://github.com/mikolalysenko/orbit-camera). | ||
Based on [orbit-camera](http://github.com/mikolalysenko/orbit-camera). | ||
@@ -25,2 +25,8 @@ Also see: | ||
## Install | ||
``` | ||
npm -i canvas-camera-2d | ||
``` | ||
## API | ||
@@ -38,23 +44,29 @@ | ||
- `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`] | ||
- `distance`: initial distance of the camera. [dtype: number, default: `1`] | ||
- `target`: x, y position the camera is looking in GL coordinates. [dtype: array of numbers, default: `[0,0]`] | ||
- `rotation`: rotation in radians around the z axis. [dtype: number, default: `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`] | ||
- `panSpeed`: initial panning speed. [dtype: number, default: `1`] | ||
- `isRotate`: if `true` rotation is enabled. [dtype: bool, default: `true`] | ||
- `rotateSpeed`: initial panning speed. [dtype: float, default: `1.0`] | ||
- `rotateSpeed`: initial panning speed. [dtype: number, default: `1`] | ||
- `isZoom`: if `true` zooming is enabled. [dtype: bool, default: `true`] | ||
- `zoomSpeed`: initial zooming speed. [dtype: float, default: `1.0`] | ||
- `zoomSpeed`: initial zooming speed. [dtype: number, default: `1`] | ||
**Returns** a new 2d camera object. | ||
**Returns** a new 2D camera object. | ||
The [camera's API](https://github.com/flekschas/camera-2d#api) is augmented with the following additional endpoints: | ||
### camera.tick() | ||
#### `camera.tick()` | ||
Call this at the beginning of each frame to update the current position of the camera. | ||
### camera.getGlPos(x, y, w, h) | ||
#### `camera.refresh()` | ||
Call after the width and height of the related canvas object changed. | ||
_Note: the camera does not update the width and height unless you tell it to using this function!_ | ||
#### `camera.getGlPos(x, y, w, h)` | ||
Computes the WebGL position of `x` and `y` given the width `w` and height `h` of the canvas object. | ||
@@ -69,7 +81,7 @@ | ||
### camera.dispose() | ||
#### `camera.dispose()` | ||
Unsubscribes all event listeners. | ||
### camera.config(options) | ||
#### `camera.config(options)` | ||
@@ -76,0 +88,0 @@ Configure the canvas camera. `options` accepts the following options: |
import createCamera from "camera-2d-simple"; | ||
import { vec2, vec3 } from "gl-matrix"; | ||
import createKeyPressed from "key-pressed"; | ||
import { vec2, vec4, mat4 } from "gl-matrix"; | ||
import isKeyPressed from "key-pressed"; | ||
import createMousePosition from "mouse-position"; | ||
@@ -12,3 +12,4 @@ import createMousePressed from "mouse-pressed"; | ||
distance = 1.0, | ||
target = [], | ||
target = [0, 0], | ||
rotation = 0, | ||
isFixed = false, | ||
@@ -23,3 +24,5 @@ isPan = true, | ||
) => { | ||
let camera = createCamera({ target, distance }); | ||
const scratch = new Float32Array(16); | ||
let camera = createCamera(target, distance, rotation); | ||
let isChanged = false; | ||
@@ -30,2 +33,7 @@ let mousePosition = createMousePosition(canvas); | ||
let height = canvas.height / window.devicePixelRatio; | ||
let width = canvas.width / window.devicePixelRatio; | ||
let isAlt = false; | ||
const getGlPos = (x, y, w, h) => { | ||
@@ -36,5 +44,7 @@ // Get relative WebGL position | ||
// Homogeneous vector | ||
const v = [relX, relY, 1]; | ||
const v = [relX, relY, 1, 1]; | ||
// Compute inverse view matrix | ||
const viewInv = mat4.invert(scratch, camera.view); | ||
// Translate vector | ||
vec3.transformMat3(v, v, camera.transformation); | ||
vec4.transformMat4(v, v, viewInv); | ||
return v.slice(0, 2); | ||
@@ -44,10 +54,8 @@ }; | ||
const tick = () => { | ||
if (isFixed) return undefined; | ||
if (isFixed) return false; | ||
const alt = createKeyPressed("<alt>"); | ||
const height = canvas.height / window.devicePixelRatio; | ||
const width = canvas.width / window.devicePixelRatio; | ||
isAlt = isKeyPressed("<alt>"); | ||
isChanged = false; | ||
if (isPan && mousePressed.left && !alt) { | ||
if (isPan && mousePressed.left && !isAlt) { | ||
// To pan 1:1 we need to half the width and height because the uniform | ||
@@ -57,3 +65,3 @@ // coordinate system goes from -1 to 1. | ||
((panSpeed * (mousePosition[0] - mousePosition.prev[0])) / width) * 2, | ||
((panSpeed * (mousePosition[1] - mousePosition.prev[1])) / height) * 2 | ||
((panSpeed * (mousePosition.prev[1] - mousePosition[1])) / height) * 2 | ||
]); | ||
@@ -64,28 +72,14 @@ isChanged = true; | ||
if (isZoom && scroll[1]) { | ||
// Target == viewport center | ||
const { target, distance: oldDist } = camera; | ||
const dZ = zoomSpeed * Math.exp(scroll[1] / height); | ||
const newDist = oldDist * dZ; | ||
const recipDDist = 1 - newDist / oldDist; | ||
// Get normalized device coordinates (NDC) | ||
const xNdc = -1 + (mousePosition[0] / width) * 2; | ||
const yNdc = 1 + (mousePosition[1] / height) * -2; | ||
// Get the relative WebGL coordinates of the mouse | ||
const [relX, relY] = getGlPos( | ||
mousePosition[0], | ||
mousePosition[1], | ||
width, | ||
height | ||
); | ||
camera.scale(1 / dZ, [xNdc, yNdc]); | ||
// X and Y distance between the center and the mouse | ||
const dX = target[0] - relX; | ||
const dY = target[1] - relY; | ||
camera.pan([dX * recipDDist, -dY * recipDDist]); | ||
camera.zoom(dZ); | ||
isChanged = true; | ||
} | ||
if (isRotate && (mousePressed.left && alt)) { | ||
if (isRotate && (mousePressed.left && isAlt)) { | ||
const wh = width / 2; | ||
@@ -127,34 +121,26 @@ const hh = height / 2; | ||
isPan: newIsPan, | ||
isRotate: newIsRotate, | ||
isZoom: newIsZoom, | ||
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; | ||
} | ||
isFixed = newIsFixed || isFixed; | ||
isPan = newIsPan || isPan; | ||
isRotate = newIsRotate || isRotate; | ||
isZoom = newIsZoom || isZoom; | ||
panSpeed = +newPanSpeed > 0 ? newPanSpeed : panSpeed; | ||
rotateSpeed = +newRotateSpeed > 0 ? newRotateSpeed : rotateSpeed; | ||
zoomSpeed = +newZoomSpeed > 0 ? newZoomSpeed : zoomSpeed; | ||
}; | ||
const refresh = () => { | ||
height = canvas.height / window.devicePixelRatio; | ||
width = canvas.width / window.devicePixelRatio; | ||
}; | ||
camera.config = config; | ||
camera.dispose = dispose; | ||
camera.getGlPos = getGlPos; | ||
camera.refresh = refresh; | ||
camera.tick = tick; | ||
@@ -161,0 +147,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
93
2
19345
254
+ Addedcamera-2d-simple@2.2.1(transitive)
+ Addedgl-matrix@3.1.0(transitive)
- Removedcamera-2d-simple@1.2.0(transitive)
Updatedcamera-2d-simple@^2.0.0-rc1