基于cornerstone3D的dicom影像浏览器 第三章 拖拽seriesItem至displayer上显示第一张dicom

先看效果

实现seriesItem拖拽至displayer显示第一张

1.在seriesItem添加拖拽事件,

seriesItem代码添加@dragstart="onDragStart"

复制代码
<div
      :class="thumbClass"
      draggable="true"
      @dragstart="onDragStart"
      @click="onClick"
    >
      ...原有的代码
    </div>

 methods: {
    onDragStart(e) {
      e.dataTransfer.setData("seriesInsUid", this.$props.series.seriesInsUid);
      e.dataTransfer.effectAllowed = "copy"; // 允许拖拽操作
    }
  }

2.在displayer.vue接受

复制代码
<script>
import { vec3 } from "gl-matrix";
import {
  RenderingEngine,
  getRenderingEngine,
  Enums,
  utilities as csUtils,
} from "@cornerstonejs/core";
const { IMAGE_RENDERED, CAMERA_MODIFIED } = Enums.Events;

import { toolGroup } from "@/utils/initTools";

import { utilities } from "@cornerstonejs/tools";
const { getOrientationStringLPS, invertOrientationStringLPS } =
  utilities.orientation;
export default {
  name: "displayer",
  props: {
    pos: {
      type: Number,
      required: true,
    },
  },
  data() {
    return {
      IsSel: false,
      IsHover: false,
      state: {
        series: null,
        image: null,
        imageIds: [],
        isSeries: false,
        viewport: null,
        renderingEngine: null,
      },
      renderingEngineId: "displayerRenderingEngine",
      imageIndex: 0,
    };
  },
  computed: {
    borderClass() {
      let s = "selected";
      if (this.IsSel) {
        s = "selected";
      } else {
        if (this.IsHover) {
          s = "hovered";
        } else {
          s = "unselect";
        }
      }
      return s;
    },
    viewportId() {
      return `DISP_STACK_${this.$props.pos}`;
    },
  },
  methods: {
    async dragDrop(e) {
      const seriesInsUid = e.dataTransfer.getData("seriesInsUid");
      const series = await this.$store.dispatch('archiveStore/FindSeries', seriesInsUid)
      if (series) {
        this.load(series, 0, true);
      }
    },
    load(series, idx, isSeries) {
      if (!series) return;
      this.state.image = series.GetImageByIndex(idx);
      if (!this.state.image) return;
      this.state.series = series;
      this.state.isSeries = isSeries;

      if (isSeries) {
        this.state.imageIds = series.GetImageIds();
      } else {
        const imageId = this.state.image.imageId;
        this.state.imageIds.push(imageId);
      }

      this.state.viewport.setStack(this.state.imageIds);
      this.state.viewport.render();
    },
    init() {
      const ViewportType = Enums.ViewportType;
      const viewportInput = {
        viewportId: this.viewportId,
        type: ViewportType.STACK,
        element: this.$refs.displayer,
        defaultOptions: {
          background: [0, 0, 0],
        },
      };

      this.state.renderingEngine = getRenderingEngine(this.renderingEngineId);
      if (!this.state.renderingEngine) {
        this.state.renderingEngine = new RenderingEngine(
          this.renderingEngineId
        );
      }

      this.state.renderingEngine.enableElement(viewportInput);
      this.state.viewport = this.state.renderingEngine.getViewport(
        this.viewportId
      );
      toolGroup.addViewport(this.viewportId, this.renderingEngineId);
    },
   
    onMouseUp(e) {
      this.IsSel = true;
      this.$emit("selected", { pos: this.$props.pos });
      e.preventDefault();
    },
    onMouseOver(e) {
      this.IsHover = true;
      e.preventDefault();
    },
    onMouseOut(e) {
      this.IsHover = false;
      e.preventDefault();
    },
    handlerClick(e) {
      this.IsSel = true;
      this.imageIndex = this.state.viewport.getCurrentImageIdIndex();
      this.$emit("selected", { pos: props.pos });
      e.preventDefault();
    },
  },
  mounted() {
    this.init();
    // 阻止右键菜单
    this.$refs.displayer.addEventListener("contextmenu", (e) => {
      e.preventDefault();
    });
  },
};
</script>

<template>
  <div
    class="displaybox"
    :class="borderClass"
    @drop.prevent="dragDrop($event)"
    @dragover.prevent
    @onMouseUp="onMouseUp"
    @mouseover="onMouseOver"
    @mouseout="onMouseOut"
    @click="handlerClick"
  >
    <div class="displayer" ref="displayer"></div>
  </div>
</template>
<style lang="scss" scoped>
.displaybox {
  position: relative;
  display: flex;
  flex-direction: row;
  background-color: black;

  .scroll-right {
    width: 20px;
  }
}
.displayer {
  flex: 1;
  text-align: left;
  cursor: default;
  user-select: none;

  $font-size: 14px;
  @mixin orient($text-align: left) {
    position: absolute;
    color: white;
    font-size: $font-size;
    text-align: $text-align;
    z-index: 10;
  }

  .orient_top {
    @include orient(center);
    top: 2px;
    left: calc(50% - 30px);
    width: 60px;
  }

  .orient_bottom {
    @include orient(center);
    bottom: 2px;
    left: calc(50% - 30px);
    width: 60px;
  }

  .orient_left {
    @include orient();
    top: calc(50% - 20px);
    left: 2px;
  }

  .orient_right {
    @include orient();
    top: calc(50% - 20px);
    right: 2px;
  }
}

.selected {
  border: 1px solid red;
}
.hovered {
  border: 1px dashed yellow;
}
.unselect {
  border: 1px solid #fff;
}
</style>
相关推荐
Highcharts.js10 分钟前
用Highcharts开发动态主从图表|双图联动的时间序列图表示例
javascript·数据库·信息可视化·highcharts·图表开发·动态图表
牛奔13 分钟前
mise 管理多版本 Go 项目
开发语言·前端·chrome·后端·golang
志尊宝41 分钟前
Vue3 零基础每日笔记(076):防抖节流的正确使用——搜索框、按钮防重复提交、滚动监听
javascript·vue.js·笔记
能源革命1 小时前
Vue 网格拖拽布局组件全景指南:7 大方案深度对比
前端·javascript·vue.js
雷工笔记1 小时前
KingFusion 驾驶舱开发:ECharts小时模板实现动态时间窗口
javascript
知野小兔1 小时前
JavaScript中Map和Set详解
javascript
PC2005_cloud1 小时前
AI 汉字漂移实录:它为什么总把「学习」写成日语「学習」
前端·后端
穆梓兰煊2 小时前
AI供应链安全不再只是包安全,还涉及模型与数据
前端·数据库
RaaS1002 小时前
AI网关能做Prompt注入防护吗?AI网关核心功能详解
前端·后端
deli0072 小时前
Skill 怎么写才被 Agent 命中?18 条规则做成 SKILL.md 校验器,规范样例 92 分
前端