toolbar.vue 8.47 KB
<script lang="ts" setup name="toolbar">
import { onUnmounted, ref, watch } from 'vue';
import {
  ZoomIn,
  ZoomOut,
  ScaleToOriginal,
  Refresh,
  Download,
  FullScreen
} from "@element-plus/icons-vue";

const props = defineProps({
  layout: {
    type: String,
    default: "",
  },
  /** 是否显示的字段血缘,字段血缘不要有切换布局。 */
  isFieldLineage: {
    type: Boolean,
    default: false,
  }
});

const emits = defineEmits(["handleChangeSize", "handleZoomOut", "handleZoomIn", "handleAutoZoom", "handleRealZoom", 'handleRefreshLayout', 'handleDownloadImage', 'handleEnterFullscreen', 'handleExitFullscreen','handelSave','handleSave',"handleChOrEn","handleToggle"]);

onUnmounted(() => {
  document.removeEventListener('webkitfullscreenchange', checkFull);
  document.removeEventListener('mozfullscreenchange', checkFull);
  document.removeEventListener('fullscreenchange', checkFull);
  document.removeEventListener('MSFullscreenChange', checkFull);
})

watch(() => props.layout, (val) => {
  // 监听退出全屏事件 --- chrome 用 esc 退出全屏并不会触发 keyup 事件
  document.addEventListener('webkitfullscreenchange', checkFull);
  document.addEventListener('mozfullscreenchange', checkFull);
  document.addEventListener('fullscreenchange', checkFull);
  document.addEventListener('MSFullscreenChange', checkFull);
})

const isFull: any = ref(true); //是否退出全屏。

const checkFull = () => {
  const windowWidth = document.documentElement.clientWidth;
  if (
    // @ts-ignore
    !document.mozFullScreen &&
    // @ts-ignore
    !document.webkitIsFullScreen &&
    // @ts-ignore
    !document.msFullscreenElement
  ) {
    isFull.value = true;
    // 退出全屏修改canvas宽高
    const windowHeight = document.documentElement.clientHeight;
    const width = props.layout === 'preview' ? windowWidth : windowWidth - 340;
    const height = window.outerHeight - 141 || windowHeight;
    emits('handleChangeSize', width, height)
  } else {
    isFull.value = false;
    // 全屏查看修改canvas宽高
    const width = windowWidth;
    const height = window.outerHeight;
    emits('handleChangeSize', width, height)
  }
};


const options = ref([
  {
    key: 'zoomOut',
    name: "ZoomIn",
    description: '放大',
    action: () => {
      emits('handleZoomOut')
    },
  },
  {
    key: 'zoomIn',
    name: "ZoomOut",
    description: '缩小',
    action: () => {
      emits('handleZoomIn')
    },
  },
  {
    key: 'autoZoom',
    name: "ScaleToOriginal",
    description: '恢复布局',
    action: () => {
      emits('handleAutoZoom')
    },
  },
  // {
  //   key: 'realZoom',
  //   name: <BorderOuterOutlined />,
  //     description: '视图居中',
  //   action: () => {
  //     emits('handleRealZoom')
  //   },
  // },
  {
    key: 'clearCanvas',
    name: "Refresh",
    description: '刷新',
    action: () => {
      emits('handleRefreshLayout')
    },
  },
  {
    key: 'downloadImage',
    name: "Download",
    description: '下载图片',
    action: () => {
      emits('handleDownloadImage')
    },
  },
  {
      key: 'fullscreenOutlined',
      name: "FullScreen",
      description: '全屏查看',
      action: () => {
        isFull.value = !isFull.value;
        emits('handleEnterFullscreen')
      },
    }
]);
const options1 = ref([
  {
    key: 'zoomOut',
    name: "ZoomIn",
    description: '放大',
    action: () => {
      emits('handleZoomOut')
    },
  },
  {
    key: 'zoomIn',
    name: "ZoomOut",
    description: '缩小',
    action: () => {
      emits('handleZoomIn')
    },
  },
  {
    key: 'autoZoom',
    name: "ScaleToOriginal",
    description: '恢复布局',
    action: () => {
      emits('handleAutoZoom')
    },
  },
  // {
  //   key: 'realZoom',
  //   name: <BorderOuterOutlined />,
  //     description: '视图居中',
  //   action: () => {
  //     emits('handleRealZoom')
  //   },
  // },
  {
    key: 'clearCanvas',
    name: "Refresh",
    description: '刷新',
    action: () => {
      emits('handleRefreshLayout')
    },
  },
  {
    key: 'downloadImage',
    name: "Download",
    description: '下载图片',
    action: () => {
      emits('handleDownloadImage')
    },
  },
  {
      key: 'fullscreenExitOutlined',
      name: "FullScreen",
      description: '退出全屏',
      action: () => {
        isFull.value = !isFull.value;
        emits('handleExitFullscreen')
      },
      keyDown:()=>{
        isFull.value = !isFull.value;
      }
    },
]);
const saveIcon =  new URL('@/assets/icons/save.svg', import.meta.url).href
const ch_en_Icon =  new URL('@/assets/icons/en_ch.svg', import.meta.url).href
const toggleIcon =  new URL('@/assets/icons/toggle.svg', import.meta.url).href
defineExpose({
  isFull
})
</script>

