Skip to content
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

add translate mode to draw #235

Merged
merged 6 commits into from
Feb 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/plugins/Draw/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## unpublished

- Feature: Add a "Translate" mode that allows moving drawn features as they are.

## 3.0.0

- Breaking: Upgrade peerDependency `ol` from `^9.2.4` to `^10.3.1`.
Expand Down
2 changes: 2 additions & 0 deletions packages/plugins/Draw/src/locales.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const resourcesDe = {
write: 'Zeichnen und Schreiben',
writeAndMeasure: 'Zeichnen, Schreiben und Messen',
edit: 'Bearbeiten',
translate: 'Verschieben',
delete: 'Löschen',
},
drawMode: {
Expand Down Expand Up @@ -53,6 +54,7 @@ export const resourcesEn = {
write: 'Draw and write',
writeAndMeasure: 'Draw, write and measure',
edit: 'Edit',
translate: 'Translate',
delete: 'Delete',
},
drawMode: {
Expand Down
2 changes: 2 additions & 0 deletions packages/plugins/Draw/src/store/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { createTextStyle } from '../utils/createTextStyle'
import createDrawStyle from '../utils/createDrawStyle'
import createInteractions from './createInteractions'
import createModifyInteractions from './createInteractions/createModifyInteractions'
import createTranslateInteractions from './createInteractions/createTranslateInteractions'
import modifyDrawStyle from './createInteractions/modifyDrawStyle'
import modifyTextStyle from './createInteractions/modifyTextStyle'

Expand All @@ -22,6 +23,7 @@ export const makeActions = () => {
const actions: PolarActionTree<DrawState, DrawGetters> = {
createInteractions,
createModifyInteractions,
createTranslateInteractions,
modifyDrawStyle,
modifyTextStyle,
setupModule({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,30 @@
import { Modify, Select, Snap } from 'ol/interaction'
import Interaction from 'ol/interaction/Interaction'
import { PolarActionContext } from '@polar/lib-custom-types'
import { Collection, Feature, Map, MapBrowserEvent } from 'ol'
import { Collection, Feature, Map } from 'ol'
import { CreateInteractionsPayload, DrawGetters, DrawState } from '../../types'
import { makeLocalSelector } from './localSelector'

const createModify = (
map: Map,
drawLayer: CreateInteractionsPayload['drawLayer']
) => {
let active = false
const activeContainer = { active: false }
const features: Collection<Feature> = new Collection()
const modify = new Modify({ features })
modify.on('modifystart', () => {
active = true
activeContainer.active = true
})
modify.on('modifyend', () => {
active = false
activeContainer.active = false
})

const localSelector = (e: MapBrowserEvent<UIEvent>) => {
if (!active) {
map.forEachFeatureAtPixel(
e.pixel,
(f) => {
if (f !== features.item(0)) {
features.setAt(0, f as Feature)
}
return true
},
{
layerFilter: (l) => l === drawLayer,
}
)
}
}

const localSelector = makeLocalSelector(
map,
activeContainer,
features,
drawLayer
)
map.on('pointermove', localSelector)
// @ts-expect-error | "un on removal" riding piggyback as _onRemove
modify._onRemove = () => map.un('pointermove', localSelector)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Translate, Snap } from 'ol/interaction'
import Interaction from 'ol/interaction/Interaction'
import { PolarActionContext } from '@polar/lib-custom-types'
import { Collection, Feature, Map } from 'ol'
import { CreateInteractionsPayload, DrawGetters, DrawState } from '../../types'
import { makeLocalSelector } from './localSelector'

const createTranslate = (
map: Map,
drawLayer: CreateInteractionsPayload['drawLayer']
) => {
const activeContainer = { active: false }
const features: Collection<Feature> = new Collection()
const translate = new Translate({ features })
translate.on('translatestart', () => {
activeContainer.active = true
})
translate.on('translateend', () => {
activeContainer.active = false
})

const localSelector = makeLocalSelector(
map,
activeContainer,
features,
drawLayer
)
map.on('pointermove', localSelector)
// @ts-expect-error | "un on removal" riding piggyback as _onRemove
translate._onRemove = () => map.un('pointermove', localSelector)

return translate
}

export default function (
{ rootGetters }: PolarActionContext<DrawState, DrawGetters>,
{ drawSource, drawLayer }: CreateInteractionsPayload
): Interaction[] {
return [
createTranslate(rootGetters.map, drawLayer),
new Snap({ source: drawSource }),
]
}
4 changes: 2 additions & 2 deletions packages/plugins/Draw/src/store/createInteractions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export default function (
map.getView().getProjection(),
configuration?.style
)

const draw = new Draw({
source: drawSource,
type: drawMode,
Expand All @@ -47,10 +46,11 @@ export default function (
// @ts-expect-error | internal hack to detect it in @polar/plugin-pins and @polar/plugin-gfi
draw._isDrawPlugin = true
draw.on('drawend', (e) => e.feature.setStyle(style))

return [draw, new Snap({ source: drawSource })]
} else if (mode === 'edit') {
return dispatch('createModifyInteractions', { drawSource, drawLayer })
} else if (mode === 'translate') {
return dispatch('createTranslateInteractions', { drawSource, drawLayer })
} else if (mode === 'delete') {
return createDeleteInteractions(drawSource, drawLayer)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Collection, Feature, Map, MapBrowserEvent } from 'ol'
import { CreateInteractionsPayload } from '../../types'

/* sets the topmost hovered feature as singleton feature in collection */
export const makeLocalSelector =
(
map: Map,
activeContainer: { active: boolean },
features: Collection<Feature>,
drawLayer: CreateInteractionsPayload['drawLayer']
) =>
// bound event processor
(e: MapBrowserEvent<UIEvent>) => {
if (!activeContainer.active) {
map.forEachFeatureAtPixel(
e.pixel,
(f) => {
if (f !== features.item(0)) {
features.setAt(0, f as Feature)
}
return true
},
{
layerFilter: (l) => l === drawLayer,
}
)
}
}
1 change: 1 addition & 0 deletions packages/plugins/Draw/src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export const makeStoreModule = () => {
none: 'plugins.draw.mode.none',
draw: `plugins.draw.mode.${drawLabel}`,
edit: 'plugins.draw.mode.edit',
translate: 'plugins.draw.mode.translate',
delete: 'plugins.draw.mode.delete',
}
},
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/Draw/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export interface PolarVectorOptions {
style?: StyleLike
}

export type Mode = 'none' | 'draw' | 'edit' | 'delete'
export type Mode = 'none' | 'draw' | 'edit' | 'translate' | 'delete'

export interface CreateInteractionsPayload {
drawSource: VectorSource
Expand Down