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

animacje przejścia zdjęć

Object Storage Arubacloud
0 głosów
1,232 wizyt
pytanie zadane 21 marca 2018 w JavaScript 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 ScriptyChris Mędrzec (190,190 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 ScriptyChris Mędrzec (190,190 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 ScriptyChris Mędrzec (190,190 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 ScriptyChris Mędrzec (190,190 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 ScriptyChris Mędrzec (190,190 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ź 1,226 wizyt
pytanie zadane 17 sierpnia 2015 w JavaScript przez Eimens Maniak (69,240 p.)
+1 głos
1 odpowiedź 1,483 wizyt
pytanie zadane 4 sierpnia 2015 w HTML i CSS przez anka Nowicjusz (190 p.)
0 głosów
1 odpowiedź 366 wizyt
pytanie zadane 28 sierpnia 2018 w JavaScript przez vneb Początkujący (490 p.)

92,555 zapytań

141,402 odpowiedzi

319,540 komentarzy

61,938 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...