• JS实现 带有话题的文本编辑 + 图片编辑(下)


    本篇主要讲述九宫格上传图片

    图片编辑实现效果:

     图片编辑实现原理:

    1. 实现九宫格编辑图片可以做成一个组件,使用原生的图片上传方式通过 input 标签上传图片
    2. 一般图片都挺大,避免用户等待时间过长,使用 canvas 将上传的图片进行压缩
    3. 每次成功上传一张图片 && 图片总量 < 9 就在图片数组后push 一个待编辑图片
    4. 由于上传图片的接口需要formData 格式的文件,就需要将压缩后的base64格式的图片 通过dataURLtoBlob blobToFile 这两个函数转换成file文件,此方法不存在浏览器不兼容问题

     

    子组件封装:

    <template>
      <div class="addImg_wrap">
        <div class="occupy_img" v-if="!info.imgUrl">
          <img
            src="//nkb-yunpan.oss-cn-beijing.aliyuncs.com/d6de603efa86935328b439f276339c2b.png"
            alt
            @click.self.prevent="addImgEvent"
            class="img1"
          />
          <input
            class="file"
            type="file"
            id="add_input2"
            accept="image/*"
            ref="avatarInput"
            @change="changeImage($event)"
          />
        </div>
        <div class="real_img" v-if="info.imgUrl">
          <img :src="info.imgUrl" alt class="img2" />
          <img
            src="https://nkb-yunpan.oss-cn-beijing.aliyuncs.com/1595a0b56803644173f839f27655754b.png"
            alt
            class="close"
            @click.self.prevent="closeEvent(index)"
          />
        </div>
      </div>
    </template>
    
    <script>
    export default {
      props: {
        info: {
          type: Object,
          default: null
        },
        index: {
          type: Number,
          default: null
        },
        isLoading: {
          type: Boolean,
          default: null
        },
      },
      data() {
        return {};
      },
      methods: {
        addImgEvent() {
          this.$refs.avatarInput.click();
        },
    
        changeImage(e) {
          const self = this;
          let imgFile = "";
          let file = e.target.files[0];
          let filename = file.name;
          if (file) {
            let reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = function() {
              // 这里的this 指向reader
              let pic = new Image();
              pic.src = this.result;
              pic.onload = function() {
                var bitmap = new Image();
                bitmap.src = self.compress(pic);
                self.dataUrl = bitmap.src
              };
            };
    
            // 不加定时器获取不到dataurl
            setTimeout(() => {
              console.log('dataUrl');
              console.log(self.dataUrl);
              let blob = self.dataURLtoBlob(self.dataUrl);
              imgFile = self.blobToFile(blob, filename);
              let data = new FormData();
              data.append("file", imgFile, filename);
              self.getImgUrl(data);
            }, 500);
          }
        },
    
        // 先将base64转换成blob,再将blob转换成file文件,此方法不存在浏览器不兼容问题
        dataURLtoBlob(dataUrl) {
          var arr = dataUrl.split(","),
            mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]),
            n = bstr.length,
            u8arr = new Uint8Array(n);
          while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
          }
          return new Blob([u8arr], { type: mime });
        },
    
        blobToFile(theBlob, fileName) {
          theBlob.lastModifiedDate = new Date();
          theBlob.name = fileName;
          return theBlob;
        },
    
        //压缩图片
        compress(img) {
          let canvas = document.createElement("canvas");
          let ctx = canvas.getContext("2d");
          let width = img.width;
          let height = img.height;
          canvas.width = width;
          canvas.height = height;
          ctx.drawImage(img, 0, 0, width, height);
          //进行压缩
          var ndata = canvas.toDataURL("image/jpeg", 0.5);
          // console.log("已压缩");
          return ndata;
        },
    
        closeEvent(index) {
          this.$emit("imgDel", index);
        },
    
        async getImgUrl(data) {
          this.$emit("loadingEvent", true);
          const res = await this.fetch.post("Upload/UploadImage",data, "post",);
          if (res && res.success) {
            // Toast("上传成功");
            this.$emit("imgAdd", { imgUrl: res.result.path, index: this.index,isLoading:false });
          }
        }
      }
    };
    </script>
    
    <style lang="less" scoped>
    .addImg_wrap {
       31%;
      margin-right: 3%;
      margin-bottom: 4%;
      &:nth-child(3n) {
        margin-right: 0;
      }
      .occupy_img,
      .real_img {
         100%;
        height: 200px;
        position: relative;
        .img1 {
           100%;
          height: 206px;
          box-sizing: border-box;
          // border: 2px dashed #888888;
        }
        .img2 {
          box-sizing: border-box;
           100%;
          height: 206px;
          border: 0;
        }
      }
      .close {
        position: absolute;
         32px;
        height: 32px;
        top: 0;
        right: 0;
        z-index: 9;
      }
      .file {
        opacity: 0;
         1px;
        height: 1px;
      }
    }
    </style>
    View Code

    父组件调用:

    <template>
      <div class="nineImgs_wrap">
        <div class="edit_img">
          <addImgComponent
            v-for="(item,index) in imgList"
            :key="index"
            :info.sync="item"
            @imgDel="imgDel"
            @imgAdd="imgAdd"
            @loadingEvent="loadingEvent"
            :index="index"
            :isLoading="isLoading"
          ></addImgComponent>
        </div>
    
         <div class="loading" v-if="isLoading">
          <van-loading type="spinner" size="30px" vertical></van-loading>
        </div>
      </div>
    </template>
    
    <script>
    import addImgComponent from "@/components/addImg.vue";
    export default {
      name: "nineImgs",
      components: {
        addImgComponent
      },
      data() {
        return {
          imgList: [
            {
              imgUrl: ""
            }
          ],
          isLoading: false
        };
      },
      methods: {
        loadingEvent(val){
          this.isLoading = val
        },
        imgAdd(val) {
          this.isLoading = val.isLoading
          this.imgList.forEach((v, i) => {
            if (i === val.index) {
              v.imgUrl = val.imgUrl;
            }
          });
          const a = {
            imgUrl: null
          };
          this.imgList.push(a);
          
        },
        imgDel(d) {
          this.imgList.forEach((v, i) => {
            if (i === d) {
              this.imgList.splice(i, 1);
            }
          });
        }
      }
    };
    </script>
    
    <style lang="less" scoped>
    .nineImgs_wrap {
       100%;
      padding: 30px;
      font-size: 18px;
      .edit_img {
        display: flex;
        flex-wrap: wrap;
        margin-top: 20px;
        .real_img,
        .occupy_img .img1 {
          height: 200px !important;
        }
      }
      .loading{
         100%;
      }
    }
    </style>
    View Code

    分享一刻:

    浏览器禁用三方 Cookie 的分析

    Safari 浏览器开始完全禁用第三方 Cookie,本文分析了有何影响,以及如何在没有 Cookie 的情况下,获取浏览器的指纹。

  • 相关阅读:
    idea 文件名乱码问题的解决
    <context:component-scan>使用说明
    <mvc:annotation-driven />
    mac下的一些常识
    centos下的防火墙配置
    mac 下安装nginx
    centos下安装nginx
    Centos-统计文件或目录占用磁盘空间-du
    Centos-查看磁盘分区占用情况-df
    Centos-重定向方式打包、备份、还原、恢复工具-cpio
  • 原文地址:https://www.cnblogs.com/huangaiya/p/12910304.html
Copyright © 2020-2023  润新知