You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

49 lines
2.5 KiB

1 day ago
/* ---- 通用确认 / 未保存三选(主 demo <dialog> 版;「关闭」按钮由 dlgOpen 追加,等同继续编辑) ---- */
function gConfirm(title, text, onOk) {
dlgOpen(title, '<div style="line-height:1.7">' + text + '</div>', [
{ text: '取消', fn: () => dlgClose() },
{ text: '确定', ok: true, fn: () => { dlgClose(); onOk(); } }
]);
}
function gUnsavedDlg(handlers) {
dlgOpen('未保存提醒', '<div style="line-height:1.7">您有未保存的更改,请选择后续操作:</div>', [
{ text: '继续编辑', fn: () => dlgClose() },
{ text: '放弃修改', fn: () => { dlgClose(); handlers.discard(); } },
{ text: '保存修改', ok: true, fn: () => { dlgClose(); handlers.save(); } }
]);
}
/* ---- 画布变换(平移 / 缩放 / 适应) ---- */
function applyTransform() {
canvasInner.style.transform = 'translate(' + G.view.panX + 'px,' + G.view.panY + 'px) scale(' + G.view.zoom + ')';
$('zoomLabel').textContent = Math.round(G.view.zoom * 100) + '%';
}
function toCanvas(cx, cy) {
const r = wrap.getBoundingClientRect();
return { x: (cx - r.left - G.view.panX) / G.view.zoom, y: (cy - r.top - G.view.panY) / G.view.zoom };
}
function zoomAt(factor, anchorClientX, anchorClientY) {
const old = G.view.zoom;
const nz = Math.max(0.3, Math.min(2, old * factor));
if (nz === old) return;
const r = wrap.getBoundingClientRect();
const ax = (anchorClientX == null ? r.width / 2 : anchorClientX - r.left);
const ay = (anchorClientY == null ? r.height / 2 : anchorClientY - r.top);
G.view.panX = ax - (ax - G.view.panX) * (nz / old);
G.view.panY = ay - (ay - G.view.panY) * (nz / old);
G.view.zoom = nz; applyTransform();
}
function fitView() {
if (!G.contacts.length) { applyTransform(); return; }
const xs = G.contacts.map(c => (G.cardPos[c.id] || { x: 0 }).x).concat([COMPANY_POS.x]);
const ys = G.contacts.map(c => (G.cardPos[c.id] || { y: 0 }).y).concat([COMPANY_POS.y]);
const minX = Math.min.apply(null, xs), maxX = Math.max.apply(null, xs) + CARD_W;
const minY = Math.min.apply(null, ys), maxY = Math.max.apply(null, ys) + CARD_H;
const zone = $('unrecZone');
const zoneBottom = zone.offsetTop + zone.offsetHeight;
const wr = wrap.getBoundingClientRect();
const bw = maxX - minX, bh = Math.max(maxY, zoneBottom) - minY;
G.view.zoom = Math.max(0.3, Math.min(2, Math.min((wr.width - 50) / bw, (wr.height - 50) / bh)));
G.view.panX = (wr.width - bw * G.view.zoom) / 2 - minX * G.view.zoom;
G.view.panY = (wr.height - bh * G.view.zoom) / 2 - minY * G.view.zoom;
applyTransform();
}