首页 > 其他分享 >vue.js3:图片镜像(翻转)并保存([email protected])

vue.js3:图片镜像(翻转)并保存([email protected])

时间:2022-09-07 17:44:22浏览次数:102  
标签:box style vue const img 37 value 3.2

一,js代码:

<template>
  <div style="background: #ffffff;" id="root" >
    <div><button @click="restore">还原</button><button @click="flipx">水平镜像</button>
      <button @click="flipy">垂直镜像</button>
      <button @click="flipxy">水平垂直镜像</button>
    </div>
    <div><input type="file" accept="image/*" @change="open" /><button @click="save">保存</button></div>

    <div style="position: relative;width:500px;height:500px;overflow: hidden;background: lightgray;" >
      <img id="img" :src="imgSrc" style="max-width:500px;max-height: 500px;" />
    </div>
  </div>
</template>

<script>
import {ref} from "vue";
export default {
  name: "FlipImg",
  setup() {
    //翻转的类型:0:还原,1,水平,2,垂直,3,水平垂直
    const flipType = ref(0);
    //图片的src
    const imgSrc = ref("");
    //图片的原宽高
    const imgWidth = ref(0);
    const imgHeight = ref(0);
    //读取图片的信息
    const open = (e) => {
      let file = e.target.files[0];
      let reader = new FileReader();
      reader.readAsDataURL(file);

      reader.onload = () =>{
        //显示图片
        imgSrc.value = reader.result;
        //得到宽高
        let img = new Image();
        img.src= reader.result;
        img.onload = () => {
          //保存宽高
          imgWidth.value = img.width;
          imgHeight.value = img.height;
        }
      }
    }
    //还原
    const restore = () => {
      flipType.value = 0;
      let box = document.getElementById('img');
      box.style.transform = 'rotateY(0deg)';
      box.style.transform = 'rotateX(0deg)';
      box.style.transitionDuration = '500ms';
      box.style.transitionTimingFunction = 'linear';
    }
    //水平镜像
    const flipx = () => {
      flipType.value = 1;
      let box = document.getElementById('img');
      box.style.transform = 'rotateY(180deg)';
      box.style.transitionDuration = '500ms';
      box.style.transitionTimingFunction = 'linear';
    }
    //垂直镜像
    const flipy = () => {
      flipType.value = 2;
      let box = document.getElementById('img');
      box.style.transform = 'rotateX(180deg)';
      box.style.transitionDuration = '500ms';
      box.style.transitionTimingFunction = 'linear';
    }
    //水平垂直镜像
    const flipxy = () => {
      flipType.value = 3;
      let box = document.getElementById('img');
      box.style.transform = 'rotateX(180deg) rotateY(180deg)';
      box.style.transitionDuration = '500ms';
      box.style.transitionTimingFunction = 'linear';
    }
    
    //保存图片
    const save = () => {
      if (flipType.value == 0) {
          alert('请执行操作后再下载');
          return;
      }

      let img = document.getElementById('img')
      //创建canvas
      const canvas = document.createElement('canvas')

      canvas.width = imgWidth.value // 根据图像大小来动态生成canvas
      canvas.height = imgHeight.value;
      if (canvas.getContext) {
        let context = canvas.getContext('2d');
        if (flipType.value == 1){
          context.translate(imgWidth.value / 2, imgHeight.value / 2)
          context.scale(-1,1) //水平翻转
          context.drawImage(img, -imgWidth.value / 2, -imgHeight.value / 2)
        } else if (flipType.value == 2) {
          context.translate(imgWidth.value / 2, imgHeight.value / 2)
          context.scale(1,-1) //垂直翻转
          context.drawImage(img, -imgWidth.value / 2, -imgHeight.value / 2)
        } else if (flipType.value == 3) {
          context.translate(imgWidth.value / 2, imgHeight.value / 2)
          context.scale(-1,-1) //水平垂直翻转
          context.drawImage(img, -imgWidth.value / 2, -imgHeight.value / 2)
        }
        downJpgByCanvas(canvas);
      }
    }

    //下载图片
    const downJpgByCanvas = (canvas) => {
      var oA = document.createElement("a");
      let time = timeFormat();
      oA.download = "img_"+time+'.jpg';// 设置下载的文件名,默认是'下载'
      oA.href = canvas.toDataURL("image/jpeg");
      document.body.appendChild(oA);
      oA.click();
      oA.remove(); // 下载之后把创建的元素删除
    }

    //补0
    const add0 = (m) => {
      return m<10?'0'+m:m
    }
    //格式化时间
    const timeFormat = ()=>{
      var time = new Date();
      var y = time.getFullYear();
      var m = time.getMonth()+1;
      var d = time.getDate();
      var h = time.getHours();
      var mm = time.getMinutes();
      var s = time.getSeconds();
      let res = y+add0(m)+add0(d)+add0(h)+add0(mm)+add0(s);
      return res;
    }

    return {
      restore,
      flipx,
      flipy,
      flipxy,
      save,
      open,
      imgSrc,
    }
  }
}
</script>

