当前位置: 首页 > article >正文

Vue3 实现拖拽小图片覆盖大图片并下载合并后的图片

体验地址

技术栈

  • Vue3: 用于构建用户界面。
  • HTML5 Canvas: 用于绘制和合并图片。
  • JavaScript: 处理拖拽和下载逻辑。

功能概述

  1. 拖拽小图片: 用户可以通过鼠标拖拽小图片到大图片的任意位置。
  2. 边界限制: 确保小图片不会超出大图片的边界。
  3. 下载合并后的图片: 用户可以点击按钮下载合并后的图片。

实现步骤

1. 创建 Vue 组件

<template>
  <div class="image-container" @mousemove="handleMouseMove" @mouseup="handleMouseUp">
    <img
      :src="largeImageUrl"
      alt="Large Image"
      class="large-image"
      ref="largeImageRef"
      crossorigin="anonymous"
    />
    <img
      :src="smallImageUrl"
      alt="Small Image"
      class="small-image"
      ref="smallImageRef"
      width="60"
      :style="{ left: smallImagePosition.x + 'px', top: smallImagePosition.y + 'px' }"
      crossorigin="anonymous"
      @mousedown="handleMouseDown"
    />
  </div>
</template>

<script>
import { ref, onMounted } from "vue";
import { uploadFileFun } from "@/utils/minio.js";
import { dataURLtoFile } from "@/utils/methods";

export default {
  setup() {
    const largeImageUrl =
      "https://";
    const smallImageUrl =
      "https:/";
    const smallImagePosition = ref({ x: 0, y: 0 });
    const largeImageRef = ref(null);
    const smallImageRef = ref(null);
    let isDragging = false;
    let dragStart = { x: 0, y: 0 };

    const handleMouseDown = (event) => {
      isDragging = true;
      dragStart = {
        x: event.clientX - smallImagePosition.value.x,
        y: event.clientY - smallImagePosition.value.y,
      };
    };

    const handleMouseMove = (event) => {
      if (!isDragging) return;

      const largeImage = largeImageRef.value;
      const smallImage = smallImageRef.value;

      const smallImageWidth = smallImage.width;
      const smallImageHeight = smallImage.height;

      let newX = event.clientX - dragStart.x;
      let newY = event.clientY - dragStart.y;

      // 边界限制,考虑小图片的大小
      newX = Math.max(0, Math.min(newX, largeImage.width - smallImageWidth));
      newY = Math.max(0, Math.min(newY, largeImage.height - smallImageHeight));

      smallImagePosition.value = { x: newX, y: newY };
    };

    const handleMouseUp = () => {
      isDragging = false;
    };

    const saveAsImage = async () => {
      const largeImage = largeImageRef.value;
      const smallImage = smallImageRef.value;

      // 获取大图片的缩放比例
      const scaleX = largeImage.naturalWidth / largeImage.width;
      const scaleY = largeImage.naturalHeight / largeImage.height;

      const canvas = document.createElement("canvas");
      canvas.width = largeImage.naturalWidth;
      canvas.height = largeImage.naturalHeight;
      const ctx = canvas.getContext("2d");

      // 绘制大图片
      ctx.drawImage(largeImage, 0, 0);

      // 计算小图片在Canvas上的缩放后位置
      const scaledX = smallImagePosition.value.x * scaleX;
      const scaledY = smallImagePosition.value.y * scaleY;

      // 绘制小图片
      ctx.drawImage(
        smallImage,
        scaledX,
        scaledY,
        smallImage.width * scaleX, // 小图片的缩放宽度
        smallImage.height * scaleY // 小图片的缩放高度
      );

      const dataUrl = canvas.toDataURL("image/png");
      const link = document.createElement("a");
      link.href = dataUrl;
      link.download = "combined-image.png";
      link.click();
    };

    onMounted(() => {
      const saveButton = document.createElement("button");
      saveButton.innerText = "下载";
      saveButton.onclick = saveAsImage;
      document.body.appendChild(saveButton);
    });

    return {
      largeImageUrl,
      smallImageUrl,
      smallImagePosition,
      largeImageRef,
      smallImageRef,
      handleMouseDown,
      handleMouseMove,
      handleMouseUp,
    };
  },
};
</script>

<style scoped>
.image-container {
  position: relative;
  width: 350px;
  height: 450px;
}
.large-image {
  width: 100%;
  height: 100%;
}
.small-image {
  position: absolute;
  cursor: move;
}
</style>

2. 拖拽小图片

使用 ref 来引用大图片和小图片,并通过监听鼠标事件来实现拖拽功能。

  • handleMouseDown: 当用户按下鼠标左键时,记录拖拽起点的位置。
  • handleMouseMove: 当用户移动鼠标时,更新小图片的位置,并限制其在大图片范围内移动。
  • handleMouseUp: 当用户释放鼠标左键时,停止拖拽。

3. 下载合并后的图片

使用 HTML5 Canvas 来绘制合并后的图片,并提供下载功能。

  • saveAsImage: 创建一个 Canvas 元素,绘制大图片和小图片,然后将 Canvas 内容转换为 Data URL,并生成一个下载链接。

4. 添加下载按钮

在组件挂载完成后,动态创建一个下载按钮并添加到页面中。

onMounted(() => {
  const saveButton = document.createElement("button");
  saveButton.innerText = "下载";
  saveButton.onclick = saveAsImage;
  document.body.appendChild(saveButton);
});

http://www.kler.cn/a/388580.html

相关文章:

  • 第74期 | GPTSecurity周报
  • 万字长文解读深度学习——ViT、ViLT、DiT
  • 实时渲染技术如何助力3D虚拟展厅?
  • git commit 校验
  • c#使用COM接口设置excel单元格宽高匹配图片,如何计算?
  • Ai创作新风标!仅需三步,利用ai工具免费制作抖音爆款的动物融合视频(含完整的步骤)
  • Flutter运行App时出现“Running Gradle task ‘assembleDebug“问题解决
  • Vue2 doc、excel、pdf、ppt、txt、图片以及视频等在线预览
  • 信创异构环境下审视云原生二层和三层容器网络
  • 共享汽车管理:SpringBoot框架的高效实现
  • Ubuntu 18在线安装Docker 实战 2024年11月
  • 访谈Sam Altman:他再次阐述对一个人AI公司的定义以及GPT系列规划
  • Java项目实战II基于Spring Boot的光影视频平台(开发文档+数据库+源码)
  • sql server 自动kill 查询超过20分钟的语句
  • MISRA C2012学习笔记(9)-Rules 8.14
  • 论文解读之SDXL: Improving Latent Diffusion Models forHigh-Resolution Image Synthesis
  • 简易入手《SOM神经网络》的本质与原理
  • Golang | Leetcode Golang题解之第552题学生出勤记录II
  • WordPress HTTPS 配置问题解决方案
  • 试编写算法将单链表就地逆置(默认是带头节 点,如果是不带头节点地逆置呢?)
  • Ubuntu24.04网络异常与应对方案记录
  • 【OH】openHarmony开发环境搭建(基于windows子系统WSL)
  • 在Ubuntu下安装RabbitMQ、添加一个新的登录用户并设置密码
  • 【kafka】大数据编写kafka命令使用脚本,轻巧简洁实用kafka
  • docker-compose 部署ntp时间同步服务(tmpfs例子)
  • 三菱MR-J4-B系列伺服参数一览