2016-07-13 5 views
2

要素のスワイプ時に不透明度を変更したいと思います。CSS/JS:スワイプで不透明度を変更する

スニペットに似たアニメーションを達成したいと思います。スワイプ中に指やカーソルがどれだけドラッグしたかによって徐々に適用されます。

EDIT:アニメーションは、Androidで通知をクリアすると同じです

  • 私の最初のアイデアドラッグイベントを処理し、要素の位置との幅に応じて、不透明度を変更することでしたスクリーン。これは良い解決策ですか?より優れたものがありますか?おそらくCSSのみですか?

私は(私の要素をイオンアイテムである)イオン使用していますので、イオン/ angular1に関連したものはあまりにも良いかもしれません。 Googleのクロームの開発者で

div.animated { 
 
    width: 100px; 
 
    height: 100px; 
 
    background: red; 
 
    position: absolute; 
 
    top: 31px; 
 
    animation: right 2s; 
 
    animation-iteration-count: infinite; 
 
    animation-direction: alternate; 
 
    animation-timing-function: linear; 
 
} 
 

 
.back { 
 
    width: 100px; 
 
    height: 100px; 
 
    border: 1px solid blue; 
 
    position: fixed; 
 
    top: 30px; 
 
    left: 50px; 
 
} 
 

 
@keyframes right { 
 
    0% { 
 
     left: 0px; 
 
     opacity: 0.1; 
 
    } 
 
    50% { opacity: 1;} 
 
    100% {left: 100px;opacity:0.1} 
 
}
The blue frame is the screen and the red square is the dragged element 
 
<div class="animated"></div> 
 
<div class="back"></div>

+1

ここでは、Googleのエンジニアhttps://www.youtube.com/watch?v=F3A6Skckh9c –

+0

