-
Notifications
You must be signed in to change notification settings - Fork 2.2k
fix(core): export MapState and MapStateProps #9929
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
41e4814
595da8e
5e9e7e4
7d8d282
99051b3
7a8af60
3ad6006
3d7cbf6
18d2204
4ff8167
69fcc2d
1258f74
c19a7f3
1c84789
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -66,6 +66,88 @@ new Deck({ | |
|
|
||
| See the `Controller` class [documentation](./controller.md#methods) for the methods that you can use and/or override. | ||
|
|
||
| ## MapState | ||
|
|
||
| The `MapState` class manages the internal state of the map controller. It provides methods for handling user interactions like panning, rotating, and zooming. | ||
|
|
||
| ### Usage | ||
|
|
||
| ```js | ||
| import {MapState} from '@deck.gl/core'; | ||
|
|
||
| // Create a MapState instance | ||
| const mapState = new MapState({ | ||
| width: 800, | ||
| height: 600, | ||
| latitude: 37.7749, | ||
| longitude: -122.4194, | ||
| zoom: 11, | ||
| bearing: 0, | ||
| pitch: 0, | ||
| makeViewport: (props) => new WebMercatorViewport(props) | ||
| }); | ||
|
|
||
| // Use MapState methods | ||
| const newState = mapState.pan({pos: [100, 100]}); | ||
| const zoomedState = mapState.zoom({pos: [400, 300], scale: 2}); | ||
|
Comment on lines
+73
to
+92
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think these classes are intended to be used directly like this - rather, they are to be implemented and the Controller uses them. My current understanding is these are for helping users implement extensions of core controllers: Usage docs along these lines makes more sense then showing direct function calls |
||
| ``` | ||
|
|
||
| ### Methods | ||
|
|
||
| MapState provides the following interaction methods: | ||
|
|
||
| - `panStart({pos})` - Start a pan interaction | ||
| - `pan({pos, startPos})` - Pan the map | ||
| - `panEnd()` - End a pan interaction | ||
| - `rotateStart({pos})` - Start a rotation interaction | ||
| - `rotate({pos, deltaAngleX, deltaAngleY})` - Rotate the map | ||
| - `rotateEnd()` - End a rotation interaction | ||
| - `zoomStart({pos})` - Start a zoom interaction | ||
| - `zoom({pos, startPos, scale})` - Zoom the map | ||
| - `zoomEnd()` - End a zoom interaction | ||
| - `zoomIn(speed)` - Zoom in | ||
| - `zoomOut(speed)` - Zoom out | ||
| - `moveLeft(speed)`, `moveRight(speed)`, `moveUp(speed)`, `moveDown(speed)` - Move the map | ||
| - `rotateLeft(speed)`, `rotateRight(speed)`, `rotateUp(speed)`, `rotateDown(speed)` - Rotate the map | ||
|
|
||
| ## MapStateProps | ||
|
|
||
| The `MapStateProps` type defines the properties for configuring map viewport state. | ||
|
|
||
| ### Properties | ||
|
|
||
| - `width` (number) - The width of the viewport | ||
| - `height` (number) - The height of the viewport | ||
| - `latitude` (number) - The latitude at the center of the viewport | ||
| - `longitude` (number) - The longitude at the center of the viewport | ||
| - `zoom` (number) - The tile zoom level of the map | ||
| - `bearing` (number, optional) - The bearing of the viewport in degrees. Default `0` | ||
| - `pitch` (number, optional) - The pitch of the viewport in degrees. Default `0` | ||
| - `altitude` (number, optional) - Specify the altitude of the viewport camera. Unit: map heights. Default `1.5` | ||
| - `position` ([number, number, number], optional) - Viewport position. Default `[0, 0, 0]` | ||
| - `maxZoom` (number, optional) - Maximum zoom level. Default `20` | ||
| - `minZoom` (number, optional) - Minimum zoom level. Default `0` | ||
| - `maxPitch` (number, optional) - Maximum pitch in degrees. Default `60` | ||
| - `minPitch` (number, optional) - Minimum pitch in degrees. Default `0` | ||
| - `normalize` (boolean, optional) - Normalize viewport props to fit map height into viewport. Default `true` | ||
|
|
||
| ### Usage | ||
|
|
||
| ```js | ||
| import type {MapStateProps} from '@deck.gl/core'; | ||
|
|
||
| const viewState: MapStateProps = { | ||
| width: 800, | ||
| height: 600, | ||
| latitude: 37.7749, | ||
| longitude: -122.4194, | ||
| zoom: 11, | ||
| bearing: 0, | ||
| pitch: 45, | ||
| maxZoom: 18, | ||
| minZoom: 5 | ||
| }; | ||
| ``` | ||
|
|
||
| ## Source | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| # ColumnLayer Cap Shape Example | ||
|
|
||
| This example demonstrates the new `capShape` property for the ColumnLayer, which allows you to customize the top of columns. | ||
|
|
||
| ## Running this example | ||
|
|
||
| To run this example, you need to install dependencies first: | ||
|
|
||
| ```bash | ||
| # From the repository root | ||
| cd examples/get-started/pure-js/column-cap-shape | ||
| yarn | ||
| yarn start | ||
| ``` | ||
|
|
||
| Or to use the local development version of deck.gl: | ||
|
|
||
| ```bash | ||
| yarn start-local | ||
| ``` | ||
|
|
||
| ## Features | ||
|
|
||
| The example shows: | ||
| - **Cap Shape Selection**: Switch between flat (default), rounded (dome), and pointy (cone) column tops | ||
| - **Disk Resolution**: Adjust the number of sides (4-40) to see how it affects geometry smoothness | ||
| - **Interactive Controls**: Real-time updates when changing settings | ||
| - **3D Visualization**: Rotate and zoom to inspect columns from different angles | ||
|
|
||
| ## Usage | ||
|
|
||
| ```javascript | ||
| new ColumnLayer({ | ||
| data: myData, | ||
| extruded: true, | ||
| capShape: 'rounded', // 'flat' | 'rounded' | 'pointy' | ||
| diskResolution: 20, | ||
| getPosition: d => d.position, | ||
| getElevation: d => d.elevation, | ||
| getFillColor: d => d.color | ||
| }); | ||
| ``` | ||
|
|
||
| ## Cap Shapes | ||
|
|
||
| - **`flat`** (default): Traditional flat top - preserves original behavior | ||
| - **`rounded`**: Dome-shaped top, like a silo - uses multiple latitude rings | ||
| - **`pointy`**: Cone-shaped top, like a missile - converges to a single apex point |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| // deck.gl | ||
| // SPDX-License-Identifier: MIT | ||
| // Copyright (c) vis.gl contributors | ||
|
|
||
| import {Deck} from '@deck.gl/core'; | ||
| import {ColumnLayer} from '@deck.gl/layers'; | ||
|
|
||
| // Generate sample data - grid of columns | ||
| const data = []; | ||
| for (let x = -2; x <= 2; x++) { | ||
| for (let y = -2; y <= 2; y++) { | ||
| data.push({ | ||
| position: [-122.4 + x * 0.01, 37.8 + y * 0.01], | ||
| elevation: Math.random() * 3000 + 1000, | ||
| color: [ | ||
| Math.floor(Math.random() * 200) + 55, | ||
| Math.floor(Math.random() * 200) + 55, | ||
| Math.floor(Math.random() * 200) + 55, | ||
| 255 | ||
| ] | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| const INITIAL_VIEW_STATE = { | ||
| longitude: -122.4, | ||
| latitude: 37.8, | ||
| zoom: 13, | ||
| pitch: 45, | ||
| bearing: 0 | ||
| }; | ||
|
|
||
| function createLayer(capShape, diskResolution) { | ||
| return new ColumnLayer({ | ||
| id: 'column-layer', | ||
| data: data, | ||
| diskResolution: diskResolution, | ||
| radius: 200, | ||
| extruded: true, | ||
| capShape: capShape, // NEW: 'flat', 'rounded', or 'pointy' | ||
| elevationScale: 1, | ||
| getPosition: d => d.position, | ||
| getFillColor: d => d.color, | ||
| getElevation: d => d.elevation, | ||
| pickable: true | ||
| }); | ||
| } | ||
|
|
||
| // Initialize deck.gl | ||
| const deckgl = new Deck({ | ||
| initialViewState: INITIAL_VIEW_STATE, | ||
| controller: true, | ||
| layers: [createLayer('flat', 20)], | ||
| getTooltip: ({object}) => object && `Elevation: ${object.elevation.toFixed(0)}m` | ||
| }); | ||
|
|
||
| // Set up controls | ||
| const capShapeSelect = document.getElementById('capShape'); | ||
| const diskResolutionSlider = document.getElementById('diskResolution'); | ||
| const diskResValueSpan = document.getElementById('diskResValue'); | ||
|
|
||
| function updateLayers() { | ||
| const capShape = capShapeSelect.value; | ||
| const diskResolution = parseInt(diskResolutionSlider.value); | ||
| diskResValueSpan.textContent = diskResolution; | ||
|
|
||
| deckgl.setProps({ | ||
| layers: [createLayer(capShape, diskResolution)] | ||
| }); | ||
| } | ||
|
|
||
| capShapeSelect.addEventListener('change', updateLayers); | ||
| diskResolutionSlider.addEventListener('input', updateLayers); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| <!doctype html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="utf-8"> | ||
| <title>deck.gl ColumnLayer Cap Shape Example</title> | ||
| <style> | ||
| body { | ||
| margin: 0; | ||
| width: 100vw; | ||
| height: 100vh; | ||
| overflow: hidden; | ||
| font-family: Arial, sans-serif; | ||
| } | ||
| #controls { | ||
| position: absolute; | ||
| top: 10px; | ||
| left: 10px; | ||
| background: white; | ||
| padding: 15px; | ||
| border-radius: 5px; | ||
| z-index: 1; | ||
| box-shadow: 0 2px 4px rgba(0,0,0,0.3); | ||
| } | ||
| .control-group { | ||
| margin-bottom: 10px; | ||
| } | ||
| label { | ||
| display: block; | ||
| margin-bottom: 5px; | ||
| font-weight: bold; | ||
| } | ||
| select, input { | ||
| width: 200px; | ||
| } | ||
| </style> | ||
| </head> | ||
| <body> | ||
| <div id="controls"> | ||
| <h3>ColumnLayer Cap Shape</h3> | ||
| <div class="control-group"> | ||
| <label>Cap Shape:</label> | ||
| <select id="capShape"> | ||
| <option value="flat">Flat (Default)</option> | ||
| <option value="rounded">Rounded (Dome)</option> | ||
| <option value="pointy">Pointy (Cone)</option> | ||
| </select> | ||
| </div> | ||
| <div class="control-group"> | ||
| <label>Disk Resolution: <span id="diskResValue">20</span></label> | ||
| <input type="range" id="diskResolution" min="4" max="40" value="20"> | ||
| </div> | ||
| </div> | ||
| </body> | ||
| <script type="module" src="app.js"></script> | ||
| </html> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| { | ||
| "name": "deckgl-example-column-cap-shape", | ||
| "version": "0.0.0", | ||
| "private": true, | ||
| "license": "MIT", | ||
| "scripts": { | ||
| "start": "vite --open", | ||
| "start-local": "vite --config ../../../vite.config.local.mjs", | ||
| "build": "vite build" | ||
| }, | ||
| "dependencies": { | ||
| "@deck.gl/core": "^9.0.0", | ||
| "@deck.gl/layers": "^9.0.0" | ||
| }, | ||
| "devDependencies": { | ||
| "vite": "^4.0.0" | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Each class is typically documented in their own file, however these classes are meant to always be composited into controllers, so this organization could make sense.
It'd be great to have the custom controller example expanded to include the application of this class and https://deck.gl/docs/api-reference/core/controller#example-implementing-a-custom-controller to mention ViewState