用js实现图片旋转的两种方案

 更新时间:2023年07月19日 08:38:59   作者:Lewin.Lin  
这篇文章主要给大家介绍了关于用js实现图片旋转的两种方案, 旋转的效果就是根据鼠标的的移动距离来显示不同的图片,形成视觉差,仿佛就是在正真的旋转,需要的朋友可以参考下

一、图片旋转的方案介绍

1、用css的rotate与translate实现

2、用js的canvas实现

二、方案1的缺陷

用css的rotate方案来实现的时,如果图片是长方形,则图片左侧会有空白区域。如果要用translate来实现向左平移时,可以解决左侧留白问题。但是当图片旋转后再显示时,宽度可能超出父盒子的宽度,致使效果无法达到预期。

三、canvas实现图片旋转

<template>
  <div style="width: 100%; height: 100%">
    <img class="img-item" src="https://img2.baidu.com/it/u=1906732828,3160455141&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=666" />
    <img class="img-item" src="https://img0.baidu.com/it/u=2911164322,2998857390&fm=253&fmt=auto&app=138&f=JPEG?w=346&h=500" />
  </div>
</template>
<script>
export default {
  name: "deviceAssets",
  data() {
    return {}
  },
  mounted() {
    this.initPage()
  },
  methods: {
    initPage() {
      this.$nextTick(async() => {
        let imgList = document.getElementsByClassName("img-item")
        if (!imgList) return
        for(let i=0; i < imgList.length; i++) {
          this.rotateBase64Img(imgList[i].src, 90, (url) => {
            console.log(`imgList[${i}].src`, url)
            imgList[i].src = url
          })
        }
      })
    },
    // 传入图片src,旋转图片后,返回一个图片信息对象
    rotateBase64Img(src, edg, callback) {
      var canvas = document.createElement('canvas');
      var ctx = canvas.getContext('2d');
      var imgW; //图片宽度
      var imgH; //图片高度
      var size; //canvas初始大小
      if (edg % 90 != 0) {
        console.error('旋转角度必须是90的倍数!');
        throw '旋转角度必须是90的倍数!';
      }
      edg < 0 && (edg = (edg % 360) + 360);
      const quadrant = (edg / 90) % 4; //旋转象限
      const cutCoor = { sx: 0, sy: 0, ex: 0, ey: 0 }; //裁剪坐标
      var image = new Image();
      image.crossOrigin = 'anonymous';  
      image.src = src;
      image.onload = function () {
        console.log('加载了');
        imgW = image.width;
        imgH = image.height;
        size = imgW > imgH ? imgW : imgH;
        canvas.width = size * 2;
        canvas.height = size * 2;
        switch (quadrant) {
          case 0:
            cutCoor.sx = size;
            cutCoor.sy = size;
            cutCoor.ex = size + imgW;
            cutCoor.ey = size + imgH;
            break;
          case 1:
            cutCoor.sx = size - imgH;
            cutCoor.sy = size;
            cutCoor.ex = size;
            cutCoor.ey = size + imgW;
            break;
          case 2:
            cutCoor.sx = size - imgW;
            cutCoor.sy = size - imgH;
            cutCoor.ex = size;
            cutCoor.ey = size;
            break;
          case 3:
            cutCoor.sx = size;
            cutCoor.sy = size - imgW;
            cutCoor.ex = size + imgH;
            cutCoor.ey = size + imgW;
            break;
        }
        ctx?.translate(size, size);
        ctx?.rotate((edg * Math.PI) / 180);
        //drawImage向画布上绘制图片
        ctx?.drawImage(image, 0, 0);
        //getImageData() 复制画布上指定矩形的像素数据
        var imgData = ctx?.getImageData(cutCoor.sx, cutCoor.sy, cutCoor.ex, cutCoor.ey);
        if (quadrant % 2 == 0) {
          canvas.width = imgW;
          canvas.height = imgH;
        } else {
          canvas.width = imgH;
          canvas.height = imgW;
        }
        //putImageData() 将图像数据放回画布
        ctx?.putImageData(imgData, 0, 0);
        callback(canvas.toDataURL('image/png'));  
      };
    }
  }
}
</script>
<style lang="scss" scoped>
.iframe {
  width: 98%;
  height: 98%;
  box-sizing: border-box;
}
.img-box {
  width: 700px;
  height: 700px;
  background-color: #ccc;
  .img {
    width: 100%;
    transform: rotateZ(90deg) ;
  }
}
</style>

