viewJs


我的项目使用的是vue,接到新的需求要在图片预览的时候,添加旋转保存按钮。需要做的无非为iview添加按钮,为按钮添加事件。

在上述图片的default.js中有iviewJs的所有配置项,在iview.js文件与你传入的合并

this.options = assign({}, DEFAULTS, isPlainObject(options) && options);复制代码


一、在工具栏中添加保存按钮

配置项中有几个钩子函数


show可以在展示之前执行绑定一下函数,在函数里我们通过使用insertAdjacentHTML()对工具栏进行样式的重新设定,并绑定函数触发相关

addPre () {      var dom = document.querySelector('.viewer-container')      if (this.list.length > 1) {        dom.insertAdjacentHTML('beforeend', '<a class="bh_pre bh_iconbutton" onclick="viewer.cprev()"><i class="ivu-icon ivu-icon-ios-arrow-back"></i></a>')        dom.insertAdjacentHTML('beforeend', '<a class="bh_next bh_iconbutton" onclick="viewer.cnext()"><i class="ivu-icon ivu-icon-ios-arrow-forward"></i></a>')      }      dom.insertAdjacentHTML('beforeend', '<div class="btn-show-big-img" onclick="viewer.setShowBigImg()">查看原图</div>')      dom.insertAdjacentHTML('beforeend', `<div class="bottonContent">       <a  onclick="viewer.zoom(0.1)"><i class="ivu-icon ivu-icon-md-add"></i></a>        <a  onclick="viewer.zoom(-0.1)"><i class="ivu-icon ivu-icon-md-remove"></i></a>         <a class="refresh-cover" onclick="viewer.crotate(-90)"><i class="ivu-icon ivu-icon-md-refresh"></i></a>         <a onclick="viewer.crotate(90)"><i class="ivu-icon ivu-icon-md-refresh"></i></a>         <a onclick="viewer.save()" class="btn-save-img" style="visibility:hidden"><i class="ivu-icon ivu-icon-md-checkmark"></i></a>       </div>     `)    },复制代码

    window.viewer = new Viewer()         window.viewer.crotate = function (val) {          _this.rotateNum += val          _this.isShowSave()          window.viewer.rotate(val)        }        window.viewer.cprev = function () {          _this.isLoad = false          _this.rotateNum = 0          _this.isShowSave()          window.viewer.prev()        }        window.viewer.cnext = function () {          _this.isLoad = false          _this.rotateNum = 0          _this.isShowSave()          window.viewer.next()        }复制代码

二、添加保存事件

渲染的基本流程:

  1. view.js中实例调用class view中的init()函数
    1. 函数获取页面Dom读取img和页面的信息进行储存
    2. 调用build函数进行组件的构建
  2. build函数会调用render中的render函数,对页面进行渲染。
  3. 用户交互操作会通过handler判断交互类型去调用method中的方法
观看源码viewer一些存储数据位置:

document.querySelector('.viewer-canvas img')
//当前展示的图片信息
image{
    naturalHeight//应该是存储的图片原始大小
    naturalWigth
    complete     //图片是否加载完成
}复制代码

//存储当前图片位置展示大小形变等初始化信息。(每次切换图片必然刷新)
imageData{
    aspectRatio: 0.625 // naturalHeight/naturalHeight的比值
    height: 788        //图片初始化要展示的大小
    width: 453.125
    left: 382.09375     //图片的位置position的top,left的值
    top: 7.899999999999977
    naturalHeight: 800 //image的natureHeight,natureWidth
    naturalWidth: 500
    ratio: 0.90625     // width/natureWidth 当前图片初始化的放缩比例
    rotate: 0          //当前用户操作图片旋转的角度
    scaleX: 1          //当前用户操作图片放缩比例
    scaleY: 1  
}复制代码

//在初始化时候生成,存储展示的图片列表信息(通过读取传入id里的img信息)
images[
    img:{
        dataset:{
            originalUrl:src //这里的数据会在切换图片的时候在这里取放在src
        }
    }
]复制代码

//存储当前页面的宽度和长度
viewData{
    width:000,
    height:000
}
//存储一开始的imageData的信息
initialImageData{
    
}复制代码

