123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- import Hammer from 'hammerjs' // 引用hammerjs
- // 定义缩放方法,接收一个element参数:使用export暴露该方法
- export function zoomElement(el) {
- function point2D(x, y) {
- return { x: x, y: y }
- }
- // 判断 正数,负数,不是数字
- function checkNumType(num) {
- var reg = new RegExp('^-?[0-9]*.?[0-9]*$')
- if (reg.test(num)) {
- // 用于检测一个字符串是否匹配某个模式
- var absVal = Math.abs(num) // 如果参数是非负数,则返回该参数;如果参数是负数,则返回该参数的相反数。
- return num == absVal ? true : false
- } else {
- console.log('this is not number')
- }
- }
- function exChangeNum(num, reNum) {
- let flag = checkNumType(num)
- let reFlag = checkNumType(reNum)
- let realNum = 0
- if (!flag && reFlag) {
- realNum = Number('-' + reNum)
- } else {
- realNum = Number(reNum)
- }
- return realNum
- }
- var reqAnimationFrame = (function () {
- return (
- window[Hammer.prefixed(window, 'requestAnimationFrame')] ||
- function (callback) {
- window.setTimeout(callback, 1000 / 60)
- }
- )
- })()
- var ticking = false
- var tMatrix = [1, 0, 0, 1, 0, 0] //x缩放,无,无,y缩放,x平移,y平移
- var initScale = 1 //初始化scale
- el.addEventListener('touchmove', function (e) {
- e.preventDefault()
- })
- var mc = new Hammer.Manager(el)
- var nowScale = 0
- var poscenter = point2D(0, 0) // 缓存双指的中心坐标
- var duration = '' // 设置过渡效果,用于双击缩放效果
- var lastTranslate = point2D(0, 0) // 记录上次的偏移值
- var lastcenter = point2D(el.offsetWidth / 2, el.offsetHeight / 2) // 图像的中心点,用于对比双指中心点
- var center = lastcenter // 初始化为图片中心点
- // 添加缩放事件
- mc.add(new Hammer.Pan({ threshold: 0, pointers: 1 }))
- mc.add(new Hammer.Pinch({ threshold: 0 }))
- mc.add(new Hammer.Tap({ event: 'doubletap', taps: 2 }))
- mc.on('pinchstart', onPinchStart) // 双指缩放
- mc.on('pinchmove', onPinch) // 双指移动
- mc.on('panmove', onPan)
- mc.on('panstart', onPanStart)
- // 缩放开始
- function onPinchStart(ev) {
- duration = ''
- lastTranslate = point2D(tMatrix[4], tMatrix[5]) //记录上一次的偏移值 0 0
- initScale = tMatrix[0] || 1
- // 手势中心点
- poscenter = point2D(ev.center.x, ev.center.y)
- // 图像中心点 = 初始化图像中心点 + 上一次偏移量的中心点
- lastcenter = point2D(center.x + lastTranslate.x, center.y + lastTranslate.y) //重新计算放大后的中心坐标
- // 手势中心点 = 缩放中心点 - 图像中心点
- poscenter = point2D(ev.center.x - lastcenter.x, ev.center.y - lastcenter.y)
- requestElementUpdate('onpinchStart')
- }
- // 缩放途中
- function onPinch(ev) {
- // 缩放倍数 这里的缩放倍数
- nowScale = initScale * ev.scale
- // 如果倍数小于1 则等于1
- if (nowScale < 1) {
- nowScale = 1
- }
- // 缩放倍数
- tMatrix[0] = tMatrix[3] = nowScale
- let x = Number((1 - ev.scale) * poscenter.x + lastTranslate.x)
- let y = Number((1 - ev.scale) * poscenter.y + lastTranslate.y)
- let tempPosX = el.getBoundingClientRect().width / 2 - point2D(el.offsetWidth / 2, el.offsetHeight / 2).x
- let tempPosY = el.getBoundingClientRect().height / 2 - point2D(el.offsetWidth / 2, el.offsetHeight / 2).y
- if (Math.abs(x) > Math.abs(tempPosX)) {
- x = exChangeNum(x, tempPosX)
- }
- if (Math.abs(y) > Math.abs(tempPosY)) {
- y = exChangeNum(y, tempPosY)
- }
- tMatrix[4] = x
- tMatrix[5] = y
- requestElementUpdate('onpinch')
- }
- // 开始拖动
- function onPanStart() {
- lastTranslate = point2D(tMatrix[4], tMatrix[5]) // 缓存上一次的偏移值
- }
- // 拖动过程
- function onPan(ev) {
- tMatrix[0] = tMatrix[3] = nowScale || initScale
- // 拖动的动画 1.6
- duration = '1.6'
- let x = Number(lastTranslate.x + ev.deltaX)
- let y = Number(lastTranslate.y + ev.deltaY)
- let tempPosX = el.getBoundingClientRect().width / 2 - point2D(el.offsetWidth / 2, el.offsetHeight / 2).x
- let tempPosY = el.getBoundingClientRect().height / 2 - point2D(el.offsetWidth / 2, el.offsetHeight / 2).y
- if (Math.abs(x) > Math.abs(tempPosX)) {
- x = exChangeNum(x, tempPosX)
- }
- if (Math.abs(y) > Math.abs(tempPosY)) {
- y = exChangeNum(y, tempPosY)
- }
- tMatrix[4] = x
- tMatrix[5] = y
- requestElementUpdate('onpan')
- }
- // 每次都会·更新 因为是在移动端 所以都采用rem 否则可以直接用matrix
- function updateElementTransform() {
- el.style.transition = duration
- let x = tMatrix[4] + 'px'
- let y = tMatrix[5] + 'px'
- el.style.transform = 'translate(' + x + ',' + y + ') ' + 'scale(' + tMatrix[0] + ',' + tMatrix[3] + ')'
- el.style.WebkitTransform = 'translate(' + x + ',' + y + ') ' + 'scale(' + tMatrix[0] + ',' + tMatrix[3] + ')'
- el.style.msTransform = 'translate(' + x + ',' + y + ') ' + 'scale(' + tMatrix[0] + ',' + tMatrix[3] + ')'
- // var tmp = tMatrix.join(',')
- // el.style.transform = 'matrix(' + tmp + ')'
- // el.style.WebkitTransform = 'matrix(' + tmp + ')'
- // el.style.msTransform = 'matrix(' + tmp + ')'
- ticking = false
- }
- function requestElementUpdate() {
- if (!ticking) {
- reqAnimationFrame(updateElementTransform)
- ticking = true
- }
- }
- /**
- 初始化设置
- */
- requestElementUpdate()
- }
|