ホームページ >ウェブフロントエンド >jsチュートリアル >Vue はスライディング スタッキング コンポーネントを実装します

Vue はスライディング スタッキング コンポーネントを実装します

php中世界最好的语言
php中世界最好的语言オリジナル
2018-04-11 16:30:122674ブラウズ

今回は、vue でのスライド スタッキング コンポーネントの実装について説明します。vue でスライド スタッキング コンポーネントを実装する際の 注意事項 については、次のとおりです。

はじめに

こんにちは、Tantan について言えば、皆さんはこのプログラムに精通していると思います (結局のところ、多くの女の子がいます) Tantan の積み重ねられたスライド コンポーネントが、ブランドをスムーズに切り替えることができるようにする重要な役割を果たします。 vueで書くとタンタンスタッキングコンポーネント

1. 機能分析

基本的な機能ポイントの簡単な概要:

  • 写真の積み重ね

  • 最初の写真のスライド


  • 条件が成功した後のスライドアウト、条件が失敗した後のリバウンド


  • 次の写真は、後で上に積み重ねられますスライドアウト


  • 体験の最適化


  • 異なるタッチポイントに応じて、スライド時に最初の画像が異なる角度でオフセットされます


  • オフセット領域は、スライドアウトが成功しました


2. 具体的な実装

機能のポイントをまとめると、コンポーネントの実装のアイデアがより明確になります

1. スタッキング効果

インターネット上には、スタックされた画像効果の例が多数あります。実装方法は主に、親レイヤーにパースペクティブとパースペクティブ原点を設定することで実現されます。サブレイヤーにtranslate3dのZ軸値を設定する場合、具体的なコードは次のとおりです

// 图片堆叠dom
 <!--opacity: 0 隐藏我们不想看到的stack-item层级-->
 <!--z-index: -1 调整stack-item层级"-->
<ul class="stack">
 <li class="stack-item" style="transform: translate3d(0px, 0px, 0px);opacity: 1;z-index: 10;"><img src="1.png" alt="01"></li>
 <li class="stack-item" style="transform: translate3d(0px, 0px, -60px);opacity: 1;z-index: 1"><img src="2.png" alt="02"></li>
 <li class="stack-item" style="transform: translate3d(0px, 0px, -120px);opacity: 1;z-index: 1"><img src="3.png" alt="03"></li>
 <li class="stack-item" style="transform: translate3d(0px, 0px, -180px);opacity: 0;z-index: -1"><img src="4.png" alt="04"></li>
 <li class="stack-item" style="transform: translate3d(0px, 0px, -180px);opacity: 0;z-index: -1"><img src="5.png" alt="05"></li>
</ul>
<style>
.stack {
 width: 100%;
 height: 100%;
 position: relative;
 perspective: 1000px; //子元素视距
 perspective-origin: 50% 150%; //子元素透视位置
 -webkit-perspective: 1000px;
 -webkit-perspective-origin: 50% 150%;
 margin: 0;
 padding: 0;
 }
 .stack-item{
 background: #fff;
 height: 100%;
 width: 100%;
 border-radius: 4px;
 text-align: center;
 overflow: hidden;
 }
 .stack-item img {
 width: 100%;
 display: block;
 pointer-events: none;
 }
</style>
上記は単なる静的コードのセットであるため、最初にコンポーネント テンプレート stack.vue を作成する必要があります。このテンプレートでは、v-for を使用してスタック ノードを走査し、使用することができます。 :style 各項目のスタイルを変更するコードは次のとおりです

<template>
 <ul class="stack">
  <li class="stack-item" v-for="(item, index) in pages" :style="[transform(index)]">
  <img :src="item.src">
  </li>
 </ul>
