Skip to content

Commit

Permalink
give opportunity to set zoom lvls (#185)
Browse files Browse the repository at this point in the history
* give opportunity to set zoom lvls

* created a story

* renamed setZoomLevel to setZoomLevelBoundary, added possibility to set min zoom on instantiation

* added min zoom lvl from options on init

* renamed methods in layermanager and maincontroller

Co-authored-by: Brynjulf <[email protected]>
  • Loading branch information
Brynjulf and Brynjulf committed Apr 21, 2020
1 parent f9a1b5a commit 5485c80
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 6 deletions.
67 changes: 64 additions & 3 deletions .storybook/src/zoom.stories.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { select } from 'd3-selection';
import { CanvasLayer } from '../../src/layers/CanvasLayer';
import { OnUpdateEvent, OnRescaleEvent, LayerOptions } from '../../src/interfaces';
import { GridLayer } from '../../src/layers/GridLayer';
import { ZoomPanHandler } from '../../src/control/ZoomPanHandler';
import { createFPSLabel } from './utils';
import { GridLayer } from '../../src/layers';
import { ZoomPanHandler } from '../../src/control';
import { Axis } from '../../src/components';
import { createFPSLabel, createRootContainer, createLayerContainer } from './utils';

const width = 600;
const height = 400;
Expand Down Expand Up @@ -269,3 +271,62 @@ export const Grid = () => {

return root;
};

export const GridWithAxis = () => {
const root = createRootContainer(width);
const container = createLayerContainer(width, height);
const buttons = document.createElement('div');

const marginXAxis = 40;
const marginYAxis = 30;

const svg = select(container).append('svg').attr('height', `${height}px`).attr('width', `${width}px`).style('position', 'absolute');

const mainGroup = svg;
const showLabels = true;

const axis = new Axis(mainGroup, showLabels, 'Displacement', 'TVD MSL', 'm');

const gridLayer = new GridLayer('grid', {
majorColor: 'black',
minorColor: 'black',
majorWidth: 0.5,
minorWidth: 0.5,
order: 1,
});

gridLayer.onMount({ elm: container, width, height });

const zoomHandler = new ZoomPanHandler(container, (event: OnRescaleEvent) => {
axis.onRescale(event);
gridLayer.onRescale(event);
});

zoomHandler.setMinZoomLevel(0.1);
zoomHandler.setMaxZoomLevel(10);

zoomHandler.setBounds([0, 1000], [0, 1000]);
zoomHandler.adjustToSize(width - marginXAxis, height - marginYAxis);

buttons.appendChild(
createButton('min zoom 1', () => {
zoomHandler.setMinZoomLevel(1);
}),
);
buttons.appendChild(
createButton('max zoom 100', () => {
zoomHandler.setMaxZoomLevel(100);
}),
);
buttons.appendChild(
createButton('reset', () => {
zoomHandler.setZoomLevelBoundary([0.1, 256]);
}),
);

root.appendChild(container);
root.appendChild(buttons);
root.appendChild(createFPSLabel());

return root;
}
15 changes: 15 additions & 0 deletions src/control/LayerManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,21 @@ export class LayerManager {
return this;
}

setZoomLevelBoundary(zoomlevels: [number, number]): LayerManager {
this._zoomPanHandler.setZoomLevelBoundary(zoomlevels);
return this;
}

setMaxZoomLevel(zoomlevel: number): LayerManager {
this._zoomPanHandler.setMaxZoomLevel(zoomlevel);
return this;
}

setMinZoomLevel(zoomlevel: number): LayerManager {
this._zoomPanHandler.setMinZoomLevel(zoomlevel);
return this;
}

get zoomPanHandler(): ZoomPanHandler {
return this._zoomPanHandler;
}
Expand Down
15 changes: 15 additions & 0 deletions src/control/MainController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,21 @@ export class Controller {
return this;
}

setZoomLevelBoundary(zoomlevels: [number, number]): Controller {
this.zoomPanHandler.setZoomLevelBoundary(zoomlevels);
return this;
}

setMaxZoomLevel(zoomlevel: number): Controller {
this.zoomPanHandler.setMaxZoomLevel(zoomlevel);
return this;
}

setMinZoomLevel(zoomlevel: number): Controller {
this.zoomPanHandler.setMinZoomLevel(zoomlevel);
return this;
}

get overlay(): Overlay {
return this._overlay;
}
Expand Down
30 changes: 27 additions & 3 deletions src/control/ZoomPanHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { zoom, zoomIdentity, ZoomBehavior, ZoomTransform } from 'd3-zoom';

import { ZoomAndPanOptions, OnRescaleEvent, OnUpdateEvent } from '../interfaces';

const DEFAULT_MIN_ZOOM_LEVEL = 0.1;
const DEFAULT_MAX_ZOOM_LEVEL = 256;

type RescaleFunction = (event: OnRescaleEvent) => void;
/**
* Handle zoom and pan for intersection layers
Expand All @@ -29,7 +32,11 @@ export class ZoomPanHandler {
* @param elm, -
* @param options - options
*/
constructor(elm: HTMLElement, onRescale: RescaleFunction, options: ZoomAndPanOptions = { maxZoomLevel: 256 }) {
constructor(
elm: HTMLElement,
onRescale: RescaleFunction,
options: ZoomAndPanOptions = { maxZoomLevel: DEFAULT_MAX_ZOOM_LEVEL, minZoomLevel: DEFAULT_MIN_ZOOM_LEVEL },
) {
this.onZoom = this.onZoom.bind(this);

this.container = select(elm);
Expand Down Expand Up @@ -231,7 +238,7 @@ export class ZoomPanHandler {
* Initialized handler
*/
init(): void {
this.zoom = zoom().scaleExtent([0.1, this.options.maxZoomLevel]).on('zoom', this.onZoom);
this.zoom = zoom().scaleExtent([this.options.minZoomLevel, this.options.maxZoomLevel]).on('zoom', this.onZoom);

this.container.call(this.zoom);
}
Expand Down Expand Up @@ -396,7 +403,7 @@ export class ZoomPanHandler {
/**
* Recalcualate the transform
*/
recalculateZoomTransform() {
recalculateZoomTransform(): void {
const { scaleX, scaleY, container, calculateTransform, updateTranslateExtent } = this;

const [dx0, dx1] = scaleX.domain();
Expand All @@ -410,4 +417,21 @@ export class ZoomPanHandler {

this.zoom.transform(container, transform);
}

setZoomLevelBoundary(zoomlevels: [number, number]): ZoomPanHandler {
this.zoom.scaleExtent(zoomlevels);
return this;
}

setMaxZoomLevel(zoomlevel: number): ZoomPanHandler {
const zoomLevels = this.zoom.scaleExtent();
this.zoom.scaleExtent([zoomLevels[0], zoomlevel]);
return this;
}

setMinZoomLevel(zoomlevel: number): ZoomPanHandler {
const zoomLevels = this.zoom.scaleExtent();
this.zoom.scaleExtent([zoomlevel, zoomLevels[1]]);
return this;
}
}
1 change: 1 addition & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export interface GeoModelData {

export interface ZoomAndPanOptions {
maxZoomLevel: number;
minZoomLevel: number;
}

export interface Connector {
Expand Down

0 comments on commit 5485c80

Please sign in to comment.