map / src /cityMapBookLayout.js
潘昌伟
Lower Beijing base map bookmark
0f6d037
Raw
History Blame Contribute Delete
7.99 kB
export const CITY_MAP_BOOK_TOP_FORBIDDEN_BOTTOM = 32;
export const CITY_MAP_BOOK_BOTTOM_FORBIDDEN_TOP_OFFSET = 56;
export const CITY_MAP_BOOK_SAFE_HEIGHT = 264;
export const CITY_MAP_BOOK_HOVER_SAFE_SCALE = 1.055;
export const CITY_MAP_BOOK_FORBIDDEN_GAP = 2;
export const CITY_MAP_SPECIAL_BOOK_LAYOUTS = {
shanghai: {
minWidth: 1200,
marginX: 64,
marginY: 132,
slots: {
"chn-shanghai--douban-25924323": { x: 0.1143, y: 0.4341 },
"chn-shanghai--manual-xinhualu": { x: 0.2254, y: 0.2208 },
"chn-shanghai--map-shanghai-1947-hanghao": { x: 0.3516, y: 0.2208 },
"chn-shanghai--douban-35299337": { x: 0.478, y: 0.18 },
"chn-shanghai--douban-20495120": { x: 0.6006, y: 0.2208 },
"chn-shanghai--manual-jiangnan-shanghai-gardens": { x: 0.7253, y: 0.2208 },
"chn-shanghai--douban-35408305": { x: 0.8568, y: 0.3114 },
"chn-shanghai--douban-36362358": { x: 0.2703, y: 0.7578, offsetY: 5 },
"chn-shanghai--douban-37442766": { x: 0.3944, y: 0.8185 },
"chn-shanghai--douban-36952719": { x: 0.6121, y: 0.8158 },
"chn-shanghai--douban-30254263": { x: 0.7253, y: 0.8168 },
"chn-shanghai--douban-26849413": { x: 0.8371, y: 0.7864, offsetY: -25 },
"chn-shanghai--douban-7055710": { x: 0.9499, y: 0.6581, offsetX: -5 },
},
},
beijing: {
minWidth: 1200,
marginX: 88,
marginY: 132,
safeHeight: 264,
hoverSafeScale: CITY_MAP_BOOK_HOVER_SAFE_SCALE,
topForbiddenBottom: 32,
topSafeGap: CITY_MAP_BOOK_FORBIDDEN_GAP,
bottomForbiddenTopOffset: 66,
slots: {
"chn-beijing--douban-1070711": { x: 0.075, y: 0.2786 },
"chn-beijing--douban-36159853": { x: 0.1964, y: 0.2521 },
"chn-beijing--homeshop-wear": { x: 0.3182, y: 0.2396 },
"chn-beijing--douban-37508268": { x: 0.4393, y: 0.322 },
"chn-beijing--douban-25751679": { x: 0.5604, y: 0.2869 },
"chn-beijing--douban-37131044": { x: 0.6817, y: 0.2744 },
"chn-beijing--douban-35279673": { x: 0.8036, y: 0.2883 },
"chn-beijing--douban-34995523": { x: 0.92, y: 0.3858, offsetY: -40 },
"chn-beijing--douban-30116399": { x: 0.075, y: 0.6643 },
"chn-beijing--douban-33395164": { x: 0.22, y: 0.7893 },
"chn-beijing--douban-30469133": { x: 0.36, y: 0.8257 },
"chn-beijing--douban-34991723": { x: 0.5, y: 0.8186 },
"chn-beijing--douban-37134106": { x: 0.64, y: 0.8247 },
"chn-beijing--isbn-9787540265052": { x: 0.7798, y: 0.7893 },
"chn-beijing--douban-26580056": { x: 0.92, y: 0.7893 },
},
},
tokyo: {
minWidth: 1200,
marginX: 88,
marginY: 132,
safeHeight: 264,
hoverSafeScale: CITY_MAP_BOOK_HOVER_SAFE_SCALE,
topForbiddenBottom: 32,
topSafeGap: CITY_MAP_BOOK_FORBIDDEN_GAP,
bottomForbiddenTopOffset: 66,
slots: {
"jpn-tokyo--douban-35928183": { x: 0.1508, y: 0.2744 },
"jpn-tokyo--douban-30438342": { x: 0.262, y: 0.2396 },
"jpn-tokyo--external-tsukuda-tsukishima-magazine": { x: 0.3831, y: 0.2396 },
"jpn-tokyo--map-qchizu-tokyo-3000": { x: 0.4952, y: 0.2396 },
"jpn-tokyo--douban-36448234": { x: 0.6385, y: 0.2396 },
"jpn-tokyo--douban-24720958": { x: 0.7691, y: 0.2883 },
"jpn-tokyo--douban-26819477": { x: 0.8639, y: 0.2883 },
"jpn-tokyo--douban-34950394": { x: 0.1446, y: 0.7503 },
"jpn-tokyo--douban-26945179": { x: 0.2573, y: 0.8134 },
"jpn-tokyo--douban-36096287": { x: 0.3745, y: 0.8069 },
"jpn-tokyo--douban-37090707": { x: 0.6924, y: 0.8045 },
"jpn-tokyo--douban-2389079": { x: 0.8056, y: 0.7337 },
"jpn-tokyo--douban-34663226": { x: 0.5703, y: 0.7995 },
},
},
"new-york": {
minWidth: 1200,
marginX: 88,
marginY: 132,
safeHeight: 245,
slots: {
"usa-new-york-city--douban-37199094": { x: 0.0747, y: 0.273 },
"usa-new-york-city--douban-36889885": { x: 0.1885, y: 0.2451 },
"usa-new-york-city--douban-35687602": { x: 0.3022, y: 0.273 },
"usa-new-york-city--map-mapping-historical-ny": { x: 0.4299, y: 0.2228 },
"usa-new-york-city--douban-37281194": { x: 0.6118, y: 0.2646 },
"usa-new-york-city--douban-30201329": { x: 0.086, y: 0.7159 },
"usa-new-york-city--douban-6124372": { x: 0.205, y: 0.7368 },
"usa-new-york-city--douban-30441545": { x: 0.3241, y: 0.7159 },
"usa-new-york-city--external-celluloid-skyline": { x: 0.4828, y: 0.7368 },
"usa-new-york-city--douban-35013441": { x: 0.5952, y: 0.7159 },
"usa-new-york-city--douban-35740229": { x: 0.7077, y: 0.7368 },
"usa-new-york-city--douban-26818878": { x: 0.8201, y: 0.7159 },
"usa-new-york-city--douban-1913467": { x: 0.9325, y: 0.7368 },
"usa-new-york-city--douban-27037182": { x: 0.787, y: 0.3203 },
},
},
"hong-kong": {
minWidth: 1200,
marginX: 88,
marginY: 132,
slots: {
"chn-hong-kong--douban-36024491": { x: 0.119, y: 0.2354, offsetX: 40 },
"chn-hong-kong--manual-zhenzhong-hk": { x: 0.2639, y: 0.2549, offsetX: 40 },
"chn-hong-kong--manual-hong-kong-guide-2014": { x: 0.4944, y: 0.18, offsetX: -40, offsetY: -10 },
"chn-hong-kong--douban-27004436": { x: 0.69, y: 0.357, offsetY: -60 },
"chn-hong-kong--manual-power-generation-urban-renewal": { x: 0.805, y: 0.357, offsetY: -60 },
"chn-hong-kong--douban-30279653": { x: 0.075, y: 0.66 },
"chn-hong-kong--douban-35452941": { x: 0.1992, y: 0.765 },
"chn-hong-kong--manual-diwenzhi": { x: 0.3233, y: 0.765 },
"chn-hong-kong--douban-36285315": { x: 0.4475, y: 0.765 },
"chn-hong-kong--manual-xiangtu-hongkong": { x: 0.5717, y: 0.765 },
"chn-hong-kong--external-sham-shui-po-101": { x: 0.6958, y: 0.765 },
"chn-hong-kong--external-wanchai-wak-dongnin": { x: 0.82, y: 0.715 },
"chn-hong-kong--douban-27136081": { x: 0.92, y: 0.385 },
},
},
};
export function hasCompleteCityMapSpecialBookLayout(special, entries = []) {
const layout = CITY_MAP_SPECIAL_BOOK_LAYOUTS[special?.id];
if (!layout || !entries.length) return false;
return entries.every((entry) => Boolean(layout.slots?.[entry?.book?.id]));
}
export function applyCityMapSpecialBookLayout(special, entries, points, stageRect) {
const layout = CITY_MAP_SPECIAL_BOOK_LAYOUTS[special?.id];
if (!layout || stageRect.width < (layout.minWidth || 0)) return points;
const minCenterY = cityMapBookMinCenterY(layout);
const maxCenterY = cityMapBookMaxCenterY(layout, stageRect, minCenterY);
return points.map((point, index) => {
const bookId = entries[index]?.book?.id;
const slot = layout.slots[bookId];
if (!slot) return point;
const marginX = layout.marginX ?? 72;
const marginY = layout.marginY ?? 96;
return {
...point,
x: clamp(stageRect.width * slot.x, marginX, Math.max(marginX, stageRect.width - marginX)) + (slot.offsetX ?? 0),
y: clamp(stageRect.height * slot.y, Math.max(marginY, minCenterY), maxCenterY) + (slot.offsetY ?? 0),
};
});
}
export function cityMapBookTopForbiddenBottom(special) {
const layout = CITY_MAP_SPECIAL_BOOK_LAYOUTS[special?.id];
return layout?.topForbiddenBottom ?? CITY_MAP_BOOK_TOP_FORBIDDEN_BOTTOM;
}
function cityMapBookMinCenterY(layout) {
const topForbiddenBottom = layout.topForbiddenBottom ?? CITY_MAP_BOOK_TOP_FORBIDDEN_BOTTOM;
const safeHeight = layout.safeHeight ?? CITY_MAP_BOOK_SAFE_HEIGHT;
const hoverSafeScale = layout.hoverSafeScale ?? 1;
const topSafeGap = layout.topSafeGap ?? 0;
return topForbiddenBottom + (safeHeight * hoverSafeScale) / 2 + topSafeGap;
}
function cityMapBookMaxCenterY(layout, stageRect, minCenterY) {
const bottomOffset = layout.bottomForbiddenTopOffset ?? CITY_MAP_BOOK_BOTTOM_FORBIDDEN_TOP_OFFSET;
const safeHeight = layout.safeHeight ?? CITY_MAP_BOOK_SAFE_HEIGHT;
const bottomForbiddenTop = stageRect.height - bottomOffset;
return Math.max(minCenterY, bottomForbiddenTop - safeHeight / 2);
}
function clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}