</template>
<script>
export default {
 props: {
 // pages数据包含基础的图片数据
 pages: {
  type: Array,
  default: []
 }
 },
 data () {
 return {
  // basicdata数据包含组件基本数据
  basicdata: {
  currentPage: 0 // 默认首图的序列
  },
  // temporaryData数据包含组件临时数据
  temporaryData: {
  opacity: 1, // 记录opacity
  zIndex: 10, // 记录zIndex
  visible: 3 // 记录默认显示堆叠数visible
  }
 }
 },
 methods: {
 // 遍历样式
 transform (index) {
  if (index >= this.basicdata.currentPage) {
  let style = {}
  let visible = this.temporaryData.visible
  let perIndex = index - this.basicdata.currentPage
  // visible可见数量前滑块的样式
  if (index <= this.basicdata.currentPage + visible - 1) {
   style[&#39;opacity&#39;] = &#39;1&#39;
   style[&#39;transform&#39;] = &#39;translate3D(0,0,&#39; + -1 * perIndex * 60 + &#39;px&#39; + &#39;)&#39;
   style[&#39;zIndex&#39;] = visible - index + this.basicdata.currentPage
   style[&#39;transitionTimingFunction&#39;] = &#39;ease&#39;
   style[&#39;transitionDuration&#39;] = 300 + &#39;ms&#39;
  } else {
   style[&#39;zIndex&#39;] = &#39;-1&#39;
   style[&#39;transform&#39;] = &#39;translate3D(0,0,&#39; + -1 * visible * 60 + &#39;px&#39; + &#39;)&#39;
  }
  return style
  }
 }
 }
}
</script>

キーポイント

:style はオブジェクトだけでなく配列や関数もバインドできるので、トラバースするときに非常に便利です。次のステップでは、最初の画像を「移動」します。

2. 画像スライド

画像のスライディング効果は、多くのシーンで使用されます。その原理は、タッチ イベントをリッスンし、変位を取得し、translate3D を通じてターゲットの変位を変更するだけです。したがって、実装したい手順は次のとおりです

。 タッチイベントをスタックにバインドします

  • ジェスチャー位置の変更の値を監視して保存します


  • 最初の画像の css 属性のtranslate3Dのx、y値を変更します


  • #### 具体的な実装

  • vue フレームワークでは、ノードを直接操作するのではなく、v-on 命令を通じて要素をバインドすることが推奨されています。そのため、すべてのバインディングを v-for traversal で記述し、最初の画像であるかどうかをインデックスを使用して判断します。次に、:style を使用してホームページのスタイルを変更します。具体的なコードは次のとおりです:
<template>
 <ul class="stack">
  <li class="stack-item" v-for="(item, index) in pages"
  :style="[transformIndex(index),transform(index)]"
  @touchstart.stop.capture="touchstart"
  @touchmove.stop.capture="touchmove"
  @touchend.stop.capture="touchend"
  @mousedown.stop.capture="touchstart"
  @mouseup.stop.capture="touchend"
  @mousemove.stop.capture="touchmove">
  <img :src="item.src">
  </li>
 </ul>
</template>
<script>
export default {
 props: {
 // pages数据包含基础的图片数据
 pages: {
  type: Array,
  default: []
 }
 },
 data () {
 return {
  // basicdata数据包含组件基本数据
  basicdata: {
  start: {}, // 记录起始位置
  end: {}, // 记录终点位置
  currentPage: 0 // 默认首图的序列
  },
  // temporaryData数据包含组件临时数据
  temporaryData: {
  poswidth: '', // 记录位移
  posheight: '', // 记录位移
  tracking: false // 是否在滑动,防止多次操作,影响体验
  }
 }
 },
 methods: {
 touchstart (e) {
  if (this.temporaryData.tracking) {
  return
  }
  // 是否为touch
  if (e.type === 'touchstart') {
  if (e.touches.length > 1) {
   this.temporaryData.tracking = false
   return
  } else {
   // 记录起始位置
   this.basicdata.start.t = new Date().getTime()
   this.basicdata.start.x = e.targetTouches[0].clientX
   this.basicdata.start.y = e.targetTouches[0].clientY
   this.basicdata.end.x = e.targetTouches[0].clientX
   this.basicdata.end.y = e.targetTouches[0].clientY
  }
  // pc操作
  } else {
  this.basicdata.start.t = new Date().getTime()
  this.basicdata.start.x = e.clientX
  this.basicdata.start.y = e.clientY
  this.basicdata.end.x = e.clientX
  this.basicdata.end.y = e.clientY
  }
  this.temporaryData.tracking = true
 },
 touchmove (e) {
  // 记录滑动位置
  if (this.temporaryData.tracking && !this.temporaryData.animation) {
  if (e.type === 'touchmove') {
   this.basicdata.end.x = e.targetTouches[0].clientX
   this.basicdata.end.y = e.targetTouches[0].clientY
  } else {
   this.basicdata.end.x = e.clientX
   this.basicdata.end.y = e.clientY
  }
  // 计算滑动值
  this.temporaryData.poswidth = this.basicdata.end.x - this.basicdata.start.x
  this.temporaryData.posheight = this.basicdata.end.y - this.basicdata.start.y
  }
 },
 touchend (e) {
  this.temporaryData.tracking = false
  // 滑动结束,触发判断
 },
 // 非首页样式切换
 transform (index) {
  if (index > this.basicdata.currentPage) {
  let style = {}
  let visible = 3
  let perIndex = index - this.basicdata.currentPage
  // visible可见数量前滑块的样式
  if (index <= this.basicdata.currentPage + visible - 1) {
   style[&#39;opacity&#39;] = &#39;1&#39;
   style[&#39;transform&#39;] = &#39;translate3D(0,0,&#39; + -1 * perIndex * 60 + &#39;px&#39; + &#39;)&#39;
   style[&#39;zIndex&#39;] = visible - index + this.basicdata.currentPage
   style[&#39;transitionTimingFunction&#39;] = &#39;ease&#39;
   style[&#39;transitionDuration&#39;] = 300 + &#39;ms&#39;
  } else {
   style[&#39;zIndex&#39;] = &#39;-1&#39;
   style[&#39;transform&#39;] = &#39;translate3D(0,0,&#39; + -1 * visible * 60 + &#39;px&#39; + &#39;)&#39;
  }
  return style
  }
 },
 // 首页样式切换
 transformIndex (index) {
  // 处理3D效果
  if (index === this.basicdata.currentPage) {
  let style = {}
  style[&#39;transform&#39;] = &#39;translate3D(&#39; + this.temporaryData.poswidth + &#39;px&#39; + &#39;,&#39; + this.temporaryData.posheight + &#39;px&#39; + &#39;,0px)&#39;
  style[&#39;opacity&#39;] = 1
  style[&#39;zIndex&#39;] = 10
  return style
  }
 }
 }
}
</script>

3. 条件が成功するとスライドアウトし、条件が失敗するとリバウンドします

条件のトリガー判定は、タッチエンド/マウスアップ後に実行されます。ここでは、最初に簡単な条件を使用して判定し、同時に最初の画像のポップアップとリバウンド効果を与えます。 コードは次のとおりです。 4. スライドさせた後、次の写真が上に重ねられます

再スタックはコンポーネントの最後の機能であり、最も重要かつ複雑な機能でもあります。私たちのコードでは、スタック項目の並べ替えは、バインディングのtransformIndexとtransform関数に依存します: style。この関数で決定される条件は、currentPageを変更して、再スタックを完了するために+1する必要があるかどうかです。 ?

答えはそれほど単純ではありません。スライドアウトは 300 ミリ秒続くアニメーション効果であり、currentPage の変更によって引き起こされる再配置はすぐに変更され、アニメーションの進行が中断されるためです。したがって、最初にtransform関数のソート条件を変更してから、currentPageを変更する必要があります。 #### 具体的な実装

変換関数のソート条件を変更する

Let currentPage+

以上がVue はスライディング スタッキング コンポーネントを実装しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。