---
name: "Map"
mode: "component"
versionRequirements:
  - { name: "@ray-js/ray", version: "0.6.9" }
  - { name: "Base library", version: "2.0.12" }
  - { name: "MapKit", version: "2.2.2" }
title: "Map - Map"
---

## Map

> [VERSION] @ray-js/ray >= 0.6.9 | Base library >= 2.0.12 | MapKit >= 2.2.2

### Description

Map component: On real devices in mainland China, it uses AMap; overseas, it uses Google Maps. In Tuya MiniApp IDE and the online preview, it is simulated via WebView and may differ from real devices. Use real-device behavior as the reference.

### Props

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `longitude` | `number` | No | - | Center longitude |
| `latitude` | `number` | No | - | Center latitude |
| `scale` | `number` | No | `16` | Zoom level, range 4–19 |
| `minScale` | `number` | No | `4` | Minimum zoom level |
| `maxScale` | `number` | No | `19` | Maximum zoom level |
| `disableRotate` | `boolean` | No | - | Whether to disable rotation; defaults to false |
| `markers` | `MapMarker[]` | No | - | Marker |
| `polyline` | `MapPolyline[]` | No | - | Route |
| `circles` | `MapCircle[]` | No | - | Circle |
| `polygons` | `MapPolygon[]` | No | - | Polygon |
| `borderWidth` | `number` | No | `0` | Border width, in px |
| `borderStyle` | `"solid" \| "dashed"` | No | `"solid"` | Border style |
| `borderColor` | `string` | No | `"#ffffff"` | Border color, must be hex format |
| `borderRadius` | `number` | No | `0` | Border radius, in px |
| `borderRadiusTopLeft` | `number` | No | - | Top-left border radius, in px |
| `borderRadiusTopRight` | `number` | No | - | Top-right border radius, in px |
| `borderRadiusBottomLeft` | `number` | No | - | Bottom-left border radius, in px |
| `borderRadiusBottomRight` | `number` | No | - | Bottom-right border radius, in px |
| `backgroundColor` | `string` | No | `"#ffffff"` | Background color, must be hex format |
| `onMarkertap` | `(event: MapMarkertapEvent) => void` | No | - | Triggered when a marker is tapped |
| `onCallouttap` | `(event: MapCallouttapEvent) => void` | No | - | Triggered when the marker’s callout is tapped |
| `onRegionchange` | `(event: MapRegionchangeEvent) => void` | No | - | Triggered when the viewport changes |
| `onInitdone` | `(event: MapInitdoneEvent) => void` | No | - | Triggered when initialization completes |
| `updateLayout` | `unknown` | No | - | Used for cross-layer components to notify the container layer to update styles |

### Referenced Types

##### `interface` MapMarker

| Property | Type | Description |
| --- | --- | --- |
| `id` | `number` | Marker ID |
| `longitude` | `number` | Longitude |
| `latitude` | `number` | Latitude |
| `title` | `string` | Marker name |
| `styleId` | `string` | Callout style type ID |
| `callout` | `MapCallout` | Callout above the marker |
| `iconPath` | `string` | Icon path |
| `rotate` | `number` | Rotation angle |
| `width` | `number \| string` | Marker icon width |
| `height` | `number \| string` | Marker icon height |

##### `interface` MapPolyline

| Property | Type | Description |
| --- | --- | --- |
| `points` | `MapPoint[]` | Latitude/longitude array |
| `color` | `string` | Line color (hex) |
| `width` | `number` | Line width |
| `dottedLine` | `boolean` | Whether dashed |

##### `interface` MapCircle

| Property | Type | Description |
| --- | --- | --- |
| `latitude` | `number` | Latitude |
| `longitude` | `number` | Longitude |
| `color` | `string` | Stroke color (hex) |
| `fillColor` | `string` | Fill color (hex) |
| `radius` | `number` | Radius |
| `strokeWidth` | `number` | Stroke width |

##### `interface` MapPolygon

| Property | Type | Description |
| --- | --- | --- |
| `points` | `MapPoint[]` | Latitude/longitude array |
| `strokeColor` | `string` | Stroke color |
| `fillColor` | `string` | Fill color |
| `strokeWidth` | `number` | Stroke width |

##### `interface` MapMarkertapEvent

| Property | Type | Description |
| --- | --- | --- |
| `detail` | `MapMarkerIdDetail` | Event detail data |

##### `interface` MapCallouttapEvent

| Property | Type | Description |
| --- | --- | --- |
| `detail` | `MapMarkerIdDetail` | Event detail data |

##### `interface` MapRegionchangeEvent

| Property | Type | Description |
| --- | --- | --- |
| `detail` | `MapRegionChangeDetail` | Event detail data |

##### `interface` MapInitdoneEvent

```typescript
export interface MapInitdoneEvent extends BaseEvent {
  /** 事件类型 */
  type: 'initdone';
}
```

##### `interface` MapCallout

| Property | Type | Description |
| --- | --- | --- |
| `content` | `string` | Text |
| `color` | `string` | Text color |
| `fontSize` | `number` | Font size |
| `borderRadius` | `number` | Border radius |
| `borderWidth` | `number` | Border width |
| `borderColor` | `string` | Border color |
| `bgColor` | `string` | Background color |
| `padding` | `number` | Text padding |
| `textAlign` | `"left" \| "right" \| "center"` | Text alignment |
| `anchorX` | `number` | Horizontal offset; positive to the right |
| `anchorY` | `number` | Vertical offset; positive downward |

##### `interface` MapMarkerIdDetail

| Property | Type | Description |
| --- | --- | --- |
| `markerId` | `number` | Marker ID |

##### `interface` BaseEvent

| Property | Type | Description |
| --- | --- | --- |
| `type` | `string` | Event type |
| `timeStamp` | `number` | Time in milliseconds since the page opened |
| `target` | `Target` | Source component of the event |
| `currentTarget` | `Target` | Collection of property values for the current component |
| `mark` | `any` | Event mark data |

##### `interface` MapRegionChangeDetail

| Property | Type | Description |
| --- | --- | --- |
| `type` | `"begin" \| "end"` | Change type |
| `causedBy` | `string` | Causes of viewport changes |

##### `interface` Target

| Property | Type | Description |
| --- | --- | --- |
| `id` | `string` | id of the event source component |
| `dataset` | `Record<string, unknown>` | Collection of custom attributes from the `dataset` on the event source component |

##### `type` MapPoint

| Property | Type | Description |
| --- | --- | --- |
| `latitude` | `number` | Latitude |
| `longitude` | `number` | Longitude |


### Examples

#### Basic usage

```tsx
import React from 'react';
import { Map, View } from '@ray-js/ray';
export default function () {
  return (
    <View style={{ padding: '20px' }}>
      <Map
        longitude={116.397428}
        latitude={39.90923}
        scale={16}
        style={{ width: '100%', height: '300px' }}
      />
    </View>
  );
}
```

#### Markers and callouts

```tsx
import React from 'react';
import { Map, View, Text } from '@ray-js/ray';

export default function () {
  const markers = [
    {
      id: 1,
      longitude: 116.397428,
      latitude: 39.90923,
      title: 'Tiananmen',
      iconPath: '/images/marker.png',
      width: 30,
      height: 30,
      callout: {
        content: 'Tiananmen Square',
        color: '#333',
        fontSize: 14,
        bgColor: '#fff',
        borderRadius: 4,
        padding: 8,
        textAlign: 'center',
      },
    },
    {
      id: 2,
      longitude: 116.407428,
      latitude: 39.91523,
      title: 'Forbidden City',
      iconPath: '/images/marker.png',
      width: 30,
      height: 30,
    },
  ];

  return (
    <View style={{ padding: '20px' }}>
      <Map
        longitude={116.397428}
        latitude={39.90923}
        scale={14}
        minScale={10}
        maxScale={18}
        markers={markers}
        style={{ width: '100%', height: '300px' }}
        onMarkertap={(e) => console.log('Marker:', e.detail.markerId)}
        onCallouttap={(e) => console.log('Callout:', e.detail.markerId)}
        onInitdone={() => console.log('Map initialized')}
      />
    </View>
  );
}
```

#### Routes and overlays

```tsx
import React from 'react';
import { Map, View } from '@ray-js/ray';

export default function () {
  const polyline = [
    {
      points: [
        { latitude: 39.90923, longitude: 116.397428 },
        { latitude: 39.91523, longitude: 116.407428 },
        { latitude: 39.92023, longitude: 116.417428 },
      ],
      color: '#1890ff',
      width: 4,
      dottedLine: false,
    },
  ];

  const circles = [
    {
      latitude: 39.90923,
      longitude: 116.397428,
      radius: 500,
      color: '#1890ff80',
      fillColor: '#1890ff20',
      strokeWidth: 2,
    },
  ];

  const polygons = [
    {
      points: [
        { latitude: 39.91, longitude: 116.40 },
        { latitude: 39.92, longitude: 116.41 },
        { latitude: 39.91, longitude: 116.42 },
      ],
      strokeColor: '#ff4d4f',
      fillColor: '#ff4d4f20',
      strokeWidth: 2,
    },
  ];

  return (
    <View style={{ padding: '20px' }}>
      <Map
        longitude={116.407428}
        latitude={39.91523}
        scale={13}
        polyline={polyline}
        circles={circles}
        polygons={polygons}
        borderRadius={12}
        style={{ width: '100%', height: '300px' }}
        onRegionchange={(e) => console.log('Region change:', e.detail.type)}
      />
    </View>
  );
}
```


### Related Links

Related API: [createMapContext](/en/miniapp/develop/miniapp/api/media/map/createMapContext). This is a native component based on off-screen rendering. Please note the [native component usage restrictions](/en/miniapp/develop/miniapp/component/native-component/native-component).

<DemoBlock 
  githubUrl="https://github.com/Tuya-Community/tuya-miniapp-demo/tree/master/rayMap" 
  qrCodeUrl="/images/qrCode/rayMap.png" 
  lang="en">
</DemoBlock>

### FAQ

1. The latitude and longitude of the map component are required. If not provided, Beijing's coordinates are used as default values.
2. The Tuya MiniApp IDE simulates the map via WebView, which differs from behavior on a real device. Please use the real device result as the reference.
3. For related principles, refer to [Native components based on off-screen rendering](/en/miniapp/develop/miniapp/component/native-component/native-component).
4. Please note the [native component usage restrictions](/en/miniapp/develop/miniapp/component/native-component/native-component).
