123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- import { Transform } from "konva/lib/Util";
- import mitt from 'mitt'
- import { alignPortMat, Pos } from "./math";
- import { MathUtils } from "three";
- export type ViewerProps = {
- size?: number[];
- bound?: number[];
- padding: number | number[];
- retain: boolean;
- };
- export class Viewer {
- props: ViewerProps;
- viewMat: Transform;
- partMat: Transform = new Transform();
- bus = mitt<{ transformChange: Transform }>()
- constructor(props: Partial<ViewerProps> = {}) {
- this.props = {
- padding: 0,
- retain: true,
- ...props,
- }
- this.viewMat = new Transform();
- }
- get bound() {
- return this.props.bound
- }
- setBound(bound: number[], size?: number[], padding?: number | number[], retain?: boolean) {
- this.props.bound = bound
- if (padding) {
- this.props.padding = padding
- }
- if (retain) {
- this.props.retain = retain
- }
- if (size) {
- this.props.size = size
- }
- padding = this.props.padding
- retain = this.props.retain
- size = this.props.size
- if (!size) {
- throw '缺少视窗size'
- }
- this.partMat = alignPortMat(
- [
- {x: bound[0], y: bound[1]},
- {x: bound[2], y: bound[3]},
- ],
- [
- {x: 0, y: 0},
- {x: size[0], y: size[1]},
- ],
- retain,
- typeof padding === "number"
- ? padding
- : {x: padding[0], y: padding[1]}
- );
- }
- 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 offsetX = position.x
- const currentX = this.viewMat.decompose().x
- const finX = currentX + offsetX
- const x = finX - currentX
- const mat = initMat.copy().invert()
- const p1 = mat.point({x: 0, y: 0})
- const p2 = mat.point({x, y: position.y})
- 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)
- }
- scale(center: Pos, scale: Pos, initMat = this.viewMat) {
- const base = initMat.decompose().scaleX
- if (base * scale.x < 0.001 || base * scale.x > 1000) {
- console.error('缩放范围0.001~1000 已超过范围无法缩放')
- 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.x, scale.y)
- .multiply(new Transform().translate(-center.x, -center.y))
- ),
- initMat
- );
- }
- scalePixel(center: Pos, scale: Pos, initMat = this.viewMat) {
- 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)
- }
- let dec = this.viewMat.decompose()
- if (dec.x > 10) {
- dec.x = 10
- this.viewMat = new Transform()
- .translate(dec.x, dec.y)
- .scale(dec.scaleX, dec.scaleY)
- .rotate(MathUtils.degToRad(dec.rotation))
- }
- // while(dec.x > 0.01) {
- // console.log(dec.x)
- // this.viewMat = this.viewMat.copy().translate(-dec.x, 0)
- // dec = this.viewMat.decompose()
- // }
- this.bus.emit('transformChange', this.transform)
- }
- get transform() {
- return this.partMat.copy().multiply(this.viewMat);
- }
- get current() {
- return this.viewMat.decompose()
- }
- }
|