Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(core): node => rotate+正常模式resize(#1428) #1835

Merged
merged 3 commits into from
Sep 21, 2024

Conversation

wbccb
Copy link
Contributor

@wbccb wbccb commented Sep 1, 2024

related: transform相关问题汇总
fix: #1428
fix: #1628
fix: #1813
fix: #1475

1. 前言

node 加入rotate后,可能影响的范围有:

  1. rotate + resize=>正常 resize 模式
  2. rotate + resize=>等比例 resize 模式
  3. rotate + bbox 调整 => 涉及到旋转后辅助线对齐
  4. rotate + bbox 调整 => 涉及到点是否在某个旋转图形内的判断
  5. rotate + bbox 调整 => 涉及到 anchor 与 anchor 连线的计算

本次 pr 主要针对 rotate + resize 的正常 resize 模式进行修复

  1. rotate + resize=>正常 resize 模式

注:由于失误,将control坐标的名称叫成anchorX和anchorY,代码中已经更改,但是这里的pr描述由于篇幅过长,重做比较耗费时间,因此这里没有更改,凡是出现anchor相关单词,都可以替换为control

2.问题发生的原因

rotate=0的情况下,坐标转换简单,通过触摸点计算出 dx 和 dy,然后进行整体的 resize,但是在rotate不等于0的情况下,我们通过触摸点计算出 dx 和 dy 还得经过一层转化才能正确 resize

  • 而目前代码中还是延续rotate=0的处理,也就是触摸点计算出来的 dx 和 dy 就是实际宽度和高度变化的 dx 和 dy,然后计算出newWidth = oldWidth+dx
  • 同时,在 resize 过程中,我们一般会保持对角 anchor 的坐标不变化(在rotate=0的情况下拉伸右下角的 anchor,左上角 anchor 保持不变),而由于宽度和高度发生变化,因此中心点 center 也发生变化,因此左上角的 anchor 实际坐标会发生变化,因此这个时候不能简单使用newCenter.x = oldCenter.x + dx的逻辑

因此在rotate不等于0的情况下,newWidth的计算和newCenter的计算都需要进行调整

问题发生的原因 (1)

3.解决方法

在原来逻辑中,recalcResizeInfo先处理了PCTResizeInfo的情况(也就是等比例缩放),返回nextResizeInfo,然后再处理正常模式下缩放,返回nextResizeInfo

export const recalcResizeInfo = () => {
  const nextResizeInfo = cloneDeep(resizeInfo);
  let { deltaX, deltaY } = nextResizeInfo;
  const { width, height, PCTResizeInfo } = nextResizeInfo;
  if (PCTResizeInfo) {
    //...处理
    return nextResizeInfo;
  }

  //...处理PCTResizeInfo为空的情况

  return nextResizeInfo;
};

因此我们在原来的逻辑上增加PCTResizeInfo为空并且rotate不等于0的逻辑处理: recalcRotatedResizeInfo(),不影响原来等比例缩放正常模式缩放+rotate=0的处理逻辑

export const recalcResizeInfo = () => {
  const nextResizeInfo = cloneDeep(resizeInfo);
  let { deltaX, deltaY } = nextResizeInfo;
  const { width, height, PCTResizeInfo } = nextResizeInfo;
  if (PCTResizeInfo) {
    //...处理等比例缩放的情况
    return nextResizeInfo;
  }

  if (rotate % (2 * Math.PI) !== 0) {
    return recalcRotatedResizeInfo(...);
  }

  //...处理PCTResizeInfo为空 + rotate等于0的情况

  return nextResizeInfo;
};

recalcRotatedResizeInfo()主要是

  • 进行数据的拼接准备
  • 通过核心方法calculateWidthAndHeight()计算出宽度、高度和新的中心点newCenter
  • 然后我们就可以通过newCenteroldCenter的比较得出deltaXdeltaY,因为最终我们是通过BaseNodeModel.resize()来重置 width、height,以及通过BaseNodeModel.move()this.x = this.x+deltaX来更新中心点的坐标
function recalcRotatedResizeInfo(
  pct: number,
  resizeInfo: ResizeInfo,
  rotate: number,
  anchorX: number,
  anchorY: number,
  oldCenterX: number,
  oldCenterY: number,
  freezeWidth = false,
  freezeHeight = false
) {
  // 假设我们触摸的点是右下角的anchor
  const { deltaX, deltaY, width: oldWidth, height: oldHeight } = resizeInfo;
  const angle = radianToAngle(rotate);

  // 右下角的anchor
  const startZeroTouchAnchorPoint = {
    x: anchorX, // control锚点的坐标x
    y: anchorY, // control锚点的坐标y
  };
  const oldCenter = { x: oldCenterX, y: oldCenterY };
  // 右下角的anchor坐标(transform后的-touchStartPoint)
  const startRotatedTouchAnchorPoint = calculatePointAfterRotateAngle(
    startZeroTouchAnchorPoint,
    oldCenter,
    angle
  );
  // 右下角的anchor坐标(transform后的-touchEndPoint)
  const endRotatedTouchAnchorPoint = {
    x: startRotatedTouchAnchorPoint.x + deltaX,
    y: startRotatedTouchAnchorPoint.y + deltaY,
  };
  // 通过固定点、旧的中心点、触摸点、旋转角度计算出新的宽度和高度以及新的中心点
  const {
    width: newWidth,
    height: newHeight,
    center: newCenter,
  } = calculateWidthAndHeight(
    startRotatedTouchAnchorPoint,
    endRotatedTouchAnchorPoint,
    oldCenter,
    angle,
    freezeWidth,
    freezeHeight,
    oldWidth,
    oldHeight
  );
  // handleResize()会处理isFreezeWidth和deltaX、isFreezeHeight和deltaY,这里不再处理
  resizeInfo.width = newWidth * pct;
  resizeInfo.height = newHeight * pct;

  // BaseNodeModel.resize(deltaX/2, deltaY/2),因此这里要*2
  resizeInfo.deltaX = (newCenter.x - oldCenter.x) * 2;
  resizeInfo.deltaY = (newCenter.y - oldCenter.y) * 2;

  return resizeInfo;
}

如下面代码所示,当我们不考虑freezeWidthfreezeHeight时,代码逻辑是非常简单的

下面将通过图示进行思路的讲解

export function calculateWidthAndHeight(
  startRotatedTouchAnchorPoint: SimplePoint,
  endRotatedTouchAnchorPoint: SimplePoint,
  oldCenter: SimplePoint,
  angle: number,
  freezeWidth = false,
  freezeHeight = false,
  oldWidth: number,
  oldHeight: number
) {
  // 假设目前触摸的是右下角的anchor
  // 计算出来左上角的anchor坐标,resize过程左上角的anchor坐标保持不变
  const freezePoint: SimplePoint = {
    x: oldCenter.x - (startRotatedTouchAnchorPoint.x - oldCenter.x),
    y: oldCenter.y - (startRotatedTouchAnchorPoint.y - oldCenter.y),
  };
  // 【touchEndPoint】右下角 + freezePoint左下角 计算出新的中心点
  let newCenter = getNewCenter(freezePoint, endRotatedTouchAnchorPoint);

  // 得到【touchEndPoint】---angle=0(右下角anchor)的坐标
  let endZeroTouchAnchorPoint: SimplePoint = calculatePointAfterRotateAngle(
    endRotatedTouchAnchorPoint,
    newCenter,
    -angle
  );

  // ---------- 使用transform之前的坐标计算出新的width和height ----------

  // 得到左上角---angle=0的坐标
  let zeroFreezePoint: SimplePoint = calculatePointAfterRotateAngle(
    freezePoint,
    newCenter,
    -angle
  );

  // transform之前的坐标的左上角+右下角计算出宽度和高度
  const width = Math.abs(endZeroTouchAnchorPoint.x - zeroFreezePoint.x);
  const height = Math.abs(endZeroTouchAnchorPoint.y - zeroFreezePoint.y);

  // ---------- 使用transform之前的坐标计算出新的width和height ----------

  return {
    width,
    height,
    center: newCenter,
  };
}

3.1 图解

  • 第1个图=>第2个图:利用目前已知的坐标oldCenterstartRotatedTouchAnchorPoint(也就是 anchor 坐标)、手指触摸的距离(也就是 onDraging 得到的 dx 和 dy),我们可以计算得到的坐标endRotatedTouchAnchorPointfreezePoint
  • 第2个图=>第3个图:利用freezePointendRotatedTouchAnchorPoint,我们可以得到新的中心点newCenter
  • 第3个图=>第4个图:自此我们知道了几乎所有点的坐标,我们进行-angle的翻转得到去掉transform的图形以及对应的坐标(也就是rotate=0的图形)
  • 第4个图:利用rotate=0的图形顺利计算出新的 width 和 height 以及 newCenter 和 oldCenter 之间的偏移量 deltaX 和 deltaY

2 1

3.2 freezeWidth 和 freezeHeight

当加入freezeWidthfreezeHeight后,情况会变的比较复杂,因为 rotate 不为 0 的时候,recalcRotatedResizeInfo()计算出来的中心点会发生变化,因此我们不能简单限制freezeWidth,我们就设置为deltaX=0,我们还是得计算出来deltaXdeltaY

因此我们在原来的calculateWidthAndHeight()加入一段修正deltaXdeltaY的逻辑

下面将通过图示进行思路的讲解

export function calculateWidthAndHeight(...) {
  //...freezeWidth和freezeHeight都为false的坐标获取逻辑

  if (freezeWidth) {
    // 如果固定width,那么不能单纯使用endZeroTouchAnchorPoint.x=startZeroTouchAnchorPoint.x
    // 因为去掉transform的左上角不一定是重合的,我们要保证的是transform后的左上角重合
    const newWidth = Math.abs(endZeroTouchAnchorPoint.x - zeroFreezePoint.x);
    const widthDx = newWidth - oldWidth;

    // 点击的是左边锚点,是+widthDx/2,点击是右边锚点,是-widthDx/2
    if (newCenter.x > endZeroTouchAnchorPoint.x) {
      // 当前触摸的是左边锚点
      newCenter.x = newCenter.x + widthDx / 2;
    } else {
      // 当前触摸的是右边锚点
      newCenter.x = newCenter.x - widthDx / 2;
    }
  }
  if (freezeHeight) {
    //...与freezeWidth处理相同
  }

  if (freezeWidth || freezeHeight) {
    // 如果调整过transform之前的坐标,那么transform后的坐标也会改变,那么算出来的newCenter也得调整
    // 由于无论如何rotate,中心点都是不变的,因此我们可以使用transform之前的坐标算出新的中心点
    const nowFreezePoint = calculatePointAfterRotateAngle(
      zeroFreezePoint,
      newCenter,
      angle
    );

    // 得到当前新rect的左上角与实际上transform后的左上角的偏移量
    const dx = nowFreezePoint.x - freezePoint.x;
    const dy = nowFreezePoint.y - freezePoint.y;

    // 修正不使用transform的坐标: 左上角、右下角、center
    newCenter.x = newCenter.x - dx;
    newCenter.y = newCenter.y - dy;
    zeroFreezePoint = calculatePointAfterRotateAngle(
      freezePoint,
      newCenter,
      -angle
    );
    endZeroTouchAnchorPoint = {
      x: newCenter.x - (zeroFreezePoint.x - newCenter.x),
      y: newCenter.y - (zeroFreezePoint.y - newCenter.y),
    };
  }

  //...利用rotate=0的图形顺利计算出新的width和height

  return {
    width,
    height,
    center: newCenter,
  };
}
  • 图1->图2: 当freezeWidth=true时,我们进行宽度的恢复,得出需要减去的宽度widthDx
  • 图2->图3: 我们使用减去的宽度widthDx去修正目前的中心点newCenter.x=newCenter.x-widthDx/2
  • 图3->图4: 我们旋转angle得到 transform 后的左上角坐标,此时应该保持一致,因此我们可以得出目前的偏移量,通过偏移量,我们整体平移图形,修正newCenter的误差
  • 图4->图5: 通过准确的newCenter以及固定不变的freezePoint,我们可以计算出新的左上角和右下角,然后计算出widthheight

2 2

3.3 其他小优化点

3.3.1 freezeWidth 和 freezeHeight 滑动卡顿问题

freezeWidth=true时,minWidth等于maxHeight,因此nextSize.width必须等于minWidth
rotate!==0触发calculateWidthAndHeight()计算widthheight,理论计算出来的nextSize.width必须等于oldWidth,但是实际上有误差,比如

  • oldWidth = 100
  • newWidth=100.000000000001

因此在calculateWidthAndHeight()直接width = oldWidth,防止误差导致cancelDrag()发生

export const handleResize = ({...}) => {
  //...
  const nextSize = recalcResizeInfo(...);

  // 限制放大缩小的最大最小范围
  if (
    nextSize.width < minWidth ||
    nextSize.width > maxWidth ||
    nextSize.height < minHeight ||
    nextSize.height > maxHeight
  ) {
    // this.dragHandler.cancelDrag()
    cancelCallback?.();
    return;
  }
  //...
};
export function calculateWidthAndHeight(...) {
  //...
  if (freezeWidth) {
    // 理论计算出来的width应该等于oldWidth
    // 但是有误差,比如oldWidth = 100; newWidth=100.000000000001
    // 会在handleResize()限制放大缩小的最大最小范围中被阻止滑动
    width = oldWidth;
  }
  if (freezeHeight) {
    height = oldHeight;
  }

  return {
    width,
    height,
    center: newCenter,
  };
}

3.3.2 onDragging 没有销毁注册事件

如下面视频所示,有一定小概率会发生,当ResizeControlGroup销毁时,也就是 Resize 的组件销毁时,此时的DOC.removeEventListener("mousemove")没有触发,也就是没有销毁注册监听,导致 onDragging 一直触发,造成滑动错乱情况发生

onDragging.mov

通过代码分析,当<ResizeControlGroup>在滑动过程中因为某些原因造成销毁,并且在销毁前没有触发handleMouseUp()事件,也就是跟视频展示一样,在滑动过程中,某些特殊原因导致滑动过程中就触发ResizeControlGroup销毁时,还没来得及触发handleMouseUp()时,就会导致window?.document注册的mousemove一直存在!

class BaseNode extends Component {
    getResizeControl(): h.JSX.Element | null {
        const { model, graphModel } = this.props
        const {
        editConfigModel: { isSilentMode, allowResize },
        } = graphModel
        const { isSelected, isHitable, resizable, isHovered } = model

        // 合并全局 allResize 和节点自身的 resizable 配置,以节点配置高于全局配置
        const canResize = allowResize && resizable // 全局开关 > 节点配置
        const style = model.getResizeControlStyle()
        if (!isSilentMode && isHitable && (isSelected || isHovered) && canResize) {
            return (
                <ResizeControlGroup
                    style={style}
                    model={model}
                    graphModel={graphModel}
                />
            )
        }
        return null
    }
}
export class ResizeControl extends Component<> {

  constructor(props: IResizeControlProps) {
    //...

    // 初始化拖拽工具
    this.dragHandler = new StepDrag({
      onDragging: this.onDragging,
      onDragEnd: this.onDragEnd,
      step: graphModel.gridSize,
    });
  }

  handleMouseDown = (e: MouseEvent) => {
    const DOC: any = window?.document;
    //...

    DOC.addEventListener("mousemove", this.handleMouseMove, false);
    DOC.addEventListener("mouseup", this.handleMouseUp, false);
    //...
  };

  handleMouseUp = (e: MouseEvent) => {
    const DOC = window.document
    //...
    Promise.resolve().then(() => {
      DOC.removeEventListener('mousemove', this.handleMouseMove, false)
      DOC.removeEventListener('mouseup', this.handleMouseUp, false)
    });
}

因此在ResizeControl销毁时,应该主动触发一次事件销毁this.dragHandler.cancelDrag(),才能避免一些错乱事情发生

目前只在ResizeControl中加入componentWillUnmount进行this.dragHandler.cancelDrag(),按照道理,其它有用到DOC.addEventListener("mousemove")都应该在组件销毁时显式触发一次事件监听销毁,这里没有深入去排查

export class ResizeControl extends Component<> {

  constructor(props: IResizeControlProps) {
    //...

    // 初始化拖拽工具
    this.dragHandler = new StepDrag({
      onDragging: this.onDragging,
      onDragEnd: this.onDragEnd,
      step: graphModel.gridSize,
    });
  }

  componentWillUnmount() {
    this.dragHandler.cancelDrag()
  }

  handleMouseDown = (e: MouseEvent) => {
    const DOC: any = window?.document;
    //...

    DOC.addEventListener("mousemove", this.handleMouseMove, false);
    DOC.addEventListener("mouseup", this.handleMouseUp, false);
    //...
  };

  handleMouseUp = (e: MouseEvent) => {
    const DOC = window.document
    //...
    Promise.resolve().then(() => {
      DOC.removeEventListener('mousemove', this.handleMouseMove, false)
      DOC.removeEventListener('mouseup', this.handleMouseUp, false)
    });
}

4. 测试代码和效果视频

4.1 正常模式的 rotate+resize

代码已经上传到examples/feature-examples/src/pages/graph/index.tsx

test-resize_compressed.mp4

4.2 freezeWidth 和 freezeHeight

由于代码中好像没有实现maxHeightminHeight的初始化处理,因此我添加了一些测试代码,没有上传

examples/feature-examples/src/pages/nodes/native/index.tsx

  • const data = {}增加测试数据freeWidth矩形freeHeight矩形
  • const config增加配置allowRotate=trueallowResize=true
const config = {
  //...省略很多数据
  allowRotate: true,
  allowResize: true,
}
const data = {
  nodes: [
    //...省略很多数据
    {
      id: "8",
      type: "rect",
      x: 350,
      y: 400,
      rotate: Math.PI * 0.2,
      properties: {
        width: 100,
        height: 100,
        minWidth: 100,
        maxWidth: 100,
      },
      text: "freeWidth矩形",
    },
    {
      id: "9",
      type: "rect",
      x: 550,
      y: 400,
      rotate: Math.PI * 0.3
      properties: {
        width: 100,
        height: 100,
        minHeight: 100,
        maxHeight: 100,
      },
      text: "freeHeight矩形",
    },
  ],
};

packages/core/src/model/node/RectNodeModel.tssetAttributes()增加

  • this.minWidth = minWidth
  • this.maxWidth = maxWidth
  • this.minHeight = minHeight
  • this.maxHeight = maxHeight
  setAttributes() {
    super.setAttributes()

    const { width, height, radius, minWidth, maxWidth, minHeight, maxHeight } =
      this.properties
    if (!isNil(width)) this.width = width
    if (!isNil(height)) this.height = height
    // @ts-ignore
    if (!isNil(minWidth)) this.minWidth = minWidth
    // @ts-ignore
    if (!isNil(maxWidth)) this.maxWidth = maxWidth
    // @ts-ignore
    if (!isNil(minHeight)) this.minHeight = minHeight
    // @ts-ignore
    if (!isNil(maxHeight)) this.maxHeight = maxHeight

    // 矩形特有
    if (!isNil(radius)) this.radius = radius
  }
test-freezeWidth.mp4

Copy link

changeset-bot bot commented Sep 1, 2024

⚠️ No Changeset found

Latest commit: 45eba18

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@boyongjiong
Copy link
Collaborator

cool 啊帅哥。下次找个时间大家认识一下吧 哈哈哈

@boyongjiong
Copy link
Collaborator

我看一下 PR,有问题再沟通

@boyongjiong
Copy link
Collaborator

靓仔,我上周看了 pr,这个 PR 会导致 extension 打包报错,好像是类型问题。你抽空也确认下?我原本想自己解决,但最近在忙其它的事情,没顾上弄

@wbccb
Copy link
Contributor Author

wbccb commented Sep 9, 2024

你说的应该是下面图这个报错
error-1

可以像下面这样解决报错,原因应该是我在此次pr中给handResize(params)加上了类型,也就是handResize(params:IHandleResizeParams),然后就报错了
error-2

但是我不想在这个pr中修复一些非rotate+resize的错误,所以我就在想修复dynamic-group相关问题的时候再顺便修了它

目前我在 pull/1858这里修复了上面这个报错,要不先review下这个pull/1858,如果pull/1858满足merge的话,合并过来应该就没有报错了

🤔️或者你先手动改下handleResizeimport方式,就可以直接运行此次pr的代码 @boyongjiong

@wbccb
Copy link
Contributor Author

wbccb commented Sep 13, 2024

🤔️有问题吗这个pr?还是你们内部想自己修复这些问题? @boyongjiong

@LeeeeeeM
Copy link

讲得很详细,👍!确实是旋转之后的 dx,dy 没有对应原有坐标导致的问题。
看代码改动比较大,在官方维护没有完全把控之前建议拆分为多个提交,每次实现固定feature 的优化。

@boyongjiong
Copy link
Collaborator

🤔️有问题吗这个pr?还是你们内部想自己修复这些问题? @boyongjiong

WIP. 大佬的 PR 很优秀,我最近忙别的没顾上弄,这两天处理一下

@boyongjiong
Copy link
Collaborator

你说的应该是下面图这个报错 error-1

可以像下面这样解决报错,原因应该是我在此次pr中给handResize(params)加上了类型,也就是handResize(params:IHandleResizeParams),然后就报错了 error-2

但是我不想在这个pr中修复一些非rotate+resize的错误,所以我就在想修复dynamic-group相关问题的时候再顺便修了它

目前我在 pull/1858这里修复了上面这个报错,要不先review下这个pull/1858,如果pull/1858满足merge的话,合并过来应该就没有报错了

🤔️或者你先手动改下handleResizeimport方式,就可以直接运行此次pr的代码 @boyongjiong

帅哥,那个 PR 我已经合进去了,这个 PR 你基于 master rebase 一下,再重新提一下?现在这个 PR 我想 gh pr checkout 1835 本地运行一下,会失败。

@wbccb
Copy link
Contributor Author

wbccb commented Sep 21, 2024

已经基于 master rebase @boyongjiong 再试试

@boyongjiong
Copy link
Collaborator

4.2 freezeWidth 和 freezeHeight @wbccb 最上面 4.2 这部分代码为什么本次 PR 不加上呢?我理解是在本次 PR 范围内的吧

@@ -0,0 +1,55 @@
export interface SimplePoint {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我可以接受这个类型定义,但其实我们内部是有一个 Position 的定义,用来表示坐标位置

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个SimplePoint的类型定义,在后续的pr中,我把它干掉,替换一下

@boyongjiong
Copy link
Collaborator

4.2 freezeWidth 和 freezeHeight @wbccb 最上面 4.2 这部分代码为什么本次 PR 不加上呢?我理解是在本次 PR 范围内的吧

@wbccb 我先把这个 PR 过了,后面如果要加上,可以再提个 PR,再次感谢大佬的贡献 ღ( ´・ᴗ・` )比心

@boyongjiong boyongjiong merged commit 7015886 into didi:master Sep 21, 2024
@wbccb
Copy link
Contributor Author

wbccb commented Sep 21, 2024

4.2 freezeWidth 和 freezeHeight @wbccb 最上面 4.2 这部分代码为什么本次 PR 不加上呢?我理解是在本次 PR 范围内的吧

有两个原因:

  • 第1个原因:因为我看了代码,目前在新版本中对minWidthmaxWidth等属性好像并没有做处理,只是移值旧的版本minWidthmaxWidth过来,所以我不太清楚你们是不是后期要改动它或者废弃它,我就不太敢动
  • 第2个原因:我只是为了测试,所以在RectNodeModelsetAttributes()加了minWidthmaxWidth的处理,但是其实还有很多xxxxNodeModel,比如DiamondNodeModelsetAttributes(),这里也需要加minWidthmaxWidth的处理,或者在基础类中增加minWidthmaxWidth的处理.....改动文件还是很多的,所以我就不太敢动

对于这个freezeWidth 和 freezeHeight的功能,我不清楚后续的优化计划(要废弃还是优化之类的),所以我就没加这段代码了 @boyongjiong

class RectNodeModel {
    setAttributes() {
        super.setAttributes()
    
        const { width, height, radius, minWidth, maxWidth, minHeight, maxHeight } =
          this.properties
        if (!isNil(width)) this.width = width
        if (!isNil(height)) this.height = height
        // @ts-ignore
        if (!isNil(minWidth)) this.minWidth = minWidth
        // @ts-ignore
        if (!isNil(maxWidth)) this.maxWidth = maxWidth
        // @ts-ignore
        if (!isNil(minHeight)) this.minHeight = minHeight
        // @ts-ignore
        if (!isNil(maxHeight)) this.maxHeight = maxHeight
    
        // 矩形特有
        if (!isNil(radius)) this.radius = radius
    }
}

@wbccb wbccb deleted the fix/rotate-resize branch September 21, 2024 09:24
@boyongjiong
Copy link
Collaborator

4.2 freezeWidth 和 freezeHeight @wbccb 最上面 4.2 这部分代码为什么本次 PR 不加上呢?我理解是在本次 PR 范围内的吧

有两个原因:

  • 第1个原因:因为我看了代码,目前在新版本中对minWidthmaxWidth等属性好像并没有做处理,只是移值旧的版本minWidthmaxWidth过来,所以我不太清楚你们是不是后期要改动它或者废弃它,我就不太敢动
  • 第2个原因:我只是为了测试,所以在RectNodeModelsetAttributes()加了minWidthmaxWidth的处理,但是其实还有很多xxxxNodeModel,比如DiamondNodeModelsetAttributes(),这里也需要加minWidthmaxWidth的处理,或者在基础类中增加minWidthmaxWidth的处理.....改动文件还是很多的,所以我就不太敢动

对于这个freezeWidth 和 freezeHeight的功能,我不清楚后续的优化计划(要废弃还是优化之类的),所以我就没加这段代码了 @boyongjiong

class RectNodeModel {
    setAttributes() {
        super.setAttributes()
    
        const { width, height, radius, minWidth, maxWidth, minHeight, maxHeight } =
          this.properties
        if (!isNil(width)) this.width = width
        if (!isNil(height)) this.height = height
        // @ts-ignore
        if (!isNil(minWidth)) this.minWidth = minWidth
        // @ts-ignore
        if (!isNil(maxWidth)) this.maxWidth = maxWidth
        // @ts-ignore
        if (!isNil(minHeight)) this.minHeight = minHeight
        // @ts-ignore
        if (!isNil(maxHeight)) this.maxHeight = maxHeight
    
        // 矩形特有
        if (!isNil(radius)) this.radius = radius
    }
}

soga,我也想想你说的东西。

哈哈,你可以根据你的想法做调整,你觉得合理的,都可以搞,合理性我们再一起讨论嘛 😄

@wbccb
Copy link
Contributor Author

wbccb commented Sep 21, 2024

🤔️嗯嗯嗯嗯 后续搞搞

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment