• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

animacje przejścia zdjęć

0 głosów
134 wizyt
pytanie zadane 21 marca 2018 w JavaScript, jQuery, AJAX przez pawel1115 Nowicjusz (140 p.)
edycja 21 marca 2018 przez pawel1115

Cześć,

jestem tu nowy, więc jeśli popełniłem jakie faux pas to przepraszam, jednak nigdzie nie mogłem odnaleźć odpowiedniej(działającej) porady. Napisałem slider i chciałbym dodać do zdjęć animacje przejścia(zarówno do automatu, jak również do "strzałek"), jednak przerosło to moje umiejętności. W związku z tym chciałbym prosić Was o pomoc, a oto mój kod:

HTML

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <main>
        <div id="slider">
            <div id="box">
                <img src="" name="img" class="img">
            </div>
            <div class="arrowPrev">
                <span></span>
            </div>
            <div class="arrowNext">
                <span></span>
            </div>
        </div>
    </main>
    <script src="slider.js"></script>
</body>

</html>

CSS

body {
  margin: 0;
  padding: 0;
}

#slider {
  position: relative;
  margin: 20px auto;
  width: 650px;
  height: 450px;
  border: 10px solid #fff;
  box-shadow: 0 0 5px 2px #ccc;
}

.img {
  position: absolute;
  width: 100%;
  height: 100%;
}

.arrowNext {
  right: 0;
}

.arrowPrev {
  left: 0;
}

.arrowNext,
.arrowPrev {
  position: absolute;
  top: 45%;
  list-style: none;
  width: 60px;
  height: 60px;
  background-color: #fff;
  border-radius: 50%;
  transition: 0.5s;
}

.arrowNext:hover,
.arrowPrev:hover {
  background-color: #0070ff;
}

.arrowNext span,
.arrowPrev span {
  position: absolute;
  width: 20px;
  height: 20px;
  border: 4px solid #0077ff;
  transition: 0.5s;
}

.arrowNext span:hover,
.arrowPrev span:hover {
  border-color: #fff;
}

.arrowNext span {
  top: 50%;
  right: 20%;
  transform: translateY(-50%) rotate(-45deg);
  border-left: none;
  border-top: none;
  transition: 0.5s;
}

.arrowNext:focus span {
  right: 25%;
  transition: 0.5s;
}

.arrowNext span::before {
  content: "";
  position: absolute;
  width: 38px;
  height: 5px;
  border-radius: 10%;
  background-color: #fff;
  transform-origin: right;
  transform: rotate(45deg) translate(2px, 25px) scale(0);
  transition: 0.5s;
}

.arrowNext:hover span::before {
  transform: rotate(45deg) translate(2px, 25px) scale(1);
  transition: 0.5s;
}

.arrowPrev span {
  top: 50%;
  left: 20%;
  transform: translateY(-50%) rotate(-45deg);
  border-right: none;
  border-bottom: none;
  transition: 0.5s;
}

.arrowPrev:focus span {
  left: 25%;
  transition: 0.5s;
}

.arrowPrev span::before {
  content: "";
  position: absolute;
  width: 38px;
  height: 5px;
  border-radius: 10%;
  background-color: #fff;
  transform-origin: left;
  transform: rotate(45deg) translate(-3px, -2px) scale(0);
  transition: 0.5s;
}

.arrowPrev:hover span::before {
  transform: rotate(45deg) translate(-3px, -2px) scale(1);
  transition: 0.5s;
}

JS

const imgs = ["img/1.jpg", "img/2.jpg", "img/3.jpg", "img/4.jpg"];

const next = document.querySelector(".arrowNext");
const prev = document.querySelector(".arrowPrev");
const time = 5000;
let i = 0;

next.addEventListener("click", function() {
  stop();

  if (i < imgs.length - 1) {
    i++;
  } else {
    i = 0;
  }
  document.img.src = imgs[i];
});

prev.addEventListener("click", function() {
  stop();

  if (i > 0) {
    i--;
  } else {
    i = imgs.length - 1;
  }
  document.img.src = imgs[i];
});

function stop() {
  window.clearTimeout("changeImage", time);
}

function changeImg() {
  if (i < imgs.length - 1) {
    i++;
  } else {
    i = 0;
  }
  document.img.src = imgs[i];
  setTimeout("changeImg()", time);
}

window.onload = changeImg;

Chodzi o przejście typu parallaxa pozioma. Coś takiego:https://www.youtube.com/watch?v=iXhS6KFPLY4 tylko w czystym JS. Z góry za pomoc dziękuję i pozdrawiam ;)

komentarz 14 kwietnia 2018 przez pawel1115 Nowicjusz (140 p.)

Czy ktoś jest w stanie mi pomóc?sad

komentarz 14 kwietnia 2018 przez JSHolic Szeryf (80,000 p.)
komentarz 16 kwietnia 2018 przez pawel1115 Nowicjusz (140 p.)
edycja 16 kwietnia 2018 przez pawel1115

dziękuje, za pomoc. Niestety @keyframes działa tylko w automacie i to wyłącznie przy pierwszym slidzie, a do tego nie działa to tak jak na filmiku, który dodałem. Kombinowałem coś z utworzeniem oddzielnej klasy z animacją i JS classList.toggle to też nie dało to pożądanego efektu. Może to ja coś źle zrobiłem?

.img {
  position: absolute;
  width: 100%;
  height: 100%;
  animation: move linear 5s;
  overflow-x: hidden;
}
@keyframes move
{
  0%{
    left: 1000px;
    display: none;
  }
  25%{
    left: 750px;
    display: none;
  }
  50%{
    left: 500px;
    display: none;
  }

  75%{
    left: 250px;
    display: none;
  }
  85%{
    left: 150px;
    display: block;
  }
  100%{
    left: 0;
    display: block;
  }
}

Mógłbyś mi doradzić coś jeszcze?

komentarz 16 kwietnia 2018 przez JSHolic Szeryf (80,000 p.)

Animację uruchamiaj dla osobnej klasy CSS. Klasę dodawaj przy kliku (lub dla automatycznego przewijania - w jakimś setTimeout), po czym usuwaj ją (np. po 1 sekundzie). Istotne, żeby po kliknięciu na kolejny obrazek, klasa z animacją była usunięta z poprzedniego obrazka i dodana na aktualny - czyli klasa z animacją była nadana dla jednego elementu w danym czasie.

komentarz 17 kwietnia 2018 przez pawel1115 Nowicjusz (140 p.)

Pewnie to już denerwujące, ale znowu mam problemwink. Napisałem coś takiego i nie za bardzo działają strzałki:

CSS:

@keyframes left {
  0% {
    transform: translateX(100%);
  }
  25% {
    transform: translateX(85%);

  }
  50% {
    transform: translateX(75%);
  }
  
  75% {
    transform: translateX(50%);
  }
  85% {
    transform: translateX(25%);
  }
  100% {
    transform: translateX(0);
  }
}
.animL { 
  animation: left linear 2s;
}

@keyframes right {
  0% {
    transform: translateX(-100%);
  }
  25% {
    transform: translateX(-85%);

  }
  50% {
    transform: translateX(-75%);
  }
  
  75% {
    transform: translateX(-50%);

  }
  85% {
    transform: translateX(-25%);
  }
  100% {
    transform: translateX(0);
  }
}
.animR {
  animation: right linear 2s;
}

JS:

const imgs = ["img/1.jpg", "img/2.jpg", "img/3.jpg", "img/4.jpg"];
const next = document.querySelector(".arrowNext");
const prev = document.querySelector(".arrowPrev");
const time = 5000;
let i = 0;

function animationL(e){
  document.img.classList.add('animL');
}

function animationR(e){
  document.img.classList.add('animR');
}

function removeL(){
  document.img.classList.remove('animL');
}
function removeR(){
  document.img.classList.remove('animR');
}

next.addEventListener("click", function() {
  clearTimeout("changeImg()", time);
  if (i < imgs.length - 1) {
    i++;
  } else {
    i = 0;
  }
  animationL(e);
  document.img.src = imgs[i];
  setTimeout("removeL()", 2500);
});

prev.addEventListener("click", function() {
  clearTimeout("changeImg()", time);
  if (i > 0) {
    i--;
  } else {
    i = imgs.length - 1;
  }
  document.img.src = imgs[i];
  animationR(e);
  e.preventDefault();
  setTimeout("removeL()", 2500);
});


function changeImg() {
  if (i < imgs.length - 1) {
    i++;
  } else {
    i = 0;
  }
  animationL(e);
  e.preventDefault();
  setTimeout("removeL()", 2500);
  document.img.src = imgs[i];
}

setTimeout("changeImg()", time);

Tak jakby automat się nie zatrzymywał. Jak widać coś chciałem z tym zrobić, ale nie wyszło. Przepraszam za uciążliwośćsmiley

komentarz 17 kwietnia 2018 przez JSHolic Szeryf (80,000 p.)

Nie uruchamiałem Twojego kodu, ale widzę w nim błędy:

  • function animationL(e){
      document.img.classList.add('animL');
    }

    Funkcja przyjmuje argument e, z którym nic nie robisz. Jeśli ma to być element na którym zapewne chcesz podmienić klasę, to po co korzystasz z document.img? Swoją drogą jeśli nie utworzyłeś gdzieś globalnej zmiennej img, to nie ma czegoś takiego. Zapewne chciałeś otrzymać kolekcję obrazków na stronie, a do tego służy document.images. Jeśli tą drogą chcesz iść (trochę bez sensu, bo powinieneś podmienić klasę na jednym obrazku), to powinieneś zrobić pętlę, ponieważ property classList przynależy do elementu a nie listy elementów. To samo dotyczy funkcji animationR, removeL i removeR

  • w linii 29 przekazujesz do funkcji parametr e - skąd go wziąłeś? Nie widzę deklaracji takiej zmiennej w podanym kodzie

  • setTimeout("removeL()", 2500);

    Nie jest to błędem, lecz przekazywanie stringa do setTimeout jest złą praktyką, ponieważ będzie użyta wtedy funkcja eval. Przekazuj albo anonimową funkcję, albo referencję do funkcji utworzonej gdzieś indziej

  • clearTimeout("changeImg()", time);

    Metoda clearTimeout przyjmuje tylko identyfikator timera, po którym rozpoznaje który z nich wyłączyć. Identyfikator zwracany jest właśnie przez setTimeout

  • e.preventDefault();

    Ponawiam pytanie - skąd bierzesz zmienną e? Nie przekazujesz jej ani nie deklarujesz w podanym kawałku kodu.

komentarz 18 kwietnia 2018 przez pawel1115 Nowicjusz (140 p.)

Poprawiłem zgodnie z Twoimi sugestiami(chyba) ten kod i wygląda to tak:

const imgs = ["img/1.jpg", "img/2.jpg", "img/3.jpg", "img/4.jpg"];
const next = document.querySelector(".arrowNext");
const prev = document.querySelector(".arrowPrev");
const time = 7000;
let i = 0;

function animationL(){
  document.img.classList.add('animL');
}

function animationR(){
  document.img.classList.add('animR');
}

function removeL(){
  document.img.classList.remove('animL');
}
function removeR(){
  document.img.classList.remove('animR');
}

next.addEventListener("click", function() {
  if (i < imgs.length - 1) {
    i++;
  } else {
    i = 0;
  }
  document.img.src = imgs[i];
  animationL();
  setTimeout(removeL, 1500);
  clearTimeout(timer);
});

prev.addEventListener("click", function() {
  if (i > 0) {
    i--;
  } else {
    i = imgs.length - 1;
  }
  document.img.src = imgs[i];
  animationR();
  setTimeout(removeR, 1500);
  removeL();
  clearTimeout(timer);
});


function changeImg() {
  if (i < imgs.length - 1) {
    i++;
  } else {
    i = 0;
  }
  animationL();
  setTimeout(removeL, 1500);
  document.img.src = imgs[i];
  const timer = setTimeout(changeImg, time);
}
window.onload = changeImg;

Po dopasowaniu czasów w JS i CSS działa to mniej więcej tak jak sobie wymyśliłem. dziękuję za poświęcony czas i pomoc :). Są jakieś forumowe sposoby odwdzięczania się za pomoc? Nie wiem jakieś przyznawanie punktów czy coś.

P.S.: Jak zapewne widzisz dopiero "oswajam się" z JS i zasugerowałem się tym: https://www.w3schools.com/jsref/event_preventdefault.asp , Chciałem po kliknięciu w strzałkę przerwać działanie funkcji "changeImg". To "e" to miał być skrót od "event", ale to chyba tak nie działa smiley.

komentarz 18 kwietnia 2018 przez JSHolic Szeryf (80,000 p.)

Ten kod nie będzie działać prawidłowo. Nadal zamiast document.images używasz document.img. Wypisz to w konsoli, a powinieneś zobaczyć wartość undefined, a więc property classList nie jest dostępne i metody add/remove również.

Czyszczenie licznika też nie będzie działać:

clearTimeout(timer);

, ponieważ zmienną timer tworzysz lokalnie w funkcji changeImg i tylko tam jest ona widoczna. Do clearTimeout powinieneś przesłać identyfikator (typu liczbowego) timera, a zamiast tego ślesz tam undefined (przez użycie niezadeklarowanej zmiennej bądź bez przypisanej wartości) - nie będzie to działać. Nawet jeśli clearTimeout "pod spodem" parsuje sobie przesłany parametr do liczby, to wartość undefined po parsowaniu staje się wartością NaN, a nie liczbą.

Sprawdź proszę konsolę. Obstawiam, że są tam błędy.

komentarz 21 kwietnia 2018 przez pawel1115 Nowicjusz (140 p.)
edycja 21 kwietnia 2018 przez pawel1115

poprawiłem kod i teraz wygląda on tak:

const imgs = ["img/1.jpg", "img/2.jpg", "img/3.jpg", "img/4.jpg"];
let img = document.querySelector('.img');
const next = document.querySelector(".arrowNext");
const prev = document.querySelector(".arrowPrev");
const time = 5000;
let i = 0;

function animationL(){
img.classList.add('animL');
}

function animationR(){
  img.classList.add('animR');
}

function removeL(){
  img.classList.remove('animL');
}
function removeR(){
  img.classList.remove('animR');
}

next.addEventListener("click", function() {
  if (i < imgs.length - 1) {
    i++;
  } else {
    i = 0;
  }
  img.src = imgs[i];
  animationL();
  setTimeout(removeL, 1500);
  clearTimeout(5000);
});

prev.addEventListener("click", function() {
  if (i > 0) {
    i--;
  } else {
    i = imgs.length - 1;
  }
  img.src = imgs[i];
  animationR();
  setTimeout(removeR, 1500);
  removeL();
  clearTimeout(5000);
});


function changeImg() {
  if (i < imgs.length - 1) {
    i++;
  } else {
    i = 0;
  }
  animationL();
  setTimeout(removeL, 1500);
  img.src = imgs[i];
  setTimeout(changeImg, time);
}
window.onload = changeImg;

Musisz mi wierzyć na słowo bo nie zrobiłem screenów, ale ani przed poprawką ani po w konsoli Firefox'a błędów nie było. Nie wiem tylko co będzie lepsze const czy let dla zmiennej img? Atrybut src tagu img zmienia się automatycznie więc chyba let czy coś źle rozumiem z właściwości tych zmiennych?

komentarz 21 kwietnia 2018 przez JSHolic Szeryf (80,000 p.)

co będzie lepsze const czy let 

Jeśli do zmiennej będziesz przypisywać coś więcej niż raz, to let, jeśli przypisanie jest jednokrotne, to const.

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
1 odpowiedź 723 wizyt
pytanie zadane 17 sierpnia 2015 w JavaScript, jQuery, AJAX przez Eimens Maniak (69,140 p.)
0 głosów
1 odpowiedź 133 wizyt
pytanie zadane 28 sierpnia 2018 w JavaScript, jQuery, AJAX przez vneb Początkujący (490 p.)
+1 głos
1 odpowiedź 791 wizyt
pytanie zadane 4 sierpnia 2015 w HTML i CSS przez anka Nowicjusz (190 p.)
Porady nie od parady
Wynikowy wygląd pytania, odpowiedzi czy komentarza, różni się od tego zaprezentowanego w edytorze postów. Stosuj więc funkcję Podgląd posta znajdującą się pod edytorem, aby upewnić się, czy na pewno ostateczny rezultat ci odpowiada.Podgląd posta

66,324 zapytań

113,061 odpowiedzi

239,218 komentarzy

46,589 pasjonatów

Przeglądających: 253
Pasjonatów: 7 Gości: 246

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...