Security News
38% of CISOs Fear They’re Not Moving Fast Enough on AI
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
ngx-panzoom
Advanced tools
An Angular component for panning and zooming an element or elements using the mouse and mousewheel. Provides rudimentary support for touchscreens (read section on mobile support). It was adapted from the angular-pan-zoom library for AngularJS, but it ha
An Angular component for panning and zooming an element or elements using the mouse and mousewheel. Provides rudimentary support for touchscreens (read section on mobile support). It was adapted from the angular-pan-zoom library for AngularJS, but it has been heavily modified. Many thanks go out to Martin Vindahl Olsen for having written it, and for his blessing in this undertaking.
It is built using Angular CLI 10.x, so it may or may not work with Angular versions earlier than this. It is only tested with the corresponding version of Angular.
This library deliberately parts with certain received Angular wisdom of using only Angular-ish methods to accomplish things. We use native event listeners. We apply CSS transforms directly to the DOM. But as this library doesn't fit the traditional Angular model, as its purpose is only to alter a certain part of the DOM using CSS transforms, without adding, moving or changing anything else, it has no impact on an application's state (except if the app consumes modelChanged
observables). By using this approach, it is hoped that compatibility and performance will be maximised.
Just after the release of 10.0, I belatedly decided that the 'ng2' thing had been around long enough, therefore ng2-panzoom
will be no more, and ngx-panzoom
will supersede it.
I should've done this at the outset for the 10.0 release. I accuse myself of amateurism. Sorry.
npm uninstall ng2-panzoom --save && npm install ngx-panzoom --save
.NgxPanZoomModule
instead of Ng2PanZoomModule
ngx-panzoom
.Click here for a demo of the module. The demo source can be found here.
Version 10.x is compiled using Angular 10.x. Per the Angular guidance at the time of writing (https://angular.io/guide/creating-libraries
), Ivy is not used for the NPM repo build. The following changes have been made:
centerContent()
, centerTopLeft()
, centerBottomLeft()
, centerTopRight()
, centerBottomRight()
, centerX()
, and centerY()
zoomToFit()
animation - using the zoomToFit() function now will animate the view to the a desired rectangle.resetView()
has been provided to animate the view back to its initial settings.zoomIn()
and zoomOut()
API functions now zoom to the last zoomed point rather than the centre point, unless no zoom point has been defined yet.panToPoint()
, panDelta()
, panDeltaPercent()
, and panDeltaAbsolute()
have been added for panning the view.I am actively soliciting pull requests for mobile support. Read on.
The library implements some basic support that may work with some mobile devices, though pinch-to-zoom still needs considerable work. As the application that this library was developed for was never intended for use with mobile devices, there are no plans to implement full mobile support. As long as this remains the case, I respecfully ask for no more issues concerning mobile support, please. I realise that this will limit adoption, but for an enterprising developer out there, I can't imagine that adding mobile support would be nearly as big of a challenge as it was to port the library to Angular from AngularJS!
npm install ngx-panzoom --save
import { NgxPanZoomModule } from 'ngx-panzoom';
@NgModule({
imports: [ ...,
NgxPanZoomModule
],
...
})
export class MyAppModule { }
This library exposes a component called 'pan-zoom', under which you may place any standard Angular template code. Though the events which trigger panning and zooming are run outside of Angular and thus themselves will not trigger change detection, it should not break change detection for any sub-components.
A configuration object is required, which gets passed in using [config]="myConfig"
.
It also exposes an API which can be used to interact with the pan/zoom view. The API is obtained through the configuration object (more below).
Be sure to place your pan-zoom component underneath an element with a definite height/width, like an absolute-positioned div. You may not see anything if you don't do this.
import { PanZoomConfig, PanZoomAPI, PanZoomModel, PanZoomConfigOptions } from 'ngx-panzoom';
@Component({
selector: 'my-component'
template: `
<div style="position: absolute; top: 100px; bottom: 0; left: 0; right: 0;">
<pan-zoom [config]="panZoomConfig">
<div style="position: relative;">
<img src="/myimage1.jpg">
</div>
</pan-zoom>
</div>
`
})
export class MyComponent {
...
panZoomConfig: PanZoomConfig = new PanZoomConfig();
...
}
You must first create and then pass in a configuration object (of type PanZoomConfig) via the config
input property. This configuration object also contains RXJS Observables which can be used to work with the API and also observe changes to the panzoom view. The parameters can either be passed in as a PanZoomConfigOptions object, or set after the creation of the PanZoomConfig instance.
panZoomConfig: PanZoomConfig = new PanZoomConfig(options?: PanZoomConfigOptions);
The following attributes are defined:
Name | Type | Default | Description |
---|---|---|---|
api | BehaviorSubject<PanZoomAPI> | Not Applicable | Subscribe to this observable to obtain access to the API for controlling panzoom programattically. See section below on getting at the API. |
zoomLevels | number | 5 | Number of discrete zoom levels, each one representing a scale. The higher the number, the more zoomed in it is. |
neutralZoomLevel | number | 2 | The zoom level at which the contents render at 1:1 scale. |
scalePerZoomLevel | number | 2.0 | The difference in actual scale between two adjacent zoom levels. |
initialZoomLevel | number | neutralZoomLevel | The initially selected zoom level. |
initialPanX | number | 0 | The initial pan in the horizontal direction. |
initialPanY | number | 0 | The initial pan in the vertical direction. |
initialZoomToFit | rectangle | null | When defined, will initially zoom to fit the given rectangle (see API for explanation of zoom to fit). This overrides the initialZoomLevel, initialPanX, and initialPanY values. |
zoomToFitZoomLevelFactor | number | 0.95 | A number to indicate how closely zoom to fit will work. 1.0 is a perfect fit. Lowering the number will reveal a bit of the surrounding contents. |
zoomOnDoubleClick | boolean | true | Enable or disable zooming in on double click. |
zoomButtonIncrement | number | 1.0 | The number of zoom levels to zoom on double click. |
zoomStepDuration | number | 0.2 | Number of seconds to animate between two adjacent zoom levels. |
zoomOnMouseWheel | boolean | true | Enable or disable zoom in/out on mouse wheel. |
invertMouseWheel | boolean | false | Invert the behaviour of the mouse wheel (or two finger trackpad gesture). |
freeMouseWheel | boolean | true | By setting this to true, the mouse wheel will freely zoom the view without respect to discreet zoom levels. With false, moving the mouse wheel will zoom the view by zoomButtonIncrement. |
freeMouseWheelFactor | number | 0.08 | How much to zoom the view with every tick of the wheel, if using freeMouseWheel. |
friction | number | 10.0 | Constant which controls the friction when dragging and then letting go. The higher the number, the more quickly the animation will come to a stop. |
haltSpeed | number | 100.0 | Constant which controls when the pan animation has slowed down enough to be terminated. The lower the number, the longer it will take to come to a stop. |
panOnClickDrag | boolean | true | Enable or disable pan on clicking and dragging the mouse. |
modelChanged | BehaviorSubject<PanZoomModel> | Not Applicable | An RXJS observable which can be subscribed to in order to observe changes to the panzoom view. The model will be passed to the callback function. |
keepInBounds | boolean | false | When true, it will not be possible to pan the contents off the screen -- it will snap back when trying to do so. It will not be possible to zoom further out than the neutral zoom level. REMEMBER that the initial zoom level must either be less than or equal to the neutral zoom level, or weird things will happen. |
keepInBoundsRestoreForce | number | 0.5 | Constant to control how quickly the contents snap back into place after attempting to pan out of bounds. |
keepInBoundsDragPullback | number | 0.7 | Constant to control the perceived force preventing dragging the contents out of bounds. |
dragMouseButton | string | 'left' | Controls which mouse button drags the view. Valid options are left , middle , and right . NOTE: Using middle and right will disable the default 'auxclick' and 'contextmenu' handlers, respectively. ALSO NOTE: Chrome seems to have a bug that doesn't the permit the 'mousemove' event to fire after middle-click drag until it receives a normal left 'click' event. If anyone can shed any light on this, I'd be happy to hear from you. It's such an edge case, though, that I won't be opening a bug report, but feel free to do so if this affects you. |
noDragFromElementClass | string | null | If set, this will prevent click-drag on elements who have a parent element containing a specific class name. |
acceleratePan | boolean | true | Controls whether the pan frame will be hardware accelerated. |
The panzoom library provides an API for interacting with, observing, and controlling it. The following methods and objects are available from the PanZoomAPI:
model: PanZoomModel
- The current panzoom model - see the PanZoomModel Interface below.
config: PanZoomConfig
- The current panzooom configuration.
changeZoomLevel(newZoomLevel: number, clickPoint: Point)
- This method will reset the view to newZoomLevel, with clickPoint as its centre point.
zoomIn()
- This will zoom the view in to the last zoomed point by one zoom level.
zoomOut()
- This will zoom the view out from the last zoomed point by one zoom level.
zoomToFit(rectangle: Rect, [duration: number])
- Animates the view to focus on a rectangle of the underlying canvas. duration is how long the animation should take (in seconds), and is optional. rectangle is two coordinates on the canvas which the panZoom view is pan/zooming. See the below section on PanZoom Interfaces for its definition.
resetView()
- A shortcut method to reset the pan and zoom back to the initial view.
getViewPosition(modelPosition: Point)
- By passing in x,y coordinates of the original, untransformed content canvas, it will return the current pixel position of this point.
getModelPosition(viewPosition: Point)
- The reverse operation of getViewPosition().
panToPoint(point: Point, [duration: number])
- Will animate the view so that the centre point of the view is at the point parameter coordinates, relative to the original, unzoomed content width and height.
panDelta(delta: Point, [duration: number])
- Will pan the view left, right, up, or down, based on a number of pixels relative to the original, unzoomed content.
panDeltaPercent(deltaPercent: Point, [duration: number])
- Will pan the view up, down, left, or right, based on a percentage of the original, unzoomed content width and height.
panDeltaAbsolute(delta: Point, [duration: number])
- Will pan the view left, right, up, or down, based on a number of pixels. This method doesn't adjust for scale. I'm not sure why you'd want this, but it's provided just in case.
centerContent([duration: number])
- Will centre the the content vertically and horizontally at the current scale.
centerTopLeft([duration: number])
- Will centre the top-left corner of the content at the current scale.
centerBottomLeft([duration: number])
- Will centre the bottom-left corner of the content at the current scale.
centerTopRight([duration: number])
- Will centre the top-right corner of the content at the current scale.
centerBottomRight([duration: number])
- Will centre the bottom-right corner of the content at the current scale.
centerX([duration: number])
- Will centre the view on its X axis.
centerY([duration: number])
- Will centre the view on its Y axis.
interface PanZoomModel {
zoomLevel: number;
isPanning?: boolean;
pan: Point; // how far the view has been moved on the x and y axes. It is not adjusted for scale
}
interface Point {
x: number;
y: number;
}
interface Rect {
x: number; // the x0 (top left) coordinate
y: number; // the y0 (top left) coordinate
width: number; // the x1 (bottom right) coordinate
height: number; // the y1 (bottom right) coordinate
}
The panzoom API is exposed through an RxJS observable as a property of the PanZoomConfig
class, named api
, to which you simply subscribe to obtain the API object. The subscription callback method will be passed the API as its only parameter, of type PanZoomAPI
. Because it uses a BehaviorSubject, the callback will immediately trigger when subscribed to, assuming panzoom has already been initialised. If panzoom hasn't yet been initialised, the subscription callback will fire as soon as initialisation occurs.
import { PanZoomConfig, PanZoomAPI, PanZoomModel } from 'ngx-panzoom';
import { Subscription } from 'rxjs';
@Component({ ... })
export class MyComponent implements OnInit, OnDestroy {
panZoomConfig: PanZoomConfig = new PanZoomConfig();
private panZoomAPI: PanZoomAPI;
private apiSubscription: Subscription;
ngOnInit(): void {
this.apiSubscription = this.panzoomConfig.api.subscribe( (api: PanZoomAPI) => this.panZoomAPI = api );
}
ngOnDestroy(): void {
this.apiSubscription.unsubscribe(); // don't forget to unsubscribe. you don't want a memory leak!
}
}
Now that we have our API stored in this.panZoomAPI
, we can access it thusly:
this.panZoomAPI.zoomIn();
this.panZoomAPI.zoomOut();
The PanZoomConfig class has an RXJS observable (modelChanged
) which can be used to monitor the pan/zoom state from another component. The observable emits type PanZoomModel
(see above section on API Interfaces). For instance, when the zoom level reaches a certain level, you may want to display a custom control or content on your page. Another use may be to do something when the panzoom centre point is over a certain part of the view.
import { PanZoomConfig, PanZoomAPI, PanZoomModel } from 'ngx-panzoom';
@Component({ ... })
export class MyComponent implements OnInit, OnDestroy {
panZoomConfig: PanZoomConfig = new PanZoomConfig();
private modelChangedSubscription: Subscription;
ngOnInit(): void {
this.modelChangedSubscription = this.panzoomConfig.modelChanged.subscribe( (model: PanZoomModel) => this.onModelChanged(model) );
}
ngOnDestroy(): void {
this.modelChangedSubscription.unsubscribe(); // don't forget to unsubscribe. you don't want a memory leak!
}
onModelChanged(model: PanZoomModel): void {
// do something after receiving your model update here
}
}
Pull requests are welcome.
Martin Vindahl Olsen's original angular-pan-zoom project on GitHub
10.3.0
lastPoint
(default for backwards-compatibility) and viewCenter
to zoomIn()
and zoomOut()
API methods. Defines which point to zoom to/from: either the centre of the screen or the last point zoomed to/from.model.isPanning
remaining true after pan end.model.isPanning
was not being set for panning API calls.FAQs
An Angular component for panning and zooming an element or elements using the mouse and mousewheel. Provides rudimentary support for touchscreens (read section on mobile support). It was adapted from the angular-pan-zoom library for AngularJS, but it ha
The npm package ngx-panzoom receives a total of 0 weekly downloads. As such, ngx-panzoom popularity was classified as not popular.
We found that ngx-panzoom demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.
Security News
Company News
Socket is joining TC54 to help develop standards for software supply chain security, contributing to the evolution of SBOMs, CycloneDX, and Package URL specifications.