この記事では、主に iOS ネイティブ ピッカー効果の Vue 実装と実装アイデアの分析を紹介します。必要な友人は参考にしてください。
同様の時間選択プラグインがありました。以前に初めて実装されましたが、適用範囲が狭すぎるため、この実装を最近リリースして、再利用性の高い vue コンポーネントを書き直したいと考えています。 Android 4.0以降をサポートし、Safari 7以降のPreview
Github
MainDom Structure of the Scroll wheelpart
rreee
cssスタイルを垂直に中央に配置する
スクローラー 3D スタイル設定 <template data-filtered="filtered">
<p class="pd-select-item">
<p class="pd-select-line"></p>
<ul class="pd-select-list">
<li class="pd-select-list-item">1</li>
</ul>
<ul class="pd-select-wheel">
<li class="pd-select-wheel-item">1</li>
</ul>
</p>
</template>
props
props: {
data: {
type: Array,
required: true
},
type: {
type: String,
default: 'cycle'
},
value: {}
}
主に 2 つの属性に注意してください:transform-style:preserve-3d;backface-visibility:hidden;
1 つ目は、インターフェイスを 3D にするための 3D レイアウトです。 2つ目は、スクロールホイールの裏側を自動的に非表示にする(その1) 画像の赤い部分、裏側のDOMノードが自動的に非表示になります)3Dスクロールホイールの実装方法
ボックス主にこの CSS 変換を使用します:rotate3d(1, 0, 0, x deg);
項目は主にこの CSS 変換を使用します:rotate3d(1, 0, 0, xdeg) translation3d(0px, 0px, [x]px);
上の2つの写真はtranslate3d(0px, 0px, [x]px)を示しています;この文の効果[x]は円の半径です
上の図では、各 dom 自体を回転させてから、translate3d(0px, 0px, [x]px); を使用するだけで済みます。α は各 dom の回転角度です。ここでは 0 ~ 180° が使用され、これらの dom を保持するためにボックスが使用されます
行の高さと角度の計算
http://tool.520101.com/calculator/sanjiaoxingjiaodu/
無限スクロールホイールの実装
.pd-select-line, .pd-select-list, .pd-select-wheel { position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%); } .pd-select-list { overflow: hidden; }
touchendは特別な処理を行います
touchendでsetCSSタイプを設定してスクロールデータを丸めます。停止すると、一度に 1 フレームずつ正確に回転します
/* 滚轮盒子 */ .pd-select-wheel { transform-style: preserve-3d; height: 30px; } /* 滚轮单项 */ .pd-select-wheel-item { white-space: nowrap; text-overflow: ellipsis; backface-visibility: hidden; position: absolute; top: 0px; width: 100%; overflow: hidden; }
現在選択されている値を取得します
/* 滚轮展示大小限定 */ spin: {start: 0, end: 9, branch: 9} /* 获取spin 数据 */ getSpinData (index) { index = index % this.listData.length return this.listData[index >= 0 ? index : index + this.listData.length] } /* 模运算 获取数组有的索引 这样就构成 圆环了 */
初期化設定
// other code .... /* 计算touchEnd移动的整数距离 */ let endMove = margin let endDeg = Math.round(updateDeg / deg) * deg if (type === 'end') { this.setListTransform(endMove, margin) this.setWheelDeg(endDeg) } else { this.setListTransform(updateMove, margin) this.setWheelDeg(updateDeg) } // other code .... 惯性缓动 // other code .... setWheelDeg (updateDeg, type, time = 1000) { if (type === 'end') { this.$refs.wheel.style.webkitTransition = `transform ${time}ms cubic-bezier(0.19, 1, 0.22, 1)` this.$refs.wheel.style.webkitTransform = `rotate3d(1, 0, 0, ${updateDeg}deg)` } else { this.$refs.wheel.style.webkitTransition = '' this.$refs.wheel.style.webkitTransform = `rotate3d(1, 0, 0, ${updateDeg}deg)` } } setListTransform (translateY = 0, marginTop = 0, type, time = 1000) { if (type === 'end') { this.$refs.list.style.webkitTransition = `transform ${time}ms cubic-bezier(0.19, 1, 0.22, 1)` this.$refs.list.style.webkitTransform = `translateY(${translateY - this.spin.branch * 34}px)` this.$refs.list.style.marginTop = `${-marginTop}px` this.$refs.list.setAttribute('scroll', translateY) console.log('end') } else { this.$refs.list.style.webkitTransition = '' this.$refs.list.style.webkitTransform = `translateY(${translateY - this.spin.branch * 34}px)` this.$refs.list.style.marginTop = `${-marginTop}px` this.$refs.list.setAttribute('scroll', translateY) } } // other code ....
非無限スクロールホイールとして表示されている場合
ここで簡単に判断できます。つまり、スクロール距離は元の数値の配列長 * 34 を超えることはできず、0 未満にすることはできません (実際のコードに関係する方向)
/* 在设置完css后获取值 */ setStyle (move, type, time) { // ...other code /* 设置$emit 延迟 */ setTimeout(() => this.getPickValue(endMove), 1000) // ...other code } /* 获取选中值 */ getPickValue (move) { let index = Math.abs(move / 34) let pickValue = this.getSpinData(index) this.$emit('input', pickValue) }
dom 構造体 対応するレスポンスも追加されました rreee
以上が皆さんのためにまとめたもので、今後皆さんのお役に立てれば幸いです。関連記事:
JavaScriptモジュールの最適化
webpackを使用してサードパーティライブラリを抽出する方法
JSを使用してクライアントタイプを決定する方法
以上がVueでピッカーエフェクトを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。