注意:

1、image.crossOrigin = 'anonymous’一定不能漏。

// 受限于 CORS 策略,会存在跨域问题,虽然可以使用图像(比如append到页面上)但是绘制到画布上会污染画布,一旦一个画布被污染,就无法提取画布的数据,比如无法使用使用画布toBlob(),toDataURL(),或getImageData()方法。

2、canvas.toDataURL(‘image/png’)

// 改成image/jpeg时,图片尺寸会更小。图片类型影响图片尺寸大小。例如:如果原图片大小为500kb,传入image/png时,图片可能是5MB,传入image/jpeg可能只有500kb左右。

3、this.rotateBase64Img(imgList[i].src, 90, (url) => {})中,只能旋转90度,180度、270度等能够被90整除的度数。

四、效果

OK,搞定~

总结

到此这篇关于用js实现图片旋转的两种方案的文章就介绍到这了,更多相关js图片旋转内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • javascript显式类型转换实例分析

    javascript显式类型转换实例分析

    这篇文章主要介绍了javascript显式类型转换,实例分析了javascript实现类型转换的常用技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • 微信小程序转发事件实现解析

    微信小程序转发事件实现解析

    这篇文章主要介绍了微信小程序转发事件实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • JS中Math对象使用示例(秒懂如何使用Math对象)

    JS中Math对象使用示例(秒懂如何使用Math对象)

    这篇文章主要给大家介绍了关于JS中Math对象使用的相关资料,Math和其他的对象不同,它不是一个构造函数,它属于一个工具类,不用创建对象,它里面封装了数学运算相关的属性和方法,需要的朋友可以参考下
    2024-06-06
  • JS中常用的消息框总结

    JS中常用的消息框总结

    小编给大家总结了JS最常用到的几种消息提示框,大家应该经常用的到,一起学习下吧。
    2018-02-02
  • 文本框回车提交与禁止提交示例

    文本框回车提交与禁止提交示例

    文本框输入数据后使用回车进行提交,想必大家都尝试过吧,在本文有个不错的示例,喜欢的朋友可以参下
    2013-09-09
  • 使用 JavaScript 创建可维护的幻灯片效果代码

    使用 JavaScript 创建可维护的幻灯片效果代码

    显然,效果很实用。对于这个效果,我们并不解释如何去使用效果库,而是讲解如何创建类似的效果,并保持他的可用性,分离式(unobtrusive),可维护性(让未来的维护者,在不需要修改你的脚本的情况下,修改图片,外观或文本标签)。
    2008-06-06
  • BootStrap表单控件之文本域textarea

    BootStrap表单控件之文本域textarea

    这篇文章主要介绍了BootStrap表单控件之文本域textarea,需要的朋友可以参考下
    2017-05-05
  • 原生JS实现简单计算器功能

    原生JS实现简单计算器功能

    这篇文章主要为大家详细介绍了原生JS实现简单计算器功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • JavaScript AJAX之惰性载入函数

    JavaScript AJAX之惰性载入函数

    这篇文章主要介绍了JavaScript AJAX之惰性载入函数,惰性载入表示函数执行的分支仅会发生1次,是种JS的优化技巧,需要的朋友可以参考下
    2014-08-08
  • JavaScript中setInterval()和setTimeout()的用法及区别

    JavaScript中setInterval()和setTimeout()的用法及区别

    这篇文章主要给大家介绍了关于JavaScript中setInterval()和setTimeout()用法及区别的相关资料,Javascript的setTimeOut和setInterval函数应用非常广泛,它们都用来处理延时和定时任务,需要的朋友可以参考下
    2023-11-11

最新评论