diff --git a/packages/ripple-ui-core/src/components/icon/constants.ts b/packages/ripple-ui-core/src/components/icon/constants.ts
index 24d59806e3..f7b85f73d3 100644
--- a/packages/ripple-ui-core/src/components/icon/constants.ts
+++ b/packages/ripple-ui-core/src/components/icon/constants.ts
@@ -85,7 +85,8 @@ export const RplIconGroups = {
'icon-view',
'icon-zoom-in',
'icon-zoom-out'
- ]
+ ],
+ map: ['icon-enlarge', 'icon-map-zoom-in', 'icon-map-zoom-out', 'icon-home']
} as const
export default {
diff --git a/packages/ripple-ui-core/src/components/icon/custom.js b/packages/ripple-ui-core/src/components/icon/custom.js
index 633457e169..ab2b99c8a5 100644
--- a/packages/ripple-ui-core/src/components/icon/custom.js
+++ b/packages/ripple-ui-core/src/components/icon/custom.js
@@ -56,5 +56,9 @@ export default {
'icon-wechat': () => import('./custom/icon-wechat.svg?component'),
'icon-youtube': () => import('./custom/icon-youtube.svg?component'),
'icon-zoom-in': () => import('./custom/icon-zoom-in.svg?component'),
- 'icon-zoom-out': () => import('./custom/icon-zoom-out.svg?component')
+ 'icon-zoom-out': () => import('./custom/icon-zoom-out.svg?component'),
+ 'icon-map-zoom-in': () => import('./custom/icon-map-zoom-in.svg?component'),
+ 'icon-map-zoom-out': () => import('./custom/icon-map-zoom-out.svg?component'),
+ 'icon-enlarge': () => import('./custom/icon-enlarge.svg?component'),
+ 'icon-home': () => import('./custom/icon-home.svg?component')
}
diff --git a/packages/ripple-ui-core/src/components/icon/custom/Icon-map-zoom-out.svg b/packages/ripple-ui-core/src/components/icon/custom/Icon-map-zoom-out.svg
new file mode 100644
index 0000000000..7fec07a021
--- /dev/null
+++ b/packages/ripple-ui-core/src/components/icon/custom/Icon-map-zoom-out.svg
@@ -0,0 +1 @@
+
diff --git a/packages/ripple-ui-core/src/components/icon/custom/icon-enlarge.svg b/packages/ripple-ui-core/src/components/icon/custom/icon-enlarge.svg
new file mode 100644
index 0000000000..192d6552f6
--- /dev/null
+++ b/packages/ripple-ui-core/src/components/icon/custom/icon-enlarge.svg
@@ -0,0 +1,4 @@
+
diff --git a/packages/ripple-ui-core/src/components/icon/custom/icon-home.svg b/packages/ripple-ui-core/src/components/icon/custom/icon-home.svg
new file mode 100644
index 0000000000..ab9a70bc03
--- /dev/null
+++ b/packages/ripple-ui-core/src/components/icon/custom/icon-home.svg
@@ -0,0 +1 @@
+
diff --git a/packages/ripple-ui-core/src/components/icon/custom/icon-map-zoom-in.svg b/packages/ripple-ui-core/src/components/icon/custom/icon-map-zoom-in.svg
new file mode 100644
index 0000000000..843dda137f
--- /dev/null
+++ b/packages/ripple-ui-core/src/components/icon/custom/icon-map-zoom-in.svg
@@ -0,0 +1 @@
+
diff --git a/packages/ripple-ui-maps/src/components/map/RplMap.css b/packages/ripple-ui-maps/src/components/map/RplMap.css
index 419e8b8a4f..913bf340f2 100644
--- a/packages/ripple-ui-maps/src/components/map/RplMap.css
+++ b/packages/ripple-ui-maps/src/components/map/RplMap.css
@@ -17,7 +17,7 @@
.rpl-map__control {
position: absolute;
right: var(--rpl-sp-2);
-
+ z-index: var(--rpl-layer-1);
@media (--rpl-bp-l) {
right: var(--rpl-sp-3);
}
@@ -86,12 +86,12 @@
bottom: var(--rpl-sp-3);
}
- .ol-zoom-in {
+ .rpl-map__control-zoom-in {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
- .ol-zoom-out {
+ .rpl-map__control-zoom-out {
border-top-left-radius: 0;
border-top-right-radius: 0;
border-top: none;
diff --git a/packages/ripple-ui-maps/src/components/map/RplMap.vue b/packages/ripple-ui-maps/src/components/map/RplMap.vue
index 38329d7561..1116a34769 100644
--- a/packages/ripple-ui-maps/src/components/map/RplMap.vue
+++ b/packages/ripple-ui-maps/src/components/map/RplMap.vue
@@ -1,5 +1,6 @@
@@ -225,22 +222,34 @@ function onHomeClick() {
-
-
diff --git a/packages/ripple-ui-maps/src/composables/useMapControlLabel.ts b/packages/ripple-ui-maps/src/composables/useMapControlLabel.ts
deleted file mode 100644
index 8a140150d8..0000000000
--- a/packages/ripple-ui-maps/src/composables/useMapControlLabel.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-export default () => {
- function createHTMLElementFromString(text: string): HTMLOrSVGElement {
- const div = document.createElement('div')
- div.innerHTML = text.trim()
- const svg = div.firstElementChild
- svg.setAttribute('fill', 'currentColor')
- return svg
- }
- return {
- createHTMLElementFromString
- }
-}
diff --git a/packages/ripple-ui-maps/src/composables/useMapControls.ts b/packages/ripple-ui-maps/src/composables/useMapControls.ts
new file mode 100644
index 0000000000..dc2d9157a3
--- /dev/null
+++ b/packages/ripple-ui-maps/src/composables/useMapControls.ts
@@ -0,0 +1,135 @@
+import { easeOut } from 'ol/easing'
+import { centerMap } from './../components/map/utils.ts'
+import { ref } from 'vue'
+export default (mapRef, center, initialZoom) => {
+ const isFullScreenRef = ref(false)
+
+ /**
+ * @param {number} delta Zoom delta.
+ * @private
+ */
+ function zoomByDelta(delta, duration = 250) {
+ const view = mapRef.value.map.getView()
+ if (!view) {
+ // the map does not have a view, so we can't act
+ // upon it
+ return
+ }
+ const currentZoom = view.getZoom()
+ if (currentZoom !== undefined) {
+ const newZoom = view.getConstrainedZoom(currentZoom + delta)
+ if (duration > 0) {
+ if (view.getAnimating()) {
+ view.cancelAnimations()
+ }
+ view.animate({
+ zoom: newZoom,
+ duration: duration,
+ easing: easeOut
+ })
+ } else {
+ view.setZoom(newZoom)
+ }
+ }
+ }
+
+ /**
+ * @param {Document} doc The root document to check.
+ * @return {boolean} Fullscreen is supported by the current platform.
+ */
+ function isFullScreenSupported(doc) {
+ const body = doc.body
+ return !!(
+ body['webkitRequestFullscreen'] ||
+ (body.requestFullscreen && doc.fullscreenEnabled)
+ )
+ }
+
+ /**
+ * @param {Document} doc The root document to check.
+ * @return {boolean} Element is currently in fullscreen.
+ */
+ function isFullScreen(doc) {
+ return !!(doc['webkitIsFullScreen'] || doc.fullscreenElement)
+ }
+
+ /**
+ * Request to fullscreen an element.
+ * @param {HTMLElement} element Element to request fullscreen
+ */
+ function requestFullScreen(element) {
+ if (element.requestFullscreen) {
+ element.requestFullscreen()
+ } else if (element['webkitRequestFullscreen']) {
+ element['webkitRequestFullscreen']()
+ }
+ }
+
+ /**
+ * Request to fullscreen an element with keyboard input.
+ * @param {HTMLElement} element Element to request fullscreen
+ */
+ function requestFullScreenWithKeys(element) {
+ if (element['webkitRequestFullscreen']) {
+ element['webkitRequestFullscreen']()
+ } else {
+ requestFullScreen(element)
+ }
+ }
+
+ /**
+ * Exit fullscreen.
+ * @param {Document} doc The document to exit fullscren from
+ */
+ function exitFullScreen(doc) {
+ if (doc.exitFullscreen) {
+ doc.exitFullscreen()
+ } else if (doc['webkitExitFullscreen']) {
+ doc['webkitExitFullscreen']()
+ }
+ }
+
+ function handleFullScreen(withKeys = false) {
+ const map = mapRef.value.map
+ if (!map) {
+ return
+ }
+ const doc = map.getOwnerDocument()
+ if (!isFullScreenSupported(doc)) {
+ return
+ }
+ if (isFullScreen(doc)) {
+ exitFullScreen(doc)
+ isFullScreenRef.value = false
+ } else {
+ const element = map.getTargetElement()
+ if (withKeys) {
+ requestFullScreenWithKeys(element)
+ } else {
+ requestFullScreen(element)
+ }
+ isFullScreenRef.value = true
+ }
+ }
+
+ function onHomeClick() {
+ centerMap(mapRef.value.map, center.value, { y: 0, x: 0 }, initialZoom)
+ }
+ function onZoomInClick() {
+ zoomByDelta(1)
+ }
+ function onZoomOutClick() {
+ zoomByDelta(-1)
+ }
+ function onFullScreenClick() {
+ handleFullScreen()
+ }
+
+ return {
+ onHomeClick,
+ onZoomInClick,
+ onZoomOutClick,
+ onFullScreenClick,
+ isFullScreenRef
+ }
+}