| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- import { Transform } from "konva/lib/Util";
- import { Pos, Size } from "../utils/math.ts";
- import { alignPortMat } from "@/utils/align-port.ts";
- import mitt from "mitt";
- import { IRect } from "konva/lib/types";
- import { MathUtils } from "three";
- export class Viewer {
- size?: Size;
- sizeMat: Transform | null;
- viewSize?: Size
- viewMat: Transform;
- bus = mitt<{ transformChange: Transform, viewSizeChange: void }>();
- constructor() {
- this.viewMat = new Transform();
- this.sizeMat = null
- }
- setSize(size: Size) {
- this.size = size;
- this.updateSizeMat()
- }
- setViewSize(size?: Size) {
- this.viewSize = size
- this.updateSizeMat()
- }
- updateSizeMat() {
- if (!this.size || !this.viewSize) {
- this.sizeMat = null
- } else {
- const diffw = this.size.width - this.viewSize.width
- const diffh = this.size.height - this.viewSize.height
- this.sizeMat = new Transform().translate(diffw / 2, diffh / 2)
- }
- this.bus.emit("transformChange", this.transform);
- this.bus.emit('viewSizeChange')
- }
- setBound({
- targetBound,
- size,
- padding = 0,
- }: {
- targetBound: IRect;
- size?: Size;
- padding?: number;
- }) {
- size = size || this.size;
- if (!size) {
- throw "size属性未设置";
- }
- const selfBound = {
- x: 0,
- y: 0,
- width: size.width - padding * 2,
- height: size.height - padding * 2,
- };
- const mat = new Transform()
- .translate(padding, padding)
- .multiply(alignPortMat(selfBound, targetBound, true));
-
- const rotate = this.viewMat.decompose().rotation
- this.setViewMat(mat);
- this.rotatePixel({x: size.width / 2, y: size.height / 2}, MathUtils.degToRad(rotate))
- }
- move(position: Pos, initMat = this.viewMat) {
- this.mutMat(new Transform().translate(position.x, position.y), initMat);
- }
- movePixel(position: Pos, initMat = this.viewMat) {
- if (isNaN(position.x) || isNaN(position.y)) {
- console.error(`无效移动位置${position.x} ${position.y}`);
- return;
- }
- const mat = initMat.copy().invert();
- const p1 = mat.point({ x: 0, y: 0 });
- const p2 = mat.point(position);
- this.move({ x: p2.x - p1.x, y: p2.y - p1.y });
- // const info = initMat.decompose()
- // const tf = new Transform()
- // tf.rotate(info.rotation)
- // tf.scale(info.scaleX, info.scaleY)
- // this.move(tf.invert().point(position), this.viewMat)
- }
- private min = 0.005
- private max = 50
- setScaleRange(min: number, max: number) {
- this.min = min
- this.max = max
- }
- scale(center: Pos, scale: number, initMat = this.viewMat) {
- const base = initMat.decompose().scaleX;
- const min = this.min
- const max = this.max
- const isMin = base * scale < min
- const isMax = base * scale > max
- if (isMax || isMin) {
- console.error(`缩放范围${min}~${max} 将自动调整缩放值`);
- if (scale > 1 && isMin) {
- scale = min / base
- } else if (scale < 1 && isMax) {
- scale = max / base
- } else {
- return;
- }
- }
- if (isNaN(center.x) || isNaN(center.y)) {
- console.error(`无效中心点${center.x} ${center.y}`);
- return;
- }
- this.mutMat(
- new Transform()
- .translate(center.x, center.y)
- .multiply(
- new Transform()
- .scale(scale, scale)
- .multiply(new Transform().translate(-center.x, -center.y))
- ),
- initMat
- );
- }
- scalePixel(center: Pos, scale: number, initMat = this.viewMat) {
- if (this.viewSize && this.size) {
- const offsetX = (this.size.width - this.viewSize.width) / 2
- const offsetY = (this.size.height - this.viewSize.height) / 2
- center = {
- x: center.x - offsetX,
- y: center.y - offsetY,
- }
- }
- const pos = initMat.copy().invert().point(center);
- this.scale(pos, scale, initMat);
- }
- rotate(center: Pos, angleRad: number, initMat = this.viewMat) {
- this.mutMat(
- new Transform()
- .translate(center.x, center.y)
- .multiply(
- new Transform()
- .rotate(angleRad)
- .multiply(new Transform().translate(-center.x, -center.y))
- ),
- initMat
- );
- }
- rotatePixel(center: Pos, angleRad: number, initMat = this.viewMat) {
- const pos = initMat.copy().invert().point(center);
- this.rotate(pos, angleRad, initMat);
- }
- mutMat(mat: Transform, initMat = this.viewMat) {
- // this.setViewMat(mat.copy().multiply(initMat))
- this.setViewMat(initMat.copy().multiply(mat));
- }
- setViewMat(mat: number[] | Transform) {
- if (mat instanceof Transform) {
- this.viewMat = mat.copy();
- } else {
- this.viewMat = new Transform(mat);
- }
- this.bus.emit("transformChange", this.transform);
- }
- get transform() {
- return this.sizeMat ? this.sizeMat.copy().multiply(this.viewMat) : this.viewMat.copy();
- }
- get current() {
- return this.transform.decompose();
- }
- }
|