feat(canvas): add inherited elements, resizing and rotation

This commit is contained in:
2026-11-06 02:03:23 +08:00
parent e28ddb673f
commit 54ff5a0fbd
12 changed files with 411 additions and 38 deletions
+27 -2
View File
@@ -6,9 +6,9 @@
.node { position: relative; width: 260px; padding: 14px; border: 1px solid #ded7ce; border-radius: 10px; background: white; color: #37352f; box-shadow: 0 2px 5px #40302405; }
.selectedNode { border-color: #a47764; box-shadow: 0 0 0 2px #a4776425; }
.nodeHeading { display: flex; align-items: center; gap: 6px; margin-bottom: 12px; font-size: 11px; color: #92877c; }
.node textarea { display: block; width: 100%; min-height: 140px; padding: 0; resize: vertical; border: 0; background: none; color: #37352f; font-family: inherit; font-size: 13px; line-height: 1.8; outline: none; }
.node textarea { display: block; width: 100%; flex: 1; min-height: 0; height: 100%; padding: 0; resize: none; border: 0; background: none; color: #37352f; font-family: inherit; font-size: 13px; line-height: 1.8; outline: none; }
.node textarea::placeholder { color: #b2a99e; }
.image { display: block; max-width: 100%; max-height: 280px; margin: auto; border-radius: 5px; object-fit: contain; }
.image { display: block; flex: 1; min-height: 0; width: 100%; height: 100%; max-width: 100%; max-height: none; margin: auto; border-radius: 5px; object-fit: contain; }
.node :global(.react-flow__handle) { width: 8px; height: 8px; background: #a47764; border: 2px solid #fff; }
.toolbar button[aria-pressed="true"] { background: #f1e6df; color: #78523f; }
.toolbar button:disabled { cursor: not-allowed; }
@@ -38,3 +38,28 @@
.branch_right { right: -48px; top: 50%; transform: translateY(-50%); }
.branch_bottom { bottom: -48px; left: 50%; transform: translateX(-50%); }
.branch_left { left: -48px; top: 50%; transform: translateY(-50%); }
.transformFrame { position: relative; box-sizing: border-box; display: flex; flex-direction: column; transform-origin: center; overflow: visible; }
.nodeHeading { flex: 0 0 auto; }
.plainFrame { padding: 4px; border: 1px solid transparent; border-radius: 2px; background: transparent; box-shadow: none; }
.plainFrame.selectedFrame { border-color: #a47764; }
.plainText { display: block; flex: 1; min-width: 0; min-height: 0; width: 100%; height: 100%; padding: 0; border: 0; outline: none; background: transparent; color: #37352f; font-family: inherit; line-height: 1.25; resize: none; }
.plainText::placeholder { color: #b3a79c; }
.resizeHandle { position: absolute; box-sizing: border-box; width: 8px; height: 8px; padding: 0; border: 1px solid #a47764; border-radius: 2px; background: white; z-index: 8; touch-action: none; }
.resize_top { top: -4px; left: calc(50% - 4px); cursor: ns-resize; }
.resize_bottom { bottom: -4px; left: calc(50% - 4px); cursor: ns-resize; }
.resize_left { left: -4px; top: calc(50% - 4px); cursor: ew-resize; }
.resize_right { right: -4px; top: calc(50% - 4px); cursor: ew-resize; }
.resize_top-left { left: -4px; top: -4px; cursor: nwse-resize; }
.resize_bottom-right { right: -4px; bottom: -4px; cursor: nwse-resize; }
.resize_top-right { right: -4px; top: -4px; cursor: nesw-resize; }
.resize_bottom-left { left: -4px; bottom: -4px; cursor: nesw-resize; }
.rotationStem { position: absolute; left: 50%; top: -62px; width: 1px; height: 62px; background: #d5c7bb; pointer-events: none; }
.rotationHandle { position: absolute; top: -88px; left: calc(50% - 12px); display: grid; place-items: center; width: 24px; height: 24px; padding: 0; border: 1px solid #cbb8a8; border-radius: 50%; background: white; color: #78523f; z-index: 8; cursor: grab; touch-action: none; }
.rotationHandle:active { cursor: grabbing; }
.rotationValue { position: absolute; top: -85px; left: calc(50% + 18px); color: #92877c; background: #fffefbe6; padding: 0 4px; border-radius: 3px; font-size: 10px; pointer-events: none; }
.plainFrame .rotationHandle { top: -38px; }
.plainFrame .rotationStem { top: -14px; height: 14px; }
.plainFrame .rotationValue { top: -35px; }
.handMode .plainText { pointer-events: none; }
.handMode .resizeHandle, .handMode .rotationHandle, .handMode .rotationStem, .handMode .rotationValue, .handMode .branchButton { display: none; }