前端 图片上鼠标画矩形框,标注文字,任意删除

06-01 1213阅读

效果:

前端 图片上鼠标画矩形框,标注文字,任意删除

页面描述:

对给定的几张图片,每张能用鼠标在图上画框,标注相关文字,框的颜色和文字内容能自定义改变,能删除任意画过的框。

实现思路:

1、对给定的这几张图片,用分页器绑定展示,能选择图片;

2、图片上绑定事件@mousedown鼠标按下——开始画矩形、@mousemove鼠标移动——绘制中临时画矩形、@mouseup鼠标抬起——结束画矩形重新渲染;

开始画矩形:鼠标按下,记录鼠标按下的位置。遍历标签数组,找到check值为true的标签,用其样式和名字创建新的标签,加入该图片的矩形框们的数组。注意,监听鼠标如果是按下后马上抬起,结束标注。

更新矩形:识别到新的标签存在,鼠标移动时监听移动距离,更新当前矩形宽高,用canvas绘制实时临时矩形。

结束画矩形:刷新该图片的矩形框们的数组,触发重新渲染。

3、在图片上v-for遍历渲染矩形框,盒子绑定动态样式改变宽高;

4、右侧能添加、修改矩形框颜色和文字;

5、列举出每个矩形框名称,能选择进行删除,还能一次清空;

      
        清空
      
      
        
          
            
            
            
            
            
              {{ annotation.label }}
            
          
          
        
        
          标签
          
            
              
                
              
              
                
                
                
              
            
          
          
            添加
          
          数据
          
            
              {{ index + 1 }}.{{ annotation.name }}
               
        
      
    


  import { DeleteOutlined } from '@ant-design/icons-vue';
  import { Pagination } from 'ant-design-vue';
  interface State {
    tagsList: any;
    canvasX: number;
    canvasY: number;
    currentPage: number;
    pageSize: number;
    imageUrls: string[];
  };
  const state = reactive({
    tagsList: [], // 标签列表
    canvasX: 0,
    canvasY: 0,
    currentPage: 1,
    pageSize: 1,
    imageUrls: [apiUrl.value + '/api/File/Image/annexpic/20241203Q9NHJ.jpg', apiUrl.value + '/api/file/Image/document/20241225QBYXZ.jpg'],
  });
  interface Annotation {
    id: string;
    name: string;
    x: number;
    y: number;
    width: number;
    height: number;
    color: string;
    label: string;
    border: string;
  };
  const annotations = reactive>([[]]);
  let currentAnnotation: Annotation | null = null;
  //开始标注
  function startAnnotation(event: MouseEvent) {
    // 获取当前选中的标签
    var tagsCon = { id: 1, check: true, color: '#000000', name: '安全帽' };
    // 遍历标签列表,获取当前选中的标签
    for (var i = 0; i  {
      endAnnotation();
      window.removeEventListener('mouseup', mouseupHandler);
    };
    window.addEventListener('mouseup', mouseupHandler);
  }
  //更新标注
  function updateAnnotation(event: MouseEvent) {
    if (currentAnnotation) {
      //更新当前标注的宽高,为负数时,鼠标向左或向上移动
      currentAnnotation.width = event.offsetX - currentAnnotation.x;
      currentAnnotation.height = event.offsetY - currentAnnotation.y;
    }
    //如果正在绘制中,更新临时矩形的位置
    if (annotationCanvas.value) {
      const canvas = annotationCanvas.value;
      //取得类名为image-container的div的宽高
      const imageContainer = document.querySelector('.image-container');
      canvas.width = imageContainer?.clientWidth || 800;
      canvas.height = imageContainer?.clientHeight || 534;
      const context = canvas.getContext('2d');
      if (context) {
        context.clearRect(0, 0, canvas.width, canvas.height);
        context.strokeStyle = currentAnnotation?.border || '#000000';
        context.lineWidth = 2;
        context.strokeRect(state.canvasX, state.canvasY, currentAnnotation?.width || 0, currentAnnotation?.height || 0);
      }
    }
  }
  function endAnnotation() {
    //刷新annotations[state.currentPage - 1],触发重新渲染
    annotations[state.currentPage - 1] = annotations[state.currentPage - 1].slice();
    currentAnnotation = null;
  }
  function annotationStyle(annotation: Annotation) {
    //如果宽高为负数,需要调整left和top的位置
    const left = annotation.width  {
      if (index === index2) {
        item.check = true;
      } else {
        item.check = false;
      }
    });
  }
  // 删除标签
  function deleteTag(index: number) {
    state.tagsList.splice(index, 1);
  }
  function addTags() {
    state.tagsList.push({ id: state.tagsList.length + 1, check: false, color: '#000000', name: '' });
  }
  // 移除某个标注
  function removeAnnotation(id: string) {
    const index = annotations[state.currentPage - 1].findIndex(a => a.id === id);
    if (index !== -1) {
      annotations[state.currentPage - 1].splice(index, 1);
    }
  }
  // 清空所有标注
  function clearAnnotations() {
    annotations[state.currentPage - 1].splice(0, annotations[state.currentPage - 1].length);
  }
  onMounted(() => {
    for (let i = 0; i  
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码