Skip to content

Commit

Permalink
feat: 输入点坐标
Browse files Browse the repository at this point in the history
  • Loading branch information
army8735 committed Jan 13, 2025
1 parent b0c6bcf commit ed78366
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 14 deletions.
149 changes: 136 additions & 13 deletions src/control/PointPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { CURVE_MODE } from '../style/define';
import { Point } from '../format';
import { clone } from '../util/type';
import PointCommand from '../history/PointCommand';
import { getPointsDspCoords } from '../tools/polyline';
import { getPointsAbsByDsp, getPointsDspCoords } from '../tools/polyline';
import { toPrecision } from '../math';

const html = `
Expand Down Expand Up @@ -43,10 +43,15 @@ const html = `
class PointPanel extends Panel {
panel: HTMLElement;
node?: Polyline | ShapeGroup;
xs: number[];
ys: number[];

constructor(root: Root, dom: HTMLElement, listener: Listener) {
super(root, dom, listener);

this.xs = [];
this.ys = [];

const panel = this.panel = document.createElement('div');
panel.className = 'point-panel';
panel.style.display = 'none';
Expand Down Expand Up @@ -126,12 +131,138 @@ class PointPanel extends Panel {
listener.geometry.keep = true;
});

let prevPoint: Point[] = [];
const onChange = () => {
listener.geometry.update();
const node = this.node;
if (node instanceof Polyline) {
listener.history.addCommand(new PointCommand([node], [{
prev: prevPoint.slice(0),
next: clone(node.props.points),
}]));
prevPoint.splice(0);
}
};

const x = panel.querySelector('input.x') as HTMLInputElement;
const y = panel.querySelector('input.y') as HTMLInputElement;

const onInputCoords = (e: Event, isX = true) => {
const node = this.node;
if (!node) {
return;
}
const value = parseFloat(isX ? x.value : y.value) || 0;
const isInput = e instanceof InputEvent; // 上下键还是真正输入
const isFirst = !prevPoint.length;
if (isFirst) {
if (node instanceof Polyline) {
prevPoint = clone(node.props.points);
}
}
if (node instanceof Polyline) {
let points = node.props.points;
// 激活的顶点或者全部
if (listener.geometry.idx.length) {
points = listener.geometry.idx.map(i => points[i]);
}
const arr = isX ? this.xs : this.ys;
listener.geometry.idx.forEach((item, i) => {
if (isInput) {
arr[i] = value;
if (!i) {
if (isX) {
x.placeholder = '';
}
else {
y.placeholder = '';
}
}
}
else {
let d = 0;
if (isX) {
if (x.placeholder) {
d = value;
}
else {
d = value - arr[i];
}
}
else {
if (y.placeholder) {
d = value;
}
else {
d = value - arr[i];
}
}
if (listener.shiftKey) {
if (d > 0) {
d = 10;
}
else {
d = -10;
}
}
else if (listener.altKey) {
if (d > 0) {
d = 0.1;
}
else {
d = -0.1;
}
}
arr[i] += d;
if (!i) {
if (isX) {
if (x.placeholder) {
x.value = '';
}
else {
x.value = toPrecision(arr[i]).toString();
}
}
else {
if (y.placeholder) {
y.value = '';
}
else {
y.value = toPrecision(arr[i]).toString();
}
}
}
}
});
const dsp = arr.map((item, i) => {
return { x: this.xs[i], y: this.ys[i] };
});
const abs = getPointsAbsByDsp(node, dsp);
const { width, height } = node;
points.forEach((item, i) => {
item.absX = abs[i].x;
item.absY = abs[i].y;
item.x = item.absX / width;
item.y = item.absY / height;
});
}
node.refresh();
listener.geometry.updateVertex(node);
listener.emit(Listener.POINT_NODE, [node]);
};

x.addEventListener('input', (e) => {
onInputCoords(e, true);
});
x.addEventListener('change', onChange);

y.addEventListener('input', (e) => {
onInputCoords(e, false);
});
y.addEventListener('change', onChange);

const range = panel.querySelector('input[type="range"]') as HTMLInputElement;
const number = panel.querySelector('input.r') as HTMLInputElement;
let prevPoint: Point[] = [];

range.addEventListener('input', (e) => {
const node = this.node;
Expand Down Expand Up @@ -160,16 +291,6 @@ class PointPanel extends Panel {
listener.geometry.updateVertex(node);
listener.emit(Listener.POINT_NODE, [node]);
});
const onChange = () => {
listener.geometry.update();
const node = this.node;
if (node instanceof Polyline) {
listener.history.addCommand(new PointCommand([node], [{
prev: prevPoint.slice(0),
next: clone(node.props.points),
}]));
}
};
range.addEventListener('change', onChange);

number.addEventListener('input', (e) => {
Expand Down Expand Up @@ -228,7 +349,7 @@ class PointPanel extends Panel {
number.value = '';
}
else {
number.value = item.cornerRadius.toString();
number.value = toPrecision(item.cornerRadius).toString();
}
}
}
Expand Down Expand Up @@ -339,6 +460,8 @@ class PointPanel extends Panel {
else {
y.value = toPrecision(ys[0]).toString();
}
this.xs = xs;
this.ys = ys;
}

updateRange(idx: number[]) {
Expand Down
16 changes: 15 additions & 1 deletion src/tools/polyline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as uuid from 'uuid';
import { Point } from '../format';
import Polyline from '../node/geom/Polyline';
import { CORNER_STYLE, CURVE_MODE, POINTS_RADIUS_BEHAVIOUR } from '../style/define';
import { calPoint } from '../math/matrix';
import { calPoint, inverse4 } from '../math/matrix';
import { pointInRect } from '../math/geom';
import { getBaseCoords, getBasicMatrix } from './node';

Expand Down Expand Up @@ -449,7 +449,21 @@ export function getPointsDspCoords(node: Polyline, points?: Point[]) {
});
}

export function getPointsAbsByDsp(node: Polyline, points: { x: number, y: number }[]) {
const m = getBasicMatrix(node);
const i = inverse4(m);
const { baseX, baseY } = getBaseCoords(node);
return points.map(item => {
const p = calPoint({ x: item.x + baseX, y: item.y + baseY }, i);
return {
x: p.x,
y: p.y,
};
});
}

export default {
getFrameVertexes,
getPointsDspCoords,
getPointsAbsByDsp,
};

0 comments on commit ed78366

Please sign in to comment.