console
const AnyScrollView = Vue.component('any-scroll-view', {
template: `
<div class= "any-scroll-view">
<div ref = "body" :style = "bodyStyle" class = "any-scroll-view__body" >
<slot></slot>
</div>
</div>`,
name: 'any-scroll-view',
props: {
acceleration: {
type: Number,
default: 3600
}
},
data() {
return {
scrollTop: 0,
scrollLeft: 0,
transitionDuration: 300
};
},
computed: {
bodyStyle() {
return {
transitionDuration: `${this.transitionDuration}ms`,
transform: `translate(${this.scrollLeft}px, ${
this.scrollTop
}px)`
};
}
},
mounted() {
const at = new AnyTouch(this.$el);
at.on('inputstart', (ev) => {
ev.preventDefault();
this.stopRoll();
});
at.on('panstart', (ev) => {
this.move(ev);
});
at.on('panmove', (ev) => {
this.move(ev);
});
at.on('swipe', (ev) => {
this.decelerate(ev);
});
this.$on('hook:destroy', () => {
at.destroy();
});
},
methods: {
getCurrentTranslate() {
const style = getComputedStyle(this.$refs.body, null);
const { transform } = style;
const array = transform.match(/(\-?)(\d)+(\.\d{0,})?/g);
return { x: Math.round(array[4]), y: Math.round(array[5]) };
},
stopRoll() {
const { x, y } = this.getCurrentTranslate();
this.moveTo({ scrollTop: y, scrollLeft: x });
},
move({ deltaX, deltaY }, transitionDuration = 0) {
this.transitionDuration = transitionDuration;
this.scrollLeft += deltaX;
this.scrollTop += deltaY;
},
moveTo({ scrollTop, scrollLeft }, transitionDuration = 0) {
this.transitionDuration = transitionDuration;
this.scrollLeft = scrollLeft;
this.scrollTop = scrollTop;
},
decelerate(ev) {
const directionSign = { up: -1, right: 1, down: 1, left: -1 }[
ev.direction
];
let SCROLL_SUFFIX = 'Top';
let AXIS_SUFFIX = 'Y';
if (ev.velocityX > ev.velocityY) {
SCROLL_SUFFIX = 'Left';
AXIS_SUFFIX = 'X';
}
const velocity = ev[`velocity${AXIS_SUFFIX}`];
this.transitionDuration = Math.round(
((velocity * 1000) / this.acceleration) * 1000
);
const scrollAxis = `scroll${SCROLL_SUFFIX}`;
this[scrollAxis] +=
directionSign *
Math.round(
Math.pow(velocity * 1000, 2) / (2 * this.acceleration)
);
}
}
});
new Vue({
el: '#app',
components: {AnyScrollView}
});
<main id="app">
<any-scroll-view>
<img class="avator" src="https://s.cdpn.io/profiles/user/406915/80.jpg?1511329408"
width="100%">
<p align="center">
铁皮饭盒
</p>
<a class="github" target="_blank" href="https://github.com/383514580/any-touch">
github : any-touch</a>
</any-scroll-view>
</main>
<script src="https://vuejs.org/js/vue.min.js">
</script>
<script src="https://unpkg.com/any-touch/dist/AnyTouch.umd.js">
</script>
body {
padding: 0;
margin: 0;
overflow:hidden;
}
.any-scroll-view {
position: relative;
border: 1px solid #ddd;
width: 320px;
margin: 5vh auto;
height: 90vh;
overflow: hidden;
&__body {
transition-timing-function: cubic-bezier(0.1, 0.57, 0.1, 1);
background: #eee;
position: absolute;
width: 100%;
height: 100%;
.avator {
touch-action: none;
display: block;
width: 80px;
border-radius: 100%;
margin: 15px auto;
}
.github {
padding: 5px 15px;
background: #000;
color: #fff;
text-decoration: none;
display: block;
text-align: center;
border-radius: 6px;
margin: 60px auto;
width:150px;
}
}
}