2016-07-13 16 views
2

Ich möchte die Deckkraft eines Elements ändern, während Sie darauf wischen.CSS/JS: Ändern der Deckkraft beim Swipe

Ich möchte eine Animation ähnlich der im Snippet erreichen, die allmählich angewendet wird, je nachdem, wie viel mein Finger/Cursor das Element beim Streichen gezogen hat.

EDIT: Die Animation ist das gleiche wie eine Benachrichtigung in Android Clearing

  • Meine erste Idee war, die Drag-Ereignis zu behandeln und die Opazität auf der Position des Elements in Abhängigkeit ändern und die Breite der Bildschirm. Ist das eine gute Lösung? Gibt es einen besseren, vielleicht nur CSS?

ich ionischer bin mit (mein Element ist ein Ionen Artikel), so alles im Zusammenhang mit ionischen/angular1 zu gut sein könnte.

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

Hier ist ein schönes Video von einem Ingenieur google https://www.youtube.com/watch?v=F3A6Skckh9c –

+0

nehmen ein Blick für [hammer.js] (http://hammerjs.github.io/) – AleshaOleg

Antwort

0

Ansrew das ist sehr nützlich. In Ionic ist es einfacher, onDrag und onRelease Direktiven zu verwenden.

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

Und diese Methoden verwenden, um die Ionen Artikel stylen:

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

Die sehr nette Leute bei Google über Chrome Devs laufen eine Show Anruf SuperCharged die Idee hinter der Show Sie schnell und einfache Möglichkeiten, um zu zeigen, Web-Anwendungen Effekte zu machen.

Sie haben eine episode (die etwa eine Stunde lang ist) über swipeable Karten, sie haben eine schnelle 10-Minuten episode nur um Ihnen die Grundidee zu geben.

Um Ihre Frage zu beantworten, ist JavaScript die einzige Möglichkeit, um darauf zu reagieren, CSS reagiert nicht auf Benutzereingaben oder Aktionen.

Außerdem ist es am besten, transform, im Gegensatz zu links, beim Verschieben von Dingen über den Bildschirm zu verwenden. Sie erklären die Gründe, warum sehr detailliert während der Show, aber der schnelle Grund ist, dass transform die GPU verwenden kann.

Wie auch immer, hier ist eine Live-Demo des Codes, den sie in der Folge gemacht haben, gib einen Blick darauf und schau, ob es das ist, wonach du suchst. Ich würde dir empfehlen, ihre Videos trotzdem anzuschauen, du kannst sehr viel lernen (das habe ich sicherlich getan).

/** 
 
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

Vielen Dank für diese Antwort! Ich kannte die Show nicht, es scheint wirklich toll! Dies ist eine interessante Lösung, sie hat mir geholfen, meins zu schreiben, das die ionen-Direktiven 'on-drag' und' on-release' verwendet. –

Verwandte Themen