テイクで素敵なビデオです[hammer.js](http://hammerjs.github.io/)の検索 – AleshaOleg

答えて

0

Ansrewのは非常に便利です。 Ionicでは、onDragonReleaseの指示文を使用する方が簡単です。

<ion-item on-drag="onDrag($event)" on-release="onRelease($event)" /> 

とイオンアイテムのスタイルをこれらのメソッドを使用します。

function onDrag (e) { 
    var element = e.currentTarget.childNodes[0]; 
    var screenW = element.offsetWidth; 
    var threshold = screenW * 0.16; 

    var delta = Math.abs(e.gesture.deltaX); 

    if(delta >= threshold) { 
     var normalizedDragDistance = (Math.abs(delta)/screenW); 
     var opacity = 1 - Math.pow(normalizedDragDistance, 0.7); 

     element.style.opacity = opacity; 
    } else { 
     e.currentTarget.childNodes[0].style.opacity = 1; 
    } 
} 

function onRelease (e) { 
    e.currentTarget.childNodes[0].style.opacity = 1; 
} 
2

非常に素晴らしい人以上がショーの背後にある考え方は、あなたのWebアプリケーションへの影響を作るために迅速かつ簡単な方法を示すことですショーコールSuperChargedを実行します。

スワイプブルカードについてはepisode(約1時間)です。彼らは基本的な考え方を与えるためにちょうど10分のepisodeでした。

あなたの質問に答えるには、javascriptが応答する唯一の方法です。CSSはユーザーの入力や操作に応答しません。

また、スクリーンを横切って物を動かすときは、左とは逆のトランスフォームを使用することをお勧めします。彼らはなぜショーの間に非常に詳細に理由を説明しますが、迅速な理由は、変換はGPUを使用することができます。とにかくここ

はそれを一目を与えると、それはあなたが探しているものだかどうかを確認し、彼らはエピソードで行われたコードのライブデモです。私はあなたが(私は確かにやった)多くのことを学ぶことができ、とにかく自分のビデオを見て推薦するのです。

/** 
 
Copyright 2016 Google Inc. All rights reserved. 
 
Licensed under the Apache License, Version 2.0 (the "License"); 
 
*/ 
 

 
'use strict'; 
 

 
class Cards { 
 
    constructor() { 
 
    this.cards = Array.from(document.querySelectorAll('.card')); 
 

 
    this.onStart = this.onStart.bind(this); 
 
    this.onMove = this.onMove.bind(this); 
 
    this.onEnd = this.onEnd.bind(this); 
 
    this.update = this.update.bind(this); 
 
    this.targetBCR = null; 
 
    this.target = null; 
 
    this.startX = 0; 
 
    this.currentX = 0; 
 
    this.screenX = 0; 
 
    this.targetX = 0; 
 
    this.draggingCard = false; 
 

 
    this.addEventListeners(); 
 

 
    requestAnimationFrame(this.update); 
 
    } 
 

 
    addEventListeners() { 
 
    document.addEventListener('touchstart', this.onStart); 
 
    document.addEventListener('touchmove', this.onMove); 
 
    document.addEventListener('touchend', this.onEnd); 
 

 
    document.addEventListener('mousedown', this.onStart); 
 
    document.addEventListener('mousemove', this.onMove); 
 
    document.addEventListener('mouseup', this.onEnd); 
 
    } 
 

 
    onStart(evt) { 
 
    if (this.target) 
 
     return; 
 

 
    if (!evt.target.classList.contains('card')) 
 
     return; 
 

 
    this.target = evt.target; 
 
    this.targetBCR = this.target.getBoundingClientRect(); 
 

 
    this.startX = evt.pageX || evt.touches[0].pageX; 
 
    this.currentX = this.startX; 
 

 
    this.draggingCard = true; 
 
    this.target.style.willChange = 'transform'; 
 

 
    evt.preventDefault(); 
 
    } 
 

 
    onMove(evt) { 
 
    if (!this.target) 
 
     return; 
 

 
    this.currentX = evt.pageX || evt.touches[0].pageX; 
 
    } 
 

 
    onEnd(evt) { 
 
    if (!this.target) 
 
     return; 
 

 
    this.targetX = 0; 
 
    let screenX = this.currentX - this.startX; 
 
    if (Math.abs(screenX) > this.targetBCR.width * 0.35) { 
 
     this.targetX = (screenX > 0) ? this.targetBCR.width : -this.targetBCR.width; 
 
    } 
 

 
    this.draggingCard = false; 
 
    } 
 

 
    update() { 
 

 
    requestAnimationFrame(this.update); 
 

 
    if (!this.target) 
 
     return; 
 

 
    if (this.draggingCard) { 
 
     this.screenX = this.currentX - this.startX; 
 
    } else { 
 
     this.screenX += (this.targetX - this.screenX)/4; 
 
    } 
 

 
    const normalizedDragDistance = 
 
     (Math.abs(this.screenX)/this.targetBCR.width); 
 
    const opacity = 1 - Math.pow(normalizedDragDistance, 3); 
 

 
    this.target.style.transform = `translateX(${this.screenX}px)`; 
 
    this.target.style.opacity = opacity; 
 

 
    // User has finished dragging. 
 
    if (this.draggingCard) 
 
     return; 
 

 
    const isNearlyAtStart = (Math.abs(this.screenX) < 0.1); 
 
    const isNearlyInvisible = (opacity < 0.01); 
 

 
    // If the card is nearly gone. 
 
    if (isNearlyInvisible) { 
 

 
     // Bail if there's no target or it's not attached to a parent anymore. 
 
     if (!this.target || !this.target.parentNode) 
 
     return; 
 

 
     this.target.parentNode.removeChild(this.target); 
 

 
     const targetIndex = this.cards.indexOf(this.target); 
 
     this.cards.splice(targetIndex, 1); 
 

 
     // Slide all the other cards. 
 
     this.animateOtherCardsIntoPosition(targetIndex); 
 

 
    } else if (isNearlyAtStart) { 
 
     this.resetTarget(); 
 
    } 
 
    } 
 

 
    animateOtherCardsIntoPosition(startIndex) { 
 
    // If removed card was the last one, there is nothing to animate. Remove target. 
 
    if (startIndex === this.cards.length) { 
 
     this.resetTarget(); 
 
     return; 
 
    } 
 

 
    const frames = [{ 
 
     transform: `translateY(${this.targetBCR.height + 20}px)` 
 
    }, { 
 
     transform: 'none' 
 
    }]; 
 
    const options = { 
 
     easing: 'cubic-bezier(0,0,0.31,1)', 
 
     duration: 150 
 
    }; 
 
    const onAnimationComplete =() => this.resetTarget(); 
 

 
    for (let i = startIndex; i < this.cards.length; i++) { 
 
     const card = this.cards[i]; 
 

 
     // Move the card down then slide it up. 
 
     card 
 
     .animate(frames, options) 
 
     .addEventListener('finish', onAnimationComplete); 
 
    } 
 
    } 
 

 
    resetTarget() { 
 
    if (!this.target) 
 
     return; 
 

 
    this.target.style.willChange = 'initial'; 
 
    this.target.style.transform = 'none'; 
 
    this.target = null; 
 
    } 
 
} 
 

 
window.addEventListener('load',() => new Cards());
/** 
 
Copyright 2016 Google Inc. All rights reserved. 
 
Licensed under the Apache License, Version 2.0 (the "License"); 
 
*/ 
 

 
html, 
 
body { 
 
    margin: 0; 
 
    padding: 0; 
 
    background: #FAFAFA; 
 
    font-family: Arial; 
 
    font-size: 30px; 
 
    color: #333; 
 
} 
 
* { 
 
    box-sizing: border-box; 
 
} 
 
.card-container { 
 
    width: 100%; 
 
    max-width: 450px; 
 
    padding: 16px; 
 
    margin: 0 auto; 
 
} 
 
.card { 
 
    background: #FFF; 
 
    border-radius: 3px; 
 
    box-shadow: 0 3px 4px rgba(0, 0, 0, 0.3); 
 
    margin: 20px 0; 
 
    height: 120px; 
 
    display: flex; 
 
    align-items: center; 
 
    justify-content: space-around; 
 
    cursor: pointer; 
 
}
<!-- 
 
https://github.com/GoogleChrome/ui-element-samples/tree/master/swipeable-cards 
 

 
https://www.youtube.com/watch?v=rBSY7BOYRo4 
 

 
/** 
 
* 
 
* Copyright 2016 Google Inc. All rights reserved. 
 
* 
 
* Licensed under the Apache License, Version 2.0 (the "License"); 
 
* you may not use this file except in compliance with the License. 
 
* You may obtain a copy of the License at 
 
* 
 
*  http://www.apache.org/licenses/LICENSE-2.0 
 
* 
 
* Unless required by applicable law or agreed to in writing, software 
 
* distributed under the License is distributed on an "AS IS" BASIS, 
 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 
* See the License for the specific language governing permissions and 
 
* limitations under the License. 
 
*/ 
 
--> 
 

 
<div class="card-container"> 
 
    <div class="card">Das Surma</div> 
 
    <div class="card">Aerotwist</div> 
 
    <div class="card">Kinlanimus Maximus</div> 
 
    <div class="card">Addyoooooooooo</div> 
 
    <div class="card">Gaunty McGaunty Gaunt</div> 
 
    <div class="card">Jack Archibungle</div> 
 
    <div class="card">Sam "The Dutts" Dutton</div> 
 
</div>

+1

この返信をありがとう!ショーを知らなかった、それは本当に素晴らしいようです! これは興味深い解決策です。それはイオンの指示を 'on-drag'と' on-release'を使って書いてくれました。 –

関連する問題