検索
ホームページウェブフロントエンドjsチュートリアルモバイルエフェクトに Picke を実装する方法

前に書いています

モバイルエフェクトに関する以前の研究に続き、今回はモバイルエフェクトに Picke を実装する方法セレクターの実装原理を見てみましょうモバイルエフェクトに Picke を実装する方法选择器的实现原理

移动端效果之Swiper

代码看这里:github

モバイルエフェクトに Picke を実装する方法

1. 核心解析

1.1 基本HTML结构


<!--     说明:    
1. 类 モバイルエフェクトに Picke を実装する方法-3d 是为了提供3d视角,如果不需要可以去掉    
2. 类 モバイルエフェクトに Picke を実装する方法-slot-absolute 在3d视角中需要加上,因为下面相对定位的 モバイルエフェクトに Picke を実装する方法-items 是要相对父容器进行    transform的,如果不加,就会造成位移不正确    3. DOM中所有的style样式都是在初始化的时候加上的--><p class="モバイルエフェクトに Picke を実装する方法 モバイルエフェクトに Picke を実装する方法-3d">
    <p class="モバイルエフェクトに Picke を実装する方法-items">
        <p class="モバイルエフェクトに Picke を実装する方法-slot モバイルエフェクトに Picke を実装する方法-slot-absolute" style="flex:1;">
            <p class="モバイルエフェクトに Picke を実装する方法-slot-wrapper" id="wrapper" style="height: 108px;">
                <p class="モバイルエフェクトに Picke を実装する方法-item モバイルエフェクトに Picke を実装する方法-selected" style="height:36px;line-height: 36px">1981</p>
                <!-- ... -->
                <p class="モバイルエフェクトに Picke を実装する方法-item" style="height:36px;line-height: 36px">1999</p>
            </p>
        </p>
    </p>
    <p class="モバイルエフェクトに Picke を実装する方法-center-highlight" style="height:36px;margin-top:-18px;"></p></p>

1.2 初始化DOM

由于饿了么源码中的モバイルエフェクトに Picke を実装する方法是采用v-for指令生成的DOM,因此我这里只是简单的用javascript来模拟一下DOM的生成。


