提交 48e993db 编写于 作者: DCloud_JSON's avatar DCloud_JSON

更新 示例项目 pull-zoom-image 向上滚动时,头部图片不缩放,跟随内容移动

上级 365c3afc
<template> <template>
<view @click="back" class="nav-back"> <view @click="back" class="nav-back">
<image class="back-img" src="/static/template/scroll-fold-nav/back.png" mode="widthFix"></image> <image class="back-img" src="/static/template/scroll-fold-nav/back.png" mode="widthFix"></image>
</view> </view>
<view class="root" @touchstart="touchstart($event as TouchEvent)" @touchmove="touchmove($event as TouchEvent)" <view style="flex:1" @touchstart="touchstart($event as TouchEvent)" @touchmove="touchmove($event as TouchEvent)" @touchend="touchend" @touchcancel="touchend">
@touchend="touchend" @touchcancel="touchend"> <image class="head-img" ref="head-img" src="../../../static/template/pull-zoom-image/head-img.jpg" mode="scaleToFill"></image>
<image class="head-img" ref="head-img" src="../../../static/template/pull-zoom-image/head-img.jpg" <view class="body" ref="body">
mode="scaleToFill"></image> <view class="user-info">
<view class="body" ref="body"> <image class="user-avatar" src="../../../static/test-image/logo.png" mode="widthFix"></image>
<view class="user-info"> <view class="font-box">
<image class="user-avatar" src="../../../static/test-image/logo.png" mode="widthFix"></image> <text class="username">uni-app-x</text>
<view class="font-box"> <text class="slogan">一次开发,多端覆盖</text>
<text class="username">uni-app-x</text> </view>
<text class="slogan">一次开发,多端覆盖</text> </view>
</view> <view class="content">
</view> <view class="content-item">
<view class="content"> <text class="text">
<view class="content-item"> 1. 当前示例监听了整个页面的touchstart、touchmove、touchend事件 ,实现监听拖动事件。
<text class="text"> </text>
1. 当前示例监听了整个页面的touchstart、touchmove、touchend事件 ,实现监听拖动事件。 </view>
</text> <view class="content-item">
</view> <text class="text">
<view class="content-item"> 2. 在拖动事件,使用 ref 直接获取 ref="body" 元素的节点,通过节点的 setProperty 方法来修改 transform的translateY 的值(根据在Y轴方向拖动的距离),从而达到页面跟随手指上下拖动的效果。
<text class="text"> </text>
2. 在拖动事件,使用 ref 直接获取 ref="body" 元素的节点,通过节点的 setProperty 方法来修改 transform的translateY 的值(根据在Y轴方向拖动的距离),从而达到页面跟随手指上下拖动的效果。 </view>
</text> <view class="content-item">
</view> <text class="text">
<view class="content-item"> 3. 在拖动事件,使用 ref 直接获取 ref="head-img" 元素的节点,通过节点的 setProperty 方法来修改 transform的scale 的值(根据在Y轴方向拖动的距离),从而达到手指上下拖动时图片缩放的效果。
<text class="text"> </text>
3. 在拖动事件,使用 ref 直接获取 ref="head-img" 元素的节点,通过节点的 setProperty 方法来修改 transform的scale 的值(根据在Y轴方向拖动的距离),从而达到手指上下拖动时图片缩放的效果。 </view>
</text> <view class="content-item">
</view> <text class="text">
<view class="content-item"> 4. 在拖动完成事件,通过帧动画,设置上述两个元素回到原来的位置。
<text class="text"> </text>
4. 在拖动完成事件,通过帧动画,设置上述两个元素回到原来的位置。 </view>
</text> <view class="content-item">
</view> <text class="text">
<view class="content-item"> 5. 请向上\向下拖动页面观察效果。
<text class="text"> </text>
5. 请向上\向下拖动页面观察效果。 </view>
</text> <view class="content-item" v-for="(item,index) in 10" :key="index">
</view> <text class="text">content-{{item}}</text>
</view>
</view>
<!-- <view class="content-item" v-for="(item,index) in 6" :key="index"> </view>
<text class="text">content-{{item}}</text> </view>
</view> -->
</view>
</view>
</view>
</template> </template>
<script> <script>
let sY : number = 0, let sY : number = 0,
touchstartAfter : boolean = false; dY : number = 0,
maxScrollTop:number = 0;
export default { export default {
data() { data() {
return { return {
$nodeMap: new Map<string, INode>(), $nodeMap: new Map<string, INode>(),
y: 0 as number y: 0 as number,
scrollTop:0 as number
} }
},
onReady() {
uni.getSystemInfo({
success: (e) => {
maxScrollTop = 1425 - e.screenHeight
}
})
}, },
methods: { methods: {
doMove() { doMove() {
this.setINodeStyle("head-img", 'transform', `scale(${(this.y > 0 ? this.y : 0) / 200 + 1})`) // console.log('doMove',this.y);
if(this.y > 0){
this.setINodeStyle("head-img", 'transform', `scale(${(this.y > 0 ? this.y : 0) / 200 + 1})`)
}else{
this.setINodeStyle("head-img", 'transform', `translateY(${this.y})`)
}
this.setINodeStyle("body", 'transform', `translateY(${this.y})`) this.setINodeStyle("body", 'transform', `translateY(${this.y})`)
}, },
touchstart(e : TouchEvent) { touchstart(e : TouchEvent) {
// console.log('touchstart')
if (this.y !== 0) {
return
}
sY = e.touches[0].screenY; sY = e.touches[0].screenY;
touchstartAfter = true
}, },
touchmove(e : TouchEvent) { touchmove(e : TouchEvent) {
// console.log('touchmove') this.y += e.touches[0].screenY - sY;
if (!touchstartAfter) { dY = e.touches[0].screenY - sY
return sY = e.touches[0].screenY;
} this.doMove()
this.y += e.touches[0].screenY - sY;
sY = e.touches[0].screenY;
this.doMove()
}, },
touchend() { touchend() {
// console.log('touchend') // console.log('touchend')
touchstartAfter = false function moveTo(y : number, callback : () => void, speed : number = 10) {
let interval : number = 0
function moveTo(y : number, callback : () => void, speed : number = 10) { let acceleration : number = 1
let interval : number = 0 interval = setInterval(() => {
let acceleration : number = 1 // 加速度
interval = setInterval(() => { acceleration += 0.2
// 加速度
acceleration += 0.2 const dy = y - this.y
if (Math.abs(dy) < 1) {
const dy = y - this.y this.y = y
if (Math.abs(dy) < 1) { } else {
this.y = y this.y += dy / speed * acceleration
} else { }
this.y += dy / speed * acceleration
} // 滚动边界限制
this.doMove() if(this.y < maxScrollTop*-1){
if (this.y == y) { this.y = maxScrollTop*-1
clearInterval(interval) }
callback() if(this.y > 0){
} this.y = 0
}, 16) }
// console.log('this.y',this.y);
this.doMove()
if (this.y == y || this.y == maxScrollTop*-1 || this.y == 0) {
clearInterval(interval)
callback()
}
}, 16)
}
// console.log('dY',dY);
if(this.y < 0){
// console.log(dY);
moveTo(this.y + dY * 20, () => {
// console.log('done');
},5)
}else{
const bounceY = (this.y * -0.03).toInt()
// console.log('bounceY', bounceY);
moveTo(bounceY, () => {
moveTo(0, () => {
// console.log('done');
}, 30)
})
} }
const bounceY = (this.y * -0.03).toInt()
console.log('bounceY', bounceY);
moveTo(bounceY, () => {
moveTo(0, () => {
console.log('done');
}, 30)
})
}, },
// 工具方法,用于快速设置 INode 的 style // 工具方法,用于快速设置 INode 的 style
setINodeStyle(refName : string, propertyName : string, propertyStyle : any) : void { setINodeStyle(refName : string, propertyName : string, propertyStyle : any) : void {
...@@ -143,21 +162,17 @@ ...@@ -143,21 +162,17 @@
</script> </script>
<style> <style>
.root {
flex: 1;
}
.head-img { .head-img {
height: 350px; height: 350px;
width: 1000rpx; /* width: 1000rpx; */
margin-left: -125rpx; margin-left: -125rpx;
margin-top: -50px; margin-top: -50px;
background-color: #aab8d9; background-color: #aab8d9;
} }
.body { .body {
flex: 1; margin-top: -200px;
margin-top: -200px; width: 750rpx;
} }
.user-info { .user-info {
...@@ -191,28 +206,27 @@ ...@@ -191,28 +206,27 @@
.content { .content {
background-color: #FFF; background-color: #FFF;
border-radius: 10px; border-radius: 10px;
flex: 1; padding: 15px;
padding: 15px;
} }
.content-item { .content-item {
padding: 10px; padding: 15px;
margin-bottom: 2px; margin-bottom: 16px;
background-color: #fff; background-color: #fff;
border-radius: 5px; border-radius: 5px;
border: 1px solid rgba(220, 220, 220, 0.1); border: 1px solid rgba(220, 220, 220, 0.5);
} }
.text { .text {
font-size: 12px; font-size: 14px;
color: #666; color: #666;
line-height: 20px; line-height: 20px;
} }
.nav-back { .nav-back {
position: absolute; position: absolute;
top: 20px; top: 30px;
left: 8px; left: 10px;
background-color: rgba(220, 220, 220, 0.3); background-color: rgba(220, 220, 220, 0.3);
border-radius: 100px; border-radius: 100px;
width: 28px; width: 28px;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册