Skip to content

Commit

Permalink
边框回弹完善中
Browse files Browse the repository at this point in the history
  • Loading branch information
SSShooter committed Mar 7, 2018
1 parent 433ad40 commit 778f4e6
Show file tree
Hide file tree
Showing 7 changed files with 776 additions and 30 deletions.
6 changes: 6 additions & 0 deletions .babelrc
@@ -0,0 +1,6 @@
{
"presets": [
["env", { "modules": false }],
"stage-3"
]
}
9 changes: 9 additions & 0 deletions .editorconfig
@@ -0,0 +1,9 @@
root = true

[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
12 changes: 12 additions & 0 deletions .gitignore
@@ -0,0 +1,12 @@
.DS_Store
node_modules/
dist/
npm-debug.log
yarn-error.log

# Editor directories and files
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
138 changes: 108 additions & 30 deletions src/App.vue
@@ -1,59 +1,137 @@
<template>
<div id="img-vuer">
<div>
<img v-finger:pinch="handlePinch" v-finger:doubleTap="handleDoubleTap" src="https://wx1.sinaimg.cn/mw690/6694d955ly1fp2xwc9dbzj20hs0ouq5g.jpg">
<div id="imgBox" style="position:relative;width: 100%;height: 100%;left:0;top:0;
background:rgba(0,0,0,0.5);display: none;">
<img style="position:absolute;width: 100%;" v-finger:pinch="handlePinch" v-finger:doubleTap="handleDoubleTap" v-finger:multipointStart="handleMultipointStart" v-finger:multipointEnd="handleMultipointEnd" v-finger:pressMove="handlePressMove" v-finger:touchEnd="handleTouchEnd" src="https://wx1.sinaimg.cn/mw690/6694d955ly1fp2xwc9dbzj20hs0ouq5g.jpg">
</div>
</div>
</template>

<script>
import vfinger from 'v-finger-mk42'
import Transform from './transform.js'
import To from './to.js'
import Vue from 'vue'
Vue.use(vfinger)
export default {
name: 'app',
data() {
return {
thisImgInitHeight: '',
thisImgInitWidth: '',
isZooming: false
thisScale: 1,
isZooming: false,
topPx: 0,
overflowX: '',
overflowY: ''
}
},
mounted() {
document.querySelector('img').style.width = this.thisImgInitWidth =
window.screen.availWidth + 'px'
document.querySelector('img').style.height = 'auto'
this.$nextTick(() => {
document.querySelector('img').style.height = this.thisImgInitHeight =
document.querySelector('img').height + 'px'
let vm = this
function imageLoaded(selector, onload) {
var img = new Image()
var dom = document.querySelector(selector)
img.onload = function() {
onload.call(dom, this.width, this.height)
img.onload = null
img = null
}
img.src = dom.getAttribute('src')
}
imageLoaded('img', function(w, h) {
document.querySelector('#imgBox').style.display = 'block'
vm.topPx = (window.innerHeight - h / w * window.innerWidth) / 2
this.style.top = vm.topPx + 'px'
})
Transform(document.querySelector('img'))
},
methods: {
handleMultipointStart(e, el) {
this.thisScale = el.scaleX
},
handleMultipointEnd(e, el) { },
handlePressMove(e, el) {
var box = el.getBoundingClientRect()
if (box.right < window.innerWidth) {
this.overflowX = 'right'
el.translateX += e.deltaX / 3
el.translateY += e.deltaY / 3
e.preventDefault()
}
else if (box.left > 0) {
this.overflowX = 'left'
el.translateX += e.deltaX / 3
el.translateY += e.deltaY / 3
e.preventDefault()
}
else if (box.right < window.innerWidth) {
this.overflowX = 'bottom'
el.translateX += e.deltaX / 3
el.translateY += e.deltaY / 3
e.preventDefault()
}
else if (box.top > 0) {
this.overflowY = 'top'
el.translateX += e.deltaX / 3
el.translateY += e.deltaY / 3
e.preventDefault()
} else {
el.translateX += e.deltaX
el.translateY += e.deltaY
e.preventDefault()
}
},
handlePinch(e, el) {
console.log(e)
// let left = el.getBoundingClientRect().left
// let top = el.getBoundingClientRect().top
// let originX = e.changedTouches[0].clientX - left
// let originY = e.changedTouches[0].clientY - top
// el.style['transform-origin'] = `${originX}px ${originY}px 0`
el.style.transform = `scale(${(e.zoom-1)/5+1})`
el.scaleX = el.scaleY = this.thisScale * e.zoom
},
handleTouchEnd(e, el) {
if (el.scaleX < 1) {
new To(el, 'scaleX', 1, 500, this.ease)
new To(el, 'scaleY', 1, 500, this.ease)
} else {
var box = el.getBoundingClientRect()
let translateBorderX = (el.scaleX - 1) * box.width / el.scaleX / 2
let translateBorderY = (el.scaleY - 1) * box.height / el.scaleY / 2
if (this.overflowX == 'left') {
new To(el, 'translateX', translateBorderX, 500, this.ease)
}
else if (this.overflowX == 'right') {
new To(el, 'translateX', -translateBorderX, 500, this.ease)
}
if (this.overflowY == 'top') {
new To(el, 'translateY', translateBorderY, 500, this.ease)
}
else if (this.overflowY == 'bottom') {
new To(el, 'translateY', -translateBorderY, 500, this.ease)
}
this.overflowX = this.overflowY = ''
}
},
handleDoubleTap(e, el) {
console.log(e)
if (!this.isZooming) {
let left = el.getBoundingClientRect().left
let top = el.getBoundingClientRect().top
console.log(left, top)
let originX = e.changedTouches[0].clientX - left
let originY = e.changedTouches[0].clientY - top
console.log(`${originX}px ${originY}px 0`)
el.style['transform-origin'] = `${originX}px ${originY}px 0`
el.style.transform = 'scale(2)'
this.isZooming = true
if (el.scaleX != 1) {
new To(el, 'scaleX', 1, 500, this.ease)
new To(el, 'scaleY', 1, 500, this.ease)
new To(el, 'translateX', 0, 500, this.ease)
new To(el, 'translateY', 0, 500, this.ease)
} else {
el.style.transform = 'scale(1)'
this.isZooming = false
var box = el.getBoundingClientRect()
var y =
box.height -
(e.changedTouches[0].pageY - this.topPx) * 2 -
(box.height / 2 - (e.changedTouches[0].pageY - this.topPx))
var x =
box.width -
e.changedTouches[0].pageX * 2 -
(box.width / 2 - e.changedTouches[0].pageX)
new To(el, 'scaleX', 2, 500, this.ease)
new To(el, 'scaleY', 2, 500, this.ease)
new To(el, 'translateX', x, 500, this.ease)
new To(el, 'translateY', y, 500, this.ease)
}
},
ease(x) {
return Math.sqrt(1 - Math.pow(x - 1, 2))
}
}
}
Expand Down
Binary file removed src/assets/logo.png
Binary file not shown.
72 changes: 72 additions & 0 deletions src/to.js
@@ -0,0 +1,72 @@
;(function() {
var lastTime = 0
var vendors = ['webkit', 'moz']
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']
window.cancelAnimationFrame =
window[vendors[x] + 'CancelAnimationFrame'] ||
window[vendors[x] + 'CancelRequestAnimationFrame']
}

if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback) {
var currTime = new Date().getTime()
var timeToCall = Math.max(0, 16 - (currTime - lastTime))
var id = window.setTimeout(function() {
callback(currTime + timeToCall)
}, timeToCall)
lastTime = currTime + timeToCall
return id
}

if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id)
}
})()

var To = function(el, property, value, time, ease, onEnd, onChange) {
var current = el[property]
var dv = value - current
var beginTime = new Date()
var self = this
var currentEase =
ease ||
function(a) {
return a
}
this.tickID = null
var toTick = function() {
var dt = new Date() - beginTime
if (dt >= time) {
el[property] = value
onChange && onChange(value)
onEnd && onEnd(value)
cancelAnimationFrame(self.tickID)
self.toTick = null
return
}
el[property] = dv * currentEase(dt / time) + current
self.tickID = requestAnimationFrame(toTick)
//self.tickID = requestAnimationFrame(toTick);
//cancelAnimationFrame������ tickID = requestAnimationFrame(toTick);���
onChange && onChange(el[property])
}
toTick()
To.List.push(this)
}

To.List = []

To.stopAll = function() {
for (var i = 0, len = To.List.length; i < len; i++) {
cancelAnimationFrame(To.List[i].tickID)
}
To.List.length = 0
}

To.stop = function(to) {
cancelAnimationFrame(to.tickID)
}

export default To

0 comments on commit 778f4e6

Please sign in to comment.