| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- /**
- * 跨 ±180 经线真机复验:维护者反馈「到达经度 0 的区域时会抽搐后旋转一周到达另一边」。
- * 在真机上把中心移到 179.x,再连续东西向拖拽跨过 180,观察经度是否绕远路。
- *
- * 运行(需先起 `yarn dev`):node .scratch/cockpit-shell-panel-layout/verify/t03-antimeridian-walkthrough.mjs
- */
- import { join } from 'node:path'
- import { tmpdir } from 'node:os'
- const BASE = process.env.COCKPIT_BASE || 'http://localhost:8000'
- const CHROME = process.env.CHROME_PATH || 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'
- const PUPPETEER = 'file:///C:/Users/ASUS/.dsh/profiles/desktop/node_modules/puppeteer-core/lib/puppeteer/puppeteer-core.js'
- const puppeteer = (await import(PUPPETEER)).default
- const browser = await puppeteer.launch({
- executablePath: CHROME,
- headless: true,
- userDataDir: join(tmpdir(), 'cockpit-t03-am-profile'),
- defaultViewport: { width: 1680, height: 950 },
- args: ['--no-sandbox', '--disable-dev-shm-usage', '--no-first-run'],
- })
- const sleep = (ms) => new Promise((r) => setTimeout(r, ms))
- const shortest = (a, b) => ((b - a + 540) % 360) - 180
- try {
- const page = await browser.newPage()
- const errors = []
- page.on('pageerror', (e) => errors.push(String((e && e.message) || e)))
- await page.goto(`${BASE}/#/cockpit`, { waitUntil: 'networkidle2', timeout: 60000 })
- await page.waitForSelector('.cockpit-shell', { timeout: 20000 })
- await page.waitForFunction(() => !!window.__cockpitMap, { timeout: 30000 })
- await page
- .waitForFunction(() => document.querySelector('.cockpit-shell__map .map-canvas')?.dataset.mapEngine === 'ready', {
- timeout: 60000,
- })
- .catch(() => {})
- await sleep(1000)
- const read = () =>
- page.evaluate(() => {
- const s = window.__cockpitMap.getCameraState()
- return { pivot: s.pivot, shown: s.shownPivot, hpr: s.hpr, settled: s.settled }
- })
- // 让相机离地面近一点,跨经线的步长才不至于一次跳过大半圈。
- await page.evaluate(() => window.__cockpitMap.setCameraDamping(110))
- await page.evaluate(() => window.__cockpitMap.setCameraFocus({ lon: 179.0, lat: 10 }))
- await page.waitForFunction(() => window.__cockpitMap.getCameraState().settled === true, { timeout: 5000 }).catch(() => {})
- await sleep(600)
- const before = await read()
- console.log('起点:', JSON.stringify({ pivot: before.pivot, r: Math.round(before.hpr.range) }))
- const canvasCenter = await page.evaluate(() => {
- const b = document.querySelector('.cockpit-shell__map .map-canvas').getBoundingClientRect()
- return { x: b.x + b.width / 2, y: b.y + b.height / 2 }
- })
- // 连续向右拖(抓着地图拖 → 中心西移 → 经度增大,会跨过 ±180)。
- const lons = []
- await page.mouse.move(canvasCenter.x, canvasCenter.y)
- await page.mouse.down({ button: 'left' })
- for (let i = 1; i <= 10; i += 1) {
- await page.mouse.move(canvasCenter.x - i * 60, canvasCenter.y, { steps: 3 })
- await sleep(60)
- const s = await read()
- lons.push(s.pivot.lon)
- }
- await page.mouse.up({ button: 'left' })
- await sleep(1200)
- // 解缠:从**起点**开始按最短弧累加,得出真实走过的经度总量。
- // 关键判据:若跨 ±180 走了长边,单步增量会接近 ±360 的整数倍,且方向会翻转。
- const track = [before.pivot.lon, ...lons]
- let acc = 0
- const arc = [0]
- for (let i = 1; i < track.length; i += 1) {
- acc += shortest(track[i - 1], track[i])
- arc.push(acc)
- }
- console.log('落点经度:', lons.map((v) => v.toFixed(3)).join(' → '))
- console.log('弧长累加:', arc.map((v) => v.toFixed(3)).join(' → '))
- console.log('总弧长 °:', arc[arc.length - 1].toFixed(3), '(应与拖拽量级相符,不是 ±360 的整数倍)')
- console.log('单调推进:', arc.every((v, i) => i === 0 || v >= arc[i - 1] - 1e-9))
- const overshoot = Math.abs(acc - shortest(track[0], track[track.length - 1]))
- console.log('与首尾最短弧之差 °:', overshoot.toFixed(3), '(≈0 说明全程没绕远路)')
- console.log('终点:', JSON.stringify(await read()))
- console.log('页面报错:', errors.length ? errors.slice(0, 3).join(' | ') : '(无)')
- } finally {
- await browser.close()
- }
|