<template>
  <div className='g6-component-toolbar-content' v-if="isFull" :style="{ width: props.isFieldLineage ? '320px' : '360px' }">
    <el-tooltip
          class="box-item"
          effect="light"
          content="切换布局"
          placement="top"
         
        >
    <div v-show="!props.isFieldLineage" class="g6-component-toolbar-item" @click="emits('handleToggle')">
      <img :src="toggleIcon" class="saveIcon" />
    </div>
    </el-tooltip>
      <el-tooltip
          class="box-item"
          effect="light"
          content="中英文切换"
          placement="top"
        >
    <div class="g6-component-toolbar-item" @click="emits('handleChOrEn')">
      <img :src="ch_en_Icon" class="saveIcon" />
    </div>
    </el-tooltip>
      <template   v-for="(item) in options" :key="item.description" >
      <el-tooltip
        class="box-item"
        effect="light"
        :content="item.description"
        placement="top"
      >
      <el-button :icon="item.name === 'ZoomIn' ? ZoomIn : (item.name === 'ZoomOut' ? ZoomOut : (item.name === 'ScaleToOriginal' ? ScaleToOriginal : (item.name === 'Refresh' ? Refresh : (item.name == 'Download' ? Download :FullScreen ))))" class="g6-component-toolbar-item" :key="isFull" @click="item.action">
      </el-button>
      </el-tooltip>
    </template>
    <el-tooltip
      class="box-item"
      effect="light"
      content="保存血缘关系图片"
      placement="top"
      >
    <div  class="g6-component-toolbar-item" @click="emits('handleSave')">
      <img :src="saveIcon" class="saveIcon" />
    </div>
    </el-tooltip>
    
  </div>
  <div className='g6-component-toolbar-content' :style="{ width: props.isFieldLineage ? '320px' : '360px' }" v-else>
    <el-tooltip
          class="box-item"
          effect="light"
          content="切换布局"
          placement="top"
          :teleported="false"
        >
    <div v-show="!props.isFieldLineage" class="g6-component-toolbar-item" @click="emits('handleToggle')">
      <img :src="toggleIcon" class="saveIcon" />
    </div>
    </el-tooltip>
    <el-tooltip
        class="box-item"
        effect="light"
        content="中英文切换"
        placement="top"
        :teleported="false"
        
      >
    <div class="g6-component-toolbar-item" @click="emits('handleChOrEn')">
      <img :src="ch_en_Icon" class="saveIcon" />
    </div>
    </el-tooltip>
      <template   v-for="(item) in options1" :key="item.description" >
      <el-tooltip
        class="box-item"
        effect="light"
        :content="item.description"
        placement="top"
        :teleported="false"
      >
      <el-button :icon="item.name === 'ZoomIn' ? ZoomIn : (item.name === 'ZoomOut' ? ZoomOut : (item.name === 'ScaleToOriginal' ? ScaleToOriginal : (item.name === 'Refresh' ? Refresh : (item.name == 'Download' ? Download :FullScreen ))))" class="g6-component-toolbar-item" :key="isFull" @click="item.action" @keydown.esc="item.keyDown ?? null">
      </el-button>
      </el-tooltip>
    </template>
    <el-tooltip
      class="box-item"
      effect="light"
      content="保存血缘关系图片"
      placement="top"
      :teleported="false"
      >
    <div  class="g6-component-toolbar-item" @click="emits('handleSave')">
      <img :src="saveIcon" class="saveIcon" />
    </div>
    </el-tooltip>

  </div>
</template>

<style scoped lang="scss">
.g6-component-toolbar-content {
  display: flex;
  flex-direction: row;
  margin-right: 4px;
  box-sizing: border-box;
  width: 350px;
}

.g6-component-toolbar-item {
  height: 40px;
  border: none;
  width: 46px;
  background: transparent !important;
  display: flex;
  align-items: center;
  
}
.saveIcon {
  height: 16px;
  border: none;
  background: transparent !important;
  display: block;
  width: 38px;
}
:deep(.el-button + .el-button){
  margin-left:0px !important;
}
</style>