<style scoped>

</style>

说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

         对应的源码可以访问这里获取: https://github.com/liuhongdi/
         或: https://gitee.com/liuhongdi

说明:作者:刘宏缔 邮箱: [email protected]

二,测试效果

还原时:

 

 水平:

 

 垂直:

三,查看vue框架的版本:

liuhongdi@lhdpc:/data/vue/pdf/image2pdf$ npm list vue
[email protected] /data/vue/pdf/image2pdf
├─┬ @vue/[email protected]
│ └─┬ @vue/[email protected]
│   ├─┬ @vue/[email protected]
│   │ └── [email protected] deduped invalid: "2.x" from node_modules/@vue/babel-preset-jsx
│   └── [email protected] deduped
└─┬ [email protected]
  └─┬ @vue/[email protected]
    └── [email protected] deduped

 

标签:box,style,vue,const,img,37,value,3.2
From: https://www.cnblogs.com/architectforest/p/16666664.html

相关文章

  • 第 24 题:聊聊 Redux 和 Vuex 的设计思想
    共同点首先两者都是处理全局状态的工具库,大致实现思想都是:全局state保存状态---->dispatch(action)------>reducer(vuex里的mutation)---->生成newState;整个状态为同步......
  • vue如何回显已上传的文件并且修改
    我们知道当我们在表单里面上传多个文件时,我们希望将多个文件和表单中的对象一起传给后端,这时我们传给后端的文件就是file数组。而我们想要回显已上传的文件,应该是拿不到那......
  • vue-puzzle-vcode与vue-drag-verify纯前端的拼图人机验证、右滑拼图验证
    转载作品!以获取原作者允许,原文地址,感觉写的比较全面,也比较实用,大家可以去看看原文章;纯前端的拼图人机验证、右滑拼图验证1、vue-puzzle-vcodegithub地址:https://github......
  • vue 正则 密码校验
    password:[/*{validator:checkPassword,trigger:'blur'}*/{pattern:/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&,.*]).{8,19......
  • Vue初学
    1.什么是“插值表达式”1.1语法插值表达式可以理解为:使用大括号来包裹JS代码作用:将大括号中的数据替换成对应属性值进行展示。PS:双大括号语法也称为模板语法(mustache语......
  • React版/Vue版都齐了,开源一套【特别】的后台管理系统...
    本项目主要基于Elux+Antd构建,包含React版本和Vue版本,旨在提供给大家一个简单基础、开箱即用的后台管理系统通用模版,主要包含运行环境、脚手架、代码风格、基本Layout、状态......
  • vue3异步组件使用
    场景一:当我们在模版中,需要根据模版当前作用域的数据,去做异步的操作时候。白话一点:表格的第二列要展示的数据是根据第一列的数据去请求接口得到。在组件模版中<Suspens......
  • vue-路由传参
    1.声明式导航(router-link)<router-linkto="/login">登录</router-link>2.编程式导航($router.push|replace)params:属于路径一部分,需要占位{path:'/search/:key......
  • vue3源码学习6-计算属性computed
    packages/reactivity/src/computed.tsexportfunctioncomputed<T>(getterOrOptions:ComputedGetter<T>|WritableComputedOptions<T>,debugOptions?:DebuggerOp......
  • Vue面试题13:说一说key的作用
    思路分析:1.给出结论,key的作用是用于优化patch性能;2.key的必要性;3.实际使用方式;4.总结:可从源码层面描述一下vue如何判断两个节点是否相同;回答范例:1.key的作用......