pull-zoom-image.uvue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <template>
  2. <view style="flex: 1">
  3. <view @click="back" class="nav-back">
  4. <image class="back-img" src="/static/template/pull-zoom-image/back.png" mode="widthFix"></image>
  5. </view>
  6. <scroll-view style="flex:1;" :refresher-enabled="true"
  7. refresher-default-style="none" @refresherpulling="onRefresherpulling"
  8. :refresher-threshold="300" :refresher-max-drag-distance="299"
  9. @scroll="onScroll" :bounces="false"
  10. >
  11. <view class="head-img-box-2" ref="head-img-box-2">
  12. <image class="img" ref="head-img-2" src="https://web-ext-storage.dcloud.net.cn/hello-uni-app-x/pull-zoom-image-head-img.jpg" mode="scaleToFill"></image>
  13. </view>
  14. <view class="user-info" ref="user-info">
  15. <image class="user-avatar" src="../../../static/test-image/logo.png" mode="widthFix"></image>
  16. <view class="font-box">
  17. <text class="username">uni-app-x</text>
  18. <text class="slogan">一次开发,多端覆盖</text>
  19. </view>
  20. </view>
  21. <view class="list-box">
  22. <view class="item" v-for="(item,index) in 30" :key="index">
  23. <text class="text">{{item}}. 占位</text>
  24. </view>
  25. </view>
  26. <!--#ifdef APP -->
  27. <view slot="refresher">
  28. <view class="head-img-box-1">
  29. <image class="img" ref="head-img-1" src="https://web-ext-storage.dcloud.net.cn/hello-uni-app-x/pull-zoom-image-head-img.jpg" mode="scaleToFill"></image>
  30. </view>
  31. </view>
  32. <!--#endif-->
  33. </scroll-view>
  34. </view>
  35. </template>
  36. <script>
  37. export default {
  38. data() {
  39. return {
  40. $elementMap: new Map<string, UniElement>()
  41. }
  42. },
  43. methods: {
  44. onScroll(e : ScrollEvent) {
  45. const {scrollTop} = e.detail
  46. let y : number = scrollTop - 110
  47. let s : number = (100 - scrollTop/3)/100
  48. if(y < 0){
  49. y = 0
  50. }
  51. if(s < 0.7){
  52. s = 0.7
  53. }
  54. let x : number = (1 - s) * -100
  55. this.setElementStyle("user-info", "transform", `translate(${x}px, ${y + (s-1)* -50}px) scale(${s})`)
  56. this.setElementStyle("head-img-box-2", "transform", `translateY(${y}px)`)
  57. },
  58. onRefresherpulling(e : RefresherEvent) {
  59. // console.log('onRefresherpulling',e.detail.dy)
  60. let pullingDistance : number = e.detail.dy
  61. this.setElementStyle("head-img-1", 'transform', `scale(${pullingDistance / 200 + 1})`)
  62. this.setElementStyle("head-img-2", 'transform', `scale(${pullingDistance / 200 + 1})`)
  63. },
  64. // 工具方法,用于快速设置 Element 的 style
  65. setElementStyle(refName : string, propertyName : string, propertyStyle : any) : void {
  66. let element : UniElement | null = (this.$data['$elementMap'] as Map<string, UniElement>).get(refName)
  67. if (element == null) {
  68. element = this.$refs[refName] as UniElement;
  69. (this.$data['$elementMap'] as Map<string, UniElement>).set(refName, element)
  70. }
  71. element.style.setProperty(propertyName, propertyStyle);
  72. },
  73. back() {
  74. uni.navigateBack({
  75. success(result) {
  76. console.log('navigateBack success', result.errMsg)
  77. },
  78. fail(error) {
  79. console.log('navigateBack fail', error.errMsg)
  80. },
  81. complete(result) {
  82. console.log('navigateBack complete', result.errMsg)
  83. }
  84. })
  85. }
  86. }
  87. }
  88. </script>
  89. <style>
  90. .head-img-box-1,
  91. .head-img-box-2
  92. {
  93. position: relative;
  94. height: 300px;
  95. }
  96. .head-img-box-1 .img,
  97. .head-img-box-2 .img
  98. {
  99. position: absolute;
  100. width: 100%;
  101. height: 600px;
  102. }
  103. .head-img-box-1 .img {
  104. top: 0px;
  105. }
  106. .head-img-box-2 .img {
  107. bottom: -100px;
  108. }
  109. .head-img-box-2 {
  110. z-index: 9;
  111. height: 200px;
  112. }
  113. .user-info{
  114. margin-top: -110px;
  115. flex: 1;
  116. padding: 15px;
  117. flex-direction: row;
  118. z-index: 10;
  119. }
  120. .user-info .user-avatar {
  121. width: 75px;
  122. height: 75px;
  123. border-radius: 100px;
  124. border: 3px solid #FFF;
  125. }
  126. .user-info .font-box {
  127. flex-direction: column;
  128. justify-content: space-around;
  129. padding: 10px;
  130. }
  131. .user-info .username {
  132. font-size: 26px;
  133. color: #FFF;
  134. }
  135. .user-info .slogan {
  136. font-size: 16px;
  137. color: #FFF;
  138. }
  139. .list-box {
  140. background-color: #FFF;
  141. z-index: 1;
  142. }
  143. .list-box .item {
  144. padding: 10px;
  145. margin: 5px;
  146. border-radius: 5px;
  147. border: 1px solid rgba(220, 220, 220, 0.3);
  148. }
  149. .list-box .text {
  150. font-size: 14px;
  151. color: #666;
  152. line-height: 20px;
  153. }
  154. .nav-back {
  155. position: absolute;
  156. top: 30px;
  157. left: 10px;
  158. border-radius: 100px;
  159. width: 28px;
  160. height: 28px;
  161. justify-content: center;
  162. align-items: center;
  163. z-index: 10;
  164. }
  165. .nav-back .back-img {
  166. width: 18px;
  167. height: 18px;
  168. }
  169. </style>