123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- <template>
- <div class="l-context-menu t-dropdown__menu">
- <template v-if="props.type === 'anchor'">
- <t-dropdown-item>
- <a @click="onAddAnchorHand">
- <div class="flex">添加手柄 <span class="flex-grow"></span> H</div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="onRemoveAnchorHand">
- <div class="flex">删除手柄 <span class="flex-grow"></span> D</div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="onToggleAnchorHand">
- <div class="flex">切换手柄 <span class="flex-grow"></span> Shift</div>
- </a>
- </t-dropdown-item>
- </template>
- <template v-if="props.type === 'pen'">
- <t-dropdown-item
- :class="!choosePens() && !choosePen() ? 'item-diabled' : ''"
- >
- <a @click="layerMove('top')">
- <div class="flex">置顶 <span class="flex-grow"></span></div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item
- :class="!choosePens() && !choosePen() ? 'item-diabled' : ''"
- >
- <a @click="layerMove('bottom')">
- <div class="flex">置底 <span class="flex-grow"></span></div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item
- :class="!choosePens() && !choosePen() ? 'item-diabled' : ''"
- >
- <a @click="layerMove('up')">
- <div class="flex">上一个图层 <span class="flex-grow"></span></div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item
- :class="!choosePens() && !choosePen() ? 'item-diabled' : ''"
- >
- <a @click="layerMove('down')">
- <div class="flex">下一个图层 <span class="flex-grow"></span></div>
- </a>
- </t-dropdown-item>
- <t-divider />
- <t-dropdown-item
- :class="!choosePens() && !choosePen() ? 'item-diabled' : ''"
- >
- <a @click="layerMove('down')">
- <div class="flex">下一个图层 <span class="flex-grow"></span></div>
- </a>
- </t-dropdown-item>
- <template v-if="choosePens()">
- <t-dropdown-item>
- <a @click="combine()">
- <div class="flex">组合 <span class="flex-grow"></span></div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="combine(0)">
- <div class="flex">组合为状态 <span class="flex-grow"></span></div>
- </a>
- </t-dropdown-item>
- </template>
- <t-dropdown-item v-if="hasChildren()">
- <a @click="unCombine()">
- <div class="flex">取消组合 <span class="flex-grow"></span></div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item
- :class="!choosePens() && !choosePen() ? 'item-diabled' : ''"
- >
- <a @click="onLock">
- <div class="flex">
- {{ getLocked() ? '解锁' : '锁定' }} <span class="flex-grow"></span>
- </div>
- </a>
- </t-dropdown-item>
- <t-divider />
- <t-dropdown-item
- :class="!choosePens() && !choosePen() ? 'item-diabled' : ''"
- >
- <a @click="onDel">
- <div class="flex">删除<span class="flex-grow"></span></div>
- </a>
- </t-dropdown-item>
- <template v-if="isLine()">
- <t-dropdown-item v-if="isLineType()">
- <a @click="changeType(0)">
- <div class="flex">变成节点<span class="flex-grow"></span></div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item v-else>
- <a @click="changeType(1)">
- <div class="flex">变成连线<span class="flex-grow"></span></div>
- </a>
- </t-dropdown-item>
- </template>
- <t-divider />
- <t-dropdown-item :class="cantUndo() ? 'item-diabled' : ''">
- <a @click="onUndo">
- <div class="flex">撤销<span class="flex-grow"></span>Ctrl + Z</div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item :class="cantRedo() ? 'item-diabled' : ''">
- <a @click="onRedo">
- <div class="flex">恢复<span class="flex-grow"></span>Shift + Z</div>
- </a>
- </t-dropdown-item>
- <t-divider />
- <t-dropdown-item
- :class="!choosePens() && !choosePen() ? 'item-diabled' : ''"
- >
- <a @click="onCut">
- <div class="flex">剪切<span class="flex-grow"></span>Ctrl + X</div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item
- :class="!choosePens() && !choosePen() ? 'item-diabled' : ''"
- >
- <a @click="onCopy">
- <div class="flex">复制<span class="flex-grow"></span>Ctrl + C</div>
- </a>
- </t-dropdown-item>
- <t-dropdown-item>
- <a @click="onPaste">
- <div class="flex">粘贴<span class="flex-grow"></span>Ctrl + V</div>
- </a>
- </t-dropdown-item>
- </template>
- </div>
- </template>
- <script setup lang="ts">
- import { ref } from 'vue';
- import { LockState, Pen, PenType, Meta2d } from '@meta2d/core';
- const props = defineProps({
- type: String,
- });
- const emit = defineEmits(['changeVisible']);
- function closeMenu() {
- emit('changeVisible', false);
- }
- const onAddAnchorHand = () => {
- meta2d.addAnchorHand();
- closeMenu();
- };
- const onRemoveAnchorHand = () => {
- meta2d.removeAnchorHand();
- closeMenu();
- };
- const onToggleAnchorHand = () => {
- meta2d.toggleAnchorHand();
- closeMenu();
- };
- function choosePen(): boolean {
- return meta2d?.store.active?.length === 1;
- }
- function choosePens(): boolean {
- return meta2d?.store.active?.length > 1;
- }
- function layerMove(type: 'top' | 'bottom' | 'up' | 'down') {
- const pens = meta2d.store.active;
- if (hasImage()) {
- if (type === 'top') {
- meta2d.setValue({
- id: pens[0].id,
- isBottom: false,
- });
- meta2d.top(pens[0]);
- } else if (type === 'bottom') {
- meta2d.setValue({
- id: pens[0].id,
- isBottom: true,
- });
- meta2d.bottom(pens[0]);
- } else if (type === 'up') {
- if (pens[0].isBottom) {
- meta2d.setValue({
- id: pens[0].id,
- isBottom: false,
- });
- } else {
- meta2d.up(pens[0]);
- }
- } else if (type === 'down') {
- if (!pens[0].isBottom) {
- meta2d.setValue({
- id: pens[0].id,
- isBottom: true,
- });
- } else {
- meta2d.down(pens[0]);
- }
- }
- } else {
- if (pens[0].name === 'gif') {
- let zIndex = pens[0].calculative.zIndex;
- if (type === 'top') {
- zIndex == 999;
- }
- if (type === 'bottom') {
- zIndex == -999;
- }
- if (type === 'up') {
- zIndex++;
- }
- if (type === 'down') {
- zIndex--;
- }
- meta2d.setValue({
- id: pens[0].id,
- zIndex,
- });
- } else {
- if (Array.isArray(pens)) {
- for (const pen of pens) {
- meta2d[type](pen);
- }
- }
- }
- meta2d.render();
- }
- emit('changeVisible', false);
- }
- function hasChildren(): boolean {
- return choosePen() && meta2d?.store.active[0]?.children?.length > 0;
- }
- function getLocked() {
- return meta2d?.store.active?.some((pen: Pen) => pen.locked);
- }
- function combine(showChild?: number) {
- meta2d.combine(meta2d.store.active, showChild);
- closeMenu();
- }
- function unCombine() {
- meta2d.uncombine();
- closeMenu();
- }
- function onLock() {
- const locked = !getLocked();
- const pens = meta2d.store.active;
- if (Array.isArray(pens)) {
- for (const pen of pens) {
- pen.locked = locked ? LockState.DisableMove : LockState.None;
- }
- }
- meta2d.render();
- closeMenu();
- }
- function onDel() {
- meta2d.delete();
- closeMenu();
- }
- function onUndo() {
- meta2d.undo();
- closeMenu();
- }
- function onRedo() {
- meta2d.redo();
- closeMenu();
- }
- function onCut() {
- meta2d.cut();
- closeMenu();
- }
- function onCopy() {
- meta2d.copy();
- closeMenu();
- }
- function onPaste() {
- meta2d.paste();
- closeMenu();
- }
- function cantUndo(): boolean {
- return (
- !!meta2d?.store.data.locked ||
- meta2d?.store.histories.length == 0 ||
- meta2d?.store.historyIndex == null ||
- meta2d?.store.historyIndex < 0
- );
- }
- function cantRedo(): boolean {
- return (
- !!meta2d?.store.data.locked ||
- meta2d?.store.histories.length == 0 ||
- meta2d?.store.historyIndex == null ||
- meta2d?.store.historyIndex > meta2d?.store.histories.length - 2
- );
- }
- function isLine(): boolean {
- return choosePen() && meta2d?.store.active[0]?.name === 'line';
- }
- function isLineType(): boolean {
- return meta2d?.store.active[0]?.type === PenType.Line;
- }
- function changeType(type: number) {
- const id = meta2d.store.active[0].id;
- meta2d.setValue(
- {
- id,
- type,
- },
- {
- history: true,
- }
- );
- closeMenu();
- }
- function hasImage(): boolean {
- const pen = meta2d.store.active[0];
- return choosePen() && pen.image && pen.name !== 'gif';
- }
- </script>
- <style lang="postcss" scoped>
- .l-context-menu {
- position: absolute;
- display: flex;
- flex-direction: column;
- padding: 6px;
- border-radius: 6px;
- gap: 2px;
- background-color: var(--color-background-popup);
- z-index: 999;
- .t-dropdown__item {
- max-width: 240px !important;
- /* padding: 0;
- background-color: transparent; */
- &:hover {
- background-color: var(--color-background-popup-hover);
- }
- a {
- width: 150px;
- display: block;
- text-decoration: none;
- color: var(--color);
- margin-left: 8px;
- label {
- font-size: 10px;
- background-color: #ff400030;
- color: var(--color-bland);
- padding: 0 6px;
- margin-left: 4px;
- border-radius: 2px;
- }
- }
- }
- .item-diabled {
- a {
- cursor: not-allowed;
- color: var(--td-text-color-disabled);
- }
- &:hover {
- background-color: #0000;
- }
- }
- }
- </style>
|