基于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>
相关推荐
漫随流水1 小时前
旅游推荐系统(view.py)
前端·数据库·python·旅游
踩着两条虫2 小时前
VTJ.PRO 核心架构全公开!从设计稿到代码,揭秘AI智能体如何“听懂人话”
前端·vue.js·ai编程
jzlhll1233 小时前
kotlin Flow first() last()总结
开发语言·前端·kotlin
用头发抵命4 小时前
Vue 3 中优雅地集成 Video.js 播放器:从组件封装到功能定制
开发语言·javascript·ecmascript
蓝冰凌4 小时前
Vue 3 中 defineExpose 的行为【defineExpose暴露ref变量】详解:自动解包、响应性与实际使用
前端·javascript·vue.js
奔跑的呱呱牛4 小时前
generate-route-vue基于文件系统的 Vue Router 动态路由生成工具
前端·javascript·vue.js
柳杉4 小时前
从动漫水面到赛博飞船:这位开发者的Three.js作品太惊艳了
前端·javascript·数据可视化
Greg_Zhong5 小时前
前端基础知识实践总结,每日更新一点...
前端·前端基础·每日学习归类
We་ct5 小时前
LeetCode 148. 排序链表:归并排序详解
前端·数据结构·算法·leetcode·链表·typescript·排序算法