var el = document.querySelector(&#39;#wrapper&#39;);
var animationFrameId = null;
var currentValue;
var itemHeight = 36;
var visibleItemCount = 3;
var valueIndex = 0;
var rotateEffect = true;
var datas = [&#39;1981&#39;, &#39;1982&#39;, &#39;1983&#39;, &#39;...&#39;, &#39;1999&#39;];// 如果支持3d视角,则给<p class="モバイルエフェクトに Picke を実装する方法"></p>加上类"モバイルエフェクトに Picke を実装する方法-3d"// <p class="モバイルエフェクトに Picke を実装する方法-slot" style="flex:1;">加上类"モバイルエフェクトに Picke を実装する方法-slot-absolute"if (rotateEffect) {
    var モバイルエフェクトに Picke を実装する方法 = document.querySelector(&#39;.モバイルエフェクトに Picke を実装する方法&#39;);
    var モバイルエフェクトに Picke を実装する方法Slot = document.querySelector(&#39;.モバイルエフェクトに Picke を実装する方法-slot&#39;);
    モバイルエフェクトに Picke を実装する方法.classList.add(&#39;モバイルエフェクトに Picke を実装する方法-3d&#39;);
    モバイルエフェクトに Picke を実装する方法Slot.classList.add(&#39;モバイルエフェクトに Picke を実装する方法-slot-absolute&#39;);}// 限定容器高度el.style.height = `${visibleItemCount * itemHeight}px`;// 生成DOMvar html = &#39;&#39;;datas.forEach(function(data, index) {
    html += `<p class="モバイルエフェクトに Picke を実装する方法-item" style="height:36px;line-height:36px;">${data}</p>`;});el.innerHTML = html;// 激活当前itemvar モバイルエフェクトに Picke を実装する方法Items = document.querySelectorAll(&#39;.モバイルエフェクトに Picke を実装する方法-item&#39;);モバイルエフェクトに Picke を実装する方法Items[valueIndex].classList.add(&#39;モバイルエフェクトに Picke を実装する方法-selected&#39;);

1.3 初始化事件

总体上来说,モバイルエフェクトに Picke を実装する方法的事件也包括滑动开始、滑动中、滑动结束。因为毕竟是移动端,滑动不可避免。这次,源码中的对滑动事件进行了封装,兼容了PC端以及排除了拖动和选择造成的影响,具体看一下分析。`


/**  * draggable.js  * 只是起到一定的兼容性 * 实质和直接调用 el.addEventListener(&#39;touchstart&#39;, startFn); 并没有多大差别 */// 滑动开始// touchstart 和 mousedown 可见对PC端的兼容// onselectstart/ondragstart 直接return 可见排除了拖动和选择element.addEventListener(supportTouch ? &#39;touchstart&#39; : &#39;mousedown&#39;, function(event) {
    if (isDragging) return;
    document.onselectstart = function() { return false; };
    document.ondragstart = function() { return false; };

    // ...});// 滑动结束var endFn = function(event) {
    // 注销事件
    if (!supportTouch) {
        document.removeEventListener(&#39;mousemove&#39;, moveFn);
        document.removeEventListener(&#39;mouseup&#39;, endFn);
    }
    document.onselectstart = null;
    document.ondragstart = null;

    isDragging = false;

    if (options.end) {
        options.end(supportTouch ? event.changedTouches[0] || event.touches[0] : event);
    }}

要是DOM跟随自己在手机屏幕上的滑动而滑动,方法大同小异,无非就是在开始滑动记录开始位置,滑动中实时计算位移,滑动结束之后将DOM滑动应该滑动的位置。这点可以参看前面一篇文章移动端效果之Swiper,这篇文章中有着相同的方法。这里重点讲一下其中的区别


// 滑动开始的执行事件方法start: function(event) {
    dragState = {
        range: getDragRange(),
        // ...
        startTranslateTop: translateUtil.getElementTranslate(el).top
    };}

这其中有两个方法,第一个getDragRange和第二个getElementTranslate(el).

  • 第一个函数的作用是获取モバイルエフェクトに Picke を実装する方法能够滑动的最小和最大的位移,这将会在滑动结束事件中用到。关于如何计算,这里简单提一下,向下滑动,最大不能超过最中间的item的最上方,这也就是为什么itemHeight * Math.floor(visibleItemCount / 2),而向上滑动,最大不能超过中间item的最下方,-itemHeight * (valuesLength - Math.ceil(visibleItemCount / 2)),细细想一下就好了。

  • 第二个函数的作用是获取当前モバイルエフェクトに Picke を実装する方法transform值,作为下一次滑动计算的依据。其实感觉这样挺费事,因为在touchend中最后肯定会计算translate值,我们只需要每次保存最后滑动的移动值就好了,而不要每次都要在DOM中取。


/** * translateUtil * 对浏览器对前缀支持的一些判断 * 检测浏览器对3d属性的支持情况 * 获取当前的translate值/清空モバイルエフェクトに Picke を実装する方法的translate值/移动モバイルエフェクトに Picke を実装する方法 * 对于浏览器的检测方面,这也算是一个比较好的工具类 */var docStyle = document.documentElement.style;var engine;var translate3d = false;// 浏览器判断if (window.opera && Object.prototype.toString.call(opera) === &#39;[object Opera]&#39;) {
    engine = &#39;presto&#39;;} else if (&#39;MozAppearance&#39; in docStyle) {
    engine = &#39;gecko&#39;;} else if (&#39;WebkitAppearance&#39; in docStyle) {
    engine = &#39;webkit&#39;;} else if (typeof navigator.cpuClass === &#39;string&#39;) {
    engine = &#39;trident&#39;;}// css前缀var cssPrefix = {
    trident: &#39;-ms-&#39;,        // IE
    gecko: &#39;-moz-&#39;,         // FireFox
    webkit: &#39;-webkit-&#39;,     // Chrome/Safari/etc...
    presto: &#39;-o-&#39;           // Opera}[engine];// style前缀var vendorPrefix = {
    trident: &#39;ms&#39;,
    gecko: &#39;Moz&#39;,
    webkit: &#39;Webkit&#39;,
    presto: &#39;O&#39;}[engine];var helpElem = document.createElement(&#39;p&#39;);var perspectiveProperty = vendorPrefix + &#39;Perspective&#39;;var transformProperty = vendorPrefix + &#39;Transform&#39;;var transformStyleName = cssPrefix + &#39;transform&#39;;var transitionProperty = vendorPrefix + &#39;Transition&#39;;var transitionStyleName = cssPrefix + &#39;transition&#39;;var transitionEndProperty = vendorPrefix.toLowerCase() + &#39;TransitionEnd&#39;;if (helpElem.style[perspectiveProperty] !== undefined) {
    translate3d = true;}// 讲一下这个正则// \s*(-?\d+(\.\d+?)?)px 这是一个单元,匹配这样的 -23.15px, 剩下的应该就好理解了var regexp = /translate\(\s*(-?\d+(\.\d+?)?)px,\s*(-?\d+(\.\d+?)?)px\)\s*translateZ\(0px\)/ig;

接下来看看滑动中


drag: function(event) {
    // 加上 dragging 类是为了清除过渡效果,在swiper中也有同样的应用
    el.classList.add(&#39;dragging&#39;);

    dragState.left = event.pageX;
    dragState.top = event.pageY;

    var deltaY = dragState.top - dragState.startTop;
  
    // 计算当前的滑动位移
    var translate = dragState.startTranslateTop + deltaY;

    // 滑动元素
    translateUtil.translateElement(el, null, translate);
    velocityTranslate = translate - prevTranslate || translate;

    prevTranslate = translate;

    if (rotateEffect) {
        updateRotate(prevTranslate, モバイルエフェクトに Picke を実装する方法Items);
    }}

看到以上的代码中有一个velocityTranslate,这个值有神马作用,最开始我也不清楚,后面发现在滑动结束之后用到了,才明白了它代表了一个速率的位移值。什么是速率?就好比你快速滑动的时候,总希望它能够惯性滑动一下,这个值乘以一个惯性值就可以得出一个惯性位移。看end中的代码。


end: function() {
    // 添加过渡
    el.classList.remove(&#39;dragging&#39;);
    // 惯性值
    var momentumRatio = 7;
    var currentTranslate = translateUtil.getElementTranslate(el).top;
    var duration = new Date() - dragState.start;

    var momentumTranslate;
    if (duration < 300) {
        momentumTranslate = currentTranslate + velocityTranslate * momentumRatio;
    }

    // 加上惯性速率之后的位移值
    console.log(&#39;momentumTranslate&#39;, momentumTranslate);

    dragRange = dragState.range;

    setTimeout(function() {
        var translate;
        if (momentumTranslate) {
            translate = Math.round(momentumTranslate / itemHeight) * itemHeight;
        } else {
            translate = Math.round(currentTranslate / itemHeight) * itemHeight;
        }

        // 取得最终的位移值,
        // 必须为itemHeight的倍数
        // 在范围的最大值和最小值中取
        translate = Math.max(Math.min(translate, dragRange[1]), dragRange[0]);
        translateUtil.translateElement(el, null, translate);

        // 计算得出当前位移下应该对应的实际值
        currentValue = translate2Value(translate);

        // 3d效果
        if (rotateEffect) {
            planUpdateRotate();
        }
    }, 10);

    dragState = {};}

这就是整个モバイルエフェクトに Picke を実装する方法的实现流程,撇开3d效果就可以使用了。下面看一下如何实现的3D效果。在doOnValuesChange中有一个最开始的初始化。


[].forEach.call(items, function(item, index) {
    translateUtil.translateElement(item, null, itemHeight * index);});

给每一个item设置了根据索引来的位移值,此时的每一个item的定位都必须是absolute的,这样位移下来才是紧挨着的,不然可能中间都会有一个itemHeight的空格。

3D效果中最关键的一点就是如何进行翻转角度的计算。在源码中定义了一个常量对象:


var VISIBEL_ITEMS_ANGLE_MAP = {
    3: -45,
    5: -20,
    7: -15};

可以看到,当只有3个可见元素的时候,高亮部分相对于X轴平行,而上一个item就必须绕X轴顺时针旋转45度,反之下一个itemX轴逆时针旋转45度。另外在其中有一段代码特别绕,根据我的理解是这样的:


// 当前item相对于顶部原本应该有的位移值var itemOffsetTop = index * itemHeight; // 滑动过程中,相对于最开始的位置滑动的位移值var translateOffset = dragRange[1] - currentTranslate;// 当应该有的位移值和滑动的位移值相等的时候,也就说明了当前的`item`被选中// 也就是说此时当前的角度为0var itemOffset = itemOffsetTop - translateOffset;var percentage = itemOffset / itemHeight;var angle = angleUnit * percentage;if (angle > 180) angle = 180;if (angle < -180) angle = -180;rotateElement(item, angle);

如果觉得太绕,其实也没有必要按照他的这种做法来,我们只要想办法确定每一个item相对于当前选中的item是处于上一个还是下一个,就可以根据此来计算角度。

2. 总结

关于饿了么中的モバイルエフェクトに Picke を実装する方法组件就看了这么多,整体来说跟swiper

モバイルエフェクト用のスワイパー🎜🎜コードはここにあります: github🎜 🎜🎜🎜1. コア分析🎜

1.1基本的な HTML 構造


🎜rrreee

1.2 DOM の初期化

🎜Ele.me ソース コードの モバイルエフェクトに Picke を実装する方法 では、 v-for 命令は DOM を生成するため、ここでは単純に javascript を使用して DOM の生成をシミュレートします。 🎜


🎜rrreee

1.3 初期化イベント

🎜一般的に、モバイルエフェクトに Picke を実装する方法 のイベントには、スライディング スタート、スライディング、スライディング エンドも含まれます。 。所詮モバイル端末なので滑りは避けられません。今回は、スライド イベントがソース コードにカプセル化されており、PC と互換性があり、ドラッグや選択の影響が排除されています。分析を詳しく見てみましょう。 `🎜


🎜rrreee🎜 携帯電話の画面上でのスライドに続いて DOM がスライドする場合も、方法は同様で、開始位置を記録するだけです。スライド開始時、スライド リアルタイムに変位を計算し、スライド終了後、DOM をスライドすべき位置までスライドさせます。この点については、以前の記事「モバイルエフェクト用のスワイパー」を参照してください。この記事も同様の方法です。ここでは相違点に焦点を当てます🎜


🎜rrreee🎜最初の getDragRange と 2 番目の getElementTranslate( el) の 2 つのメソッドがあります。 >.🎜

  • 🎜 最初の関数の機能は、モバイルエフェクトに Picke を実装する方法 がスライドできる最小および最大の変位を取得することです。これが使用されます。スライディング終了イベント。計算方法については、下にスライドすると、最大値が中央の item の上部を超えることができないため、itemHeight * Math.floor(visibleItemCount / 2) となります。 code>、上にスライドする間、最大値は中央の item, -itemHeight * (valuesLength - Math.ceil(visibleItemCount / 2))の下端を超えることはできません。 >、よく考えてからで十分です。 🎜
  • 🎜 2 番目の関数は、次のスライディング計算の基礎として現在の モバイルエフェクトに Picke を実装する方法transform 値を取得することです。 translate の値は必ず touchend で計算されるため、実際には、毎回最後のスライド移動の値を保存するだけで済むため、これは非常に面倒だと感じます。毎回すべて DOM から取得する必要があります。 🎜


🎜rrreee🎜 次に、スライドを見てみましょう 🎜


🎜rrreee🎜上記のコードには velocityTranslate という値があり、最初は知りませんでしたが、後でスライドが完了した後に使用されていることがわかりました。速度の変位値を表すことに気づきました。速度とは何ですか?素早くスライドするときと同じように、慣性でスライドできることを常に望みます。この値に慣性値を乗算すると、慣性変位が得られます。 end のコードを見てください。 🎜


🎜rrreee🎜これは モバイルエフェクトに Picke を実装する方法 全体の実装プロセスです。3d 効果なしでも使用できます。 3D 効果を実現する方法を見てみましょう。 doOnValuesChange には初期化があります。 🎜


🎜rrreee🎜は、各 item のインデックスに基づいてディスプレイスメント値を設定します。このとき、各 item の位置が決まります。ディスプレイスメントが互いに近くなるように、absolute である必要があります。それ以外の場合、中央に itemHeight のスペースが存在する可能性があります。 🎜🎜 3D エフェクトで最も重要なポイントは、フリップ角度を計算する方法です。定数オブジェクトはソース コードで定義されています: 🎜


🎜rrreee🎜 表示要素が 3 つだけの場合、強調表示された部分は X を基準にしていることがわかります。 code >軸は平行で、前の <code>itemX 軸を中心に時計回りに 45 度回転する必要がありますが、次の item は回転する必要がありますX 軸を中心に時計回りに /code>軸は反時計回りに 45 度回転します。さらに、私の理解によれば、特に複雑なコードのセクションがあります。 🎜


🎜rrreee🎜 複雑すぎると思われる場合は、次のようなものがあります。実際には、各 item が現在選択されている item に対して前または次の位置にあるかどうかを判断する方法があれば、彼のアプローチに従う必要はありません。これをもとに角度を計算します。 🎜🎜2. 概要🎜🎜 Ele.me の モバイルエフェクトに Picke を実装する方法 コンポーネントについては、全体として、swiper のスライドと非常によく似ています。変位値に基づいて正しい位置にスライドさせるのは、変位値の最終計算にあります。実際、値の計算方法については、誰もが似たような実装になる可能性があり、ソースに従う必要はありません。これにより、コードを書きやすくなる可能性があります。これはほんの少しの個人的な理解ですが、私自身と皆さんに少しでも役立つことを願っています。 🎜

以上がモバイルエフェクトに Picke を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

不同的电脑系统在调整屏幕亮度的操作方法上会有些不同,最近就有使用win7系统的网友不知道win7怎么调整屏幕亮度,看久了电脑眼睛比较酸痛。下面小编就教下大家win7调整屏幕亮度的方法。具体的操作步骤如下:1、点击win7电脑左下角的“开始”,在弹出的开始菜单中选择“控制面板”打开。2、在打开的控制面板中找到“电源选项”打开。3、也可以用鼠标右键电脑右下角的电源图标,在弹出的菜单中,点击“调整屏幕亮度”,如下图所示。两种方法都可以用。4、在打开的电源选项窗口的最下面可以看到屏幕亮度调整的滚动条,直

win10监控摄像头打开照片的方法win10监控摄像头打开照片的方法Jul 10, 2023 pm 09:41 PM

如果我们手头没有手机,只有电脑,但我们必须拍照,我们可以使用电脑内置的监控摄像头拍照,那么如何打开win10监控摄像头,事实上,我们只需要下载一个相机应用程序。打开win10监控摄像头的具体方法。win10监控摄像头打开照片的方法:1.首先,盘快捷键Win+i打开设置。2.打开后,进入个人隐私设置。3.然后在相机手机权限下打开访问限制。4.打开后,您只需打开相机应用软件。(如果没有,可以去微软店下载一个)5.打开后,如果计算机内置监控摄像头或组装了外部监控摄像头,则可以拍照。(因为人们没有安装摄

基于Java的机器视觉实践和方法介绍基于Java的机器视觉实践和方法介绍Jun 18, 2023 am 11:21 AM

随着科技的不断发展,机器视觉技术在各个领域得到了广泛应用,如工业自动化、医疗诊断、安防监控等。Java作为一种流行的编程语言,其在机器视觉领域也有着重要的应用。本文将介绍基于Java的机器视觉实践和相关方法。一、Java在机器视觉中的应用Java作为一种跨平台的编程语言,具有跨操作系统、易于维护、高度可扩展等优点,对于机器视觉的应用具有一定的优越性。Java

win7怎么调屏幕亮度的两种简单方法win7怎么调屏幕亮度的两种简单方法Jul 08, 2023 pm 06:33 PM

目前有很多屏幕亮度调整软件,我们可以通过使用软件进行快速调整或者通过显示器上自带的亮度功能进行调整。以下是详细的Win7屏幕亮度调整方式,您可以通过教程中的方法进行快速调整即可。Win7系统电脑怎么调节屏幕亮度教程:1、依次点击“计算机—右键—控制面板”,如果没有也可以在搜索框中进行搜索。2、点击控制面板下的“硬件和声音”,或者点击“外观和个性化”都可以。3、点击“NVIDIA控制面板”,有些显卡可能是AMD或者Intel的,请根据实际情况选择。4、调节图示中亮度滑块即可。5、还有一种方法,就是

PHP文件下载方法及常见问题解答PHP文件下载方法及常见问题解答Jun 09, 2023 pm 12:37 PM

PHP是一个广泛使用的服务器端编程语言,它的许多功能和特性可以将其用于各种任务,包括文件下载。在本文中,我们将了解如何使用PHP创建文件下载脚本,并解决文件下载过程中可能出现的常见问题。一、文件下载方法要在PHP中下载文件,我们需要创建一个PHP脚本。让我们看一下如何实现这一点。创建下载文件的链接通过HTML或PHP在页面上创建一个链接,让用户能够下载文件。

Vue 中的 createApp 方法是什么?Vue 中的 createApp 方法是什么?Jun 11, 2023 am 11:25 AM

随着前端开发的快速发展,越来越多的框架被用来构建复杂的Web应用程序。Vue.js是流行的前端框架之一,它提供了许多功能和工具来简化开发人员构建高质量的Web应用程序。createApp()方法是Vue.js中的一个核心方法之一,它提供了一种简单的方式来创建Vue实例和应用程序。本文将深入探讨Vue中createApp方法的作用,其如何使用以及使用时需要了解

Go 语言中的方法是怎样定义和使用的?Go 语言中的方法是怎样定义和使用的?Jun 10, 2023 am 08:16 AM

Go语言是近年来备受青睐的编程语言,因其简洁、高效、并发等特点而备受开发者喜爱。其中,方法(Method)也是Go语言中非常重要的概念。接下来,本文就将详细介绍Go语言中方法的定义和使用。一、方法的定义Go语言中的方法是带有接收器(Receiver)的函数,它是一个与某个类型绑定的函数。接收器可以是值类型或者指针类型。用于接收者的参数可以在方法名

使用PHP数组实现数据缓存和存储的方法和技巧使用PHP数组实现数据缓存和存储的方法和技巧Jul 16, 2023 pm 02:33 PM

使用PHP数组实现数据缓存和存储的方法和技巧随着互联网的发展和数据量的急剧增长,数据缓存和存储成为了我们在开发过程中必须要考虑的问题之一。PHP作为一门广泛应用的编程语言,也提供了丰富的方法和技巧来实现数据缓存和存储。其中,使用PHP数组进行数据缓存和存储是一种简单而高效的方法。一、数据缓存数据缓存的目的是为了减少对数据库或其他外部数据源的访问次数,从而提高

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター