跳到主要内容

相机系统

相机(Camera)控制地图的视图,包括中心点、缩放级别和旋转角度。

获取相机

const camera = engine.getCamera();

中心点

设置中心点

// 使用经纬度
camera.setCenterLonLat(116.4074, 39.9042);

// 使用 Web Mercator 坐标(米)
import { Vec2, WebMercatorProjection } from 'mapjar';
const pos = WebMercatorProjection.lonLatToMeters(116.4074, 39.9042);
camera.setCenter(pos);

获取中心点

// 获取经纬度
const lonLat = camera.getCenterLonLat();
console.log(lonLat); // { x: 116.4074, y: 39.9042 }

// 获取 Web Mercator 坐标
const center = camera.getCenter();
console.log(center); // { x: 12958223.5, y: 4825473.6 }

缩放级别

设置缩放级别

// 缩放级别范围:0-22
camera.setZoom(10);

获取缩放级别

const zoom = camera.getZoom();
console.log(zoom); // 10

缩放到指定点

// 以屏幕坐标 (400, 300) 为中心放大 1 级
camera.zoomTo(1, { x: 400, y: 300 });

// 以屏幕中心放大 1 级
camera.zoomTo(1);

带动画的缩放

// 平滑缩放到指定点
camera.animateZoomTo(1, { x: 400, y: 300 }, {
duration: 300, // 动画时长(毫秒)
easing: (t) => t * t, // 缓动函数
});

旋转

设置旋转角度

// 旋转角度(弧度)
camera.setRotation(Math.PI / 4); // 45度

// 重置旋转
engine.resetRotation();

获取旋转角度

const rotation = camera.getRotation();
console.log(rotation); // 0.785 (弧度)
console.log(rotation * 180 / Math.PI); // 45 (度)

启用/禁用旋转

// 在创建地图时配置
const engine = new MapEngine('#map', {
center: [116.4074, 39.9042],
zoom: 10,
enableRotation: true, // 启用右键旋转(默认 true)
});

平移

// 平移指定像素距离
camera.pan(100, 100); // 向右 100px,向下 100px

分辨率

// 获取当前分辨率(米/像素)
const resolution = camera.getResolution();
console.log(resolution); // 152.87 米/像素

视口尺寸

// 获取视口宽度和高度(像素)
const width = camera.getWidth();
const height = camera.getHeight();
console.log(`视口尺寸: ${width}x${height}`);

// 设置视口尺寸(通常由引擎自动管理)
camera.setSize(1920, 1080);

坐标转换

世界坐标转屏幕坐标

import { WebMercatorProjection } from 'mapjar';

// 将经纬度转换为屏幕坐标
const worldPos = WebMercatorProjection.lonLatToMeters(116.4074, 39.9042);
const screenPos = camera.worldToScreen(worldPos);
console.log(screenPos); // { x: 960, y: 540 }

屏幕坐标转世界坐标

// 将屏幕坐标转换为世界坐标
const worldPos = camera.screenToWorld({ x: 960, y: 540 });
const lonLat = WebMercatorProjection.metersToLonLat(worldPos.x, worldPos.y);
console.log(lonLat); // { x: 116.4074, y: 39.9042 }

可见边界

// 获取当前可见的地理边界
const bounds = camera.getVisibleBounds();
console.log(bounds);
// {
// minX: 12900000, // 最小 X(米)
// minY: 4800000, // 最小 Y(米)
// maxX: 13000000, // 最大 X(米)
// maxY: 4900000 // 最大 Y(米)
// }

平滑动画

flyTo - 飞行到指定位置

// 飞行到上海,缩放到 12 级
camera.flyTo(121.4737, 31.2304, 12, {
duration: 2000, // 动画时长(毫秒),默认自动计算
maxDuration: 3000, // 最大时长(毫秒),默认 3000
});

// 只改变位置,保持当前缩放
camera.flyTo(121.4737, 31.2304);

// 使用 MapEngine 的快捷方法
engine.flyTo(121.4737, 31.2304, 12, { duration: 2000 });

fitBounds - 适配边界

// 适配中国边界
camera.fitBounds({
minLon: 73.5,
minLat: 18.2,
maxLon: 135.0,
maxLat: 53.5
}, {
duration: 2000, // 动画时长
padding: 50, // 边界填充(像素)
});

// 使用 MapEngine 的快捷方法
engine.fitBounds({
minLon: 73.5,
minLat: 18.2,
maxLon: 135.0,
maxLat: 53.5
}, {
duration: 2000,
padding: 50,
});

动画控制

// 停止当前动画
camera.stopAnimation();

// 检查是否有动画正在运行
const hasAnimation = camera.updateAnimation();
console.log(hasAnimation); // true 或 false

高 DPI 支持

Mapjar 自动适配高分辨率屏幕(Retina 等):

// 获取设备像素比
const dpr = camera.getDevicePixelRatio();
console.log(dpr); // 1, 2, 或 3

// 手动设置设备像素比(通常不需要)
camera.setDevicePixelRatio(2);

// 在 MapEngine 中设置
const engine = new MapEngine('#map', {
center: [116.4074, 39.9042],
zoom: 10,
devicePixelRatio: 2, // 手动指定
});

// 或使用引擎方法
engine.setDevicePixelRatio(2);

视图矩阵

// 获取视图矩阵(用于 WebGL 渲染)
const viewMatrix = camera.getViewMatrix();
console.log(viewMatrix); // Float32Array(16)

实用示例

点击地图获取经纬度

engine.on('click', (event) => {
console.log(`点击位置: ${event.lon.toFixed(4)}, ${event.lat.toFixed(4)}`);
});

鼠标位置实时显示

const coordDisplay = document.getElementById('coords');

engine.on('mousemove', (event) => {
coordDisplay.textContent =
`经度: ${event.lon.toFixed(4)}, 纬度: ${event.lat.toFixed(4)}`;
});

限制地图范围

const camera = engine.getCamera();

// 在每次相机更新后检查边界
function constrainView() {
const center = camera.getCenterLonLat();

// 限制在中国范围内
const minLon = 73.5, maxLon = 135.0;
const minLat = 18.2, maxLat = 53.5;

let newLon = center.x;
let newLat = center.y;

if (newLon < minLon) newLon = minLon;
if (newLon > maxLon) newLon = maxLon;
if (newLat < minLat) newLat = minLat;
if (newLat > maxLat) newLat = maxLat;

if (newLon !== center.x || newLat !== center.y) {
camera.setCenterLonLat(newLon, newLat);
}
}

// 在渲染循环中调用
// constrainView();

下一步