//下面缩略图导航列表的数据
items[
    li,li
]复制代码
viewJs会在打开的时候会有读取我们id内的DOM,并做初始化。这时在DOM中读取数据就会放在以上几个对象中。
所以当我保存后,图片是不能够实时刷新的。需要我们手动去改变,把保存后的数据放入以上图片中。

1、首先我们只是改变了当前图片的src。
需要注意的是如果保存后的图片路径没有改变需要给src加一时间戳保证图片重新去请求。

let imgEl = document.querySelector('.viewer-canvas img')//返回的数据可能有date参数
imgEl.src = newUrl复制代码

2、相应的缩略图的src也需要改变

//修改选中缩略图的src及当前展示图片的src
const imageActive = document.querySelector('.viewer-list .viewer-active img')
imageActive.src = httpUrl复制代码

3、这样我们需要做相应改变的有图片展示的宽高(宽高是经过比例设置的,保证不超过屏幕)
我们只需要在图片旋转为90,270的时候,img的宽高进行调换并对imageData中的数据进行重新赋值,并调用renderImage对当前图片进行重置。

//当图片旋转保存时,需要对当前展示的图片进行宽高重新计算和渲染
  if(rotate % 180 === 90) {
    let viewer = window.viewer
    let imageData =  viewer.imageData
    let viewerData = viewer.viewerData
    let b = imageData.naturalHeight
    
    imageData.naturalHeight =  imageData.naturalWidth
    imageData.naturalWidth = b
    imageData.aspectRatio =  imageData.naturalWidth /  imageData.naturalHeight
    const footerHeight = viewer.footer.offsetHeight
    let viewerHeight = Math.max(viewerData.height - footerHeight, footerHeight)

    if (viewerHeight * imageData.aspectRatio >  viewerData.width) {
      imageData.height = Math.min((viewerData.width /  imageData.aspectRatio), imageData.naturalHeight) 
      imageData.width = Math.min(viewerData.width, imageData.naturalWidth)
    } else {
      imageData.width = Math.min((viewerHeight *  imageData.aspectRatio), imageData.naturalWidth)
      imageData.height =  Math.min(viewerData.height, imageData.naturalHeight)
    }
    imageData.ratio =  imageData.width /  imageData.naturalWidth
    
    imageData.left = ( viewerData.width - Math.min( imageData.width*0.9,  imageData.naturalWidth))/2
    imageData.top = (viewerHeight - Math.min( imageData.height*0.9,  imageData.naturalHeight))/2

  }
  window.viewer.imageData.rotate = 0
  window.viewer.imageData.scaleX = 1
  window.viewer.imageData.scaleY = 1
  console.log(window.viewer.element)
  // window.viewer.rotateTo(0)
  window.viewer.renderImage()复制代码

4、我们还需要考虑当左右切换的时候,这里有一个坑。这里他取的img的datset.originalUrl中的数据,不是直接去的img的src。在替换的时候需要把originUrl进行替换

//修改viewer组件中的缓存数据
  for(let i=0;i -1){
      window.viewer.images[i].src  = httpUrl
      window.viewer.items[i].querySelector('img').setAttribute(`data-original-url`, httpUrl)
      break
    }
  }复制代码

到这里这个需求大致修补完成,勉强能用了
优化:点击旋转的时候,会改变imageData的rotate。在renderImage的时候会发现有旋转。交互不太
需要保存的时候先隐藏img,添加加载项。再image.onload函数中再复现img

let canvas =  document.querySelector('.viewer-canvas')
  let imgEl = document.querySelector('.viewer-canvas img')//返回的数据可能有date参数
  canvas.classList.add('viewer-loading')
  imgEl.style.display = 'none'//使用visibility,并能及时隐藏
  
  imgEl.onload = function () {
    canvas.classList.remove('viewer-loading')
    imgEl.style.display = 'block'
  }复制代码

总结:
经过添加保存按钮,把viewJs进行了一次系统的学习。对其中的原理有了更清晰的认识。初始化的拆分,工具函数的拆分,渲染函数的拆分都给了我很大的启发。

附:

viewJS


转载于:https://juejin.im/post/5d006ce46fb9a07ee0630f2b

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值