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

wypełnianie diva wycentrowanym obrazkiem

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
+2 głosów
857 wizyt
pytanie zadane 24 czerwca 2021 w JavaScript przez mikolaj.k Obywatel (1,430 p.)
edycja 24 czerwca 2021 przez mikolaj.k

Biblioteka Panzoom (https://timmywil.com/panzoom/demo/) umożliwia przesuwania i powiększanie obrazu w divie:
https://codepen.io/reti/pen/MWpMNYE
Wszystko działa prawidłowo.

Teraz chciałbym, aby te zdjęcia, po załadowaniu wypełniły swoje divy, ale tak żeby były wycentrowane wertykalnie i horyzontalnie, przy czym:
- jeżeli obraz ma orientację horyzontalną, to jego wysokość nie może być większa od diva
- jeżeli obraz ma orinetację wertykalną, to jego szerokość nie może być większa od diva.
Dokładnie tak jak tutaj: https://drive.google.com/file/d/1znFq-EJVE4Dv2j9sc3xZUZuMH0bhRsfz/view?usp=sharing

Jak to zrobić? Próbuję na różne sposoby i już skończyły mi się pomysły.

komentarz 25 czerwca 2021 przez ScriptyChris Mędrzec (190,190 p.)

Podpowiem, że można ustawić początkową skalę oraz pozycję na osi X i Y za pomocą propertisów w obiekcie konfiguracyjnym - nie trzeba ruszać ani HTML-a ani CSS-a.

Demo rozwiązania do dopracowania - trzeba lepiej wyliczyć pozycje na osiach X i Y, ale skalowanie zdaje się być ok: https://codepen.io/ScriptyChris/pen/oNZKxjj?editors=1010

komentarz 25 czerwca 2021 przez mikolaj.k Obywatel (1,430 p.)
Nie wiem jak to się stało, ale przeoczyłem ten komentarz :) Sorry, odpowiem niebawem!
komentarz 26 czerwca 2021 przez mikolaj.k Obywatel (1,430 p.)

@ScriptyChris,
 bardzo Ci dziękuję. Będę mógł do tego usiąść dopiero za kilka dni. Wstępnie tylko powiem, że problem zoomowania rozwiązałem w ten sposób: https://codepen.io/reti/pen/MWpMNYE Gdybym umiał dodać do tego centrowanie, to problem byłby całkowicie rozwiązany.

komentarz 28 czerwca 2021 przez mikolaj.k Obywatel (1,430 p.)

@ScriptyChris,


zoomowanie jest u Ciebie ok, ale powinno być odwrotnie. Moim celem było całkowite wypełnienie kwadratów. Jest tak: https://pasteboard.co/K8GfeHD.png (po ręcznym poprawieniu pozycji) a powinno być tak: https://drive.google.com/file/d/1znFq-EJVE4Dv2j9sc3xZUZuMH0bhRsfz/view

Jeżeli chodzi o wyliczenie pozycji na osiach X i Y, to nie mam pojęcia jak się do tego zabrać. Trudno mi się odnaleźć w tym kodzie, ale to jest kwestia mojego braku zaawansowania, np. nie rozumiem tego zapisu:

 const { startX, startY }

Co to znaczy?

4 odpowiedzi

+2 głosów
odpowiedź 29 czerwca 2021 przez mikolaj.k Obywatel (1,430 p.)

Chyba się udało: https://codepen.io/reti/pen/JjNjMVa

Wystarczył jednak CSS. Jutro jeszcze będę to dokładnie testował.

komentarz 29 czerwca 2021 przez VBService Ekspert (256,320 p.)

Dodałbym jeszcze parametr: np. minScale: 0.95

. . .

var panzoom1 = Panzoom(document.querySelector(".zoom-area1"), {
  maxScale: 6, minScale: 0.95
});

. . .

żeby zapobiec efektowi, możliwości zmniejszenia obrazka bardziej niż wielkość "kontenera".  wink

1
komentarz 1 lipca 2021 przez mikolaj.k Obywatel (1,430 p.)
Dzięki! :)
0 głosów
odpowiedź 24 czerwca 2021 przez niezalogowany

Nie wiem czy dobrze zrozumiałem ? frown

<div class="main-container">
  <div class="zoom-wrapper1">
    <div class="zoom-area1 parent">
      <img src="https://ironcodestudio.com/wp-content/uploads/2015/03/css-remove-horizontal-scrollbar.jpg" />
    </div>
  </div>

  <div class="zoom-wrapper2">
    <div class="zoom-area2 parent">
      <img src="https://image.freepik.com/free-photo/vertical-view-eiffel-tower-paris-france_1258-3169.jpg" />
    </div>
  </div>
</div>
.main-container {
  display: flex;
}
.zoom-wrapper1 {
  width: 300px;
  height: 300px;
  border: 5px solid #1C6EA4;
}

.zoom-wrapper2 {
  width: 300px;
  height: 300px;
  border: 5px solid #1C6EA4;
}

.parent {
  display: flex;
  align-items: center;
  justify-content: center;
}

img {
  width: 300px;
  height: 300px;
}
var panzoom1 = Panzoom(document.querySelector(".zoom-area1"), {
  maxScale: 6
});
document.querySelector(".zoom-wrapper1").addEventListener("wheel", panzoom1.zoomWithWheel);


var panzoom2 = Panzoom(document.querySelector(".zoom-area2"), {
  maxScale: 6
});
document.querySelector(".zoom-wrapper2").addEventListener("wheel", panzoom2.zoomWithWheel);

 

komentarz 24 czerwca 2021 przez mikolaj.k Obywatel (1,430 p.)
Sorry, przyjrzałem się temu 2 przykładowi z codepen i jest zły. Zmieniłem link. Dokładnie chodzi mi o coś takiego: https://drive.google.com/file/d/1znFq-EJVE4Dv2j9sc3xZUZuMH0bhRsfz/view?usp=sharing
komentarz 24 czerwca 2021 przez niezalogowany
<div class="main-container">
  <div class="zoom-wrapper1">
    <div class="zoom-area1 parent">
      <img src="https://ironcodestudio.com/wp-content/uploads/2015/03/css-remove-horizontal-scrollbar.jpg" class="img-one" />
    </div>
  </div>
 
  <div class="zoom-wrapper2">
    <div class="zoom-area2 parent">
      <img src="https://image.freepik.com/free-photo/vertical-view-eiffel-tower-paris-france_1258-3169.jpg" class="img-two"/>
    </div>
  </div>
</div>
.main-container {
  display: flex;
}
.zoom-wrapper1 {
  width: 300px;
  height: 300px;
  border: 5px solid #1C6EA4;
}
 
.zoom-wrapper2 {
  width: 300px;
  height: 300px;
  border: 5px solid #1C6EA4;
}
 
.parent {
  display: flex;
  align-items: center;
  justify-content: center;
}
 
img {
  width: 100%;
  height: 300px;
  object-fit:cover;
}
var panzoom1 = Panzoom(document.querySelector(".zoom-area1"), {
  maxScale: 6
});
document.querySelector(".zoom-wrapper1").addEventListener("wheel", panzoom1.zoomWithWheel);
 
 
var panzoom2 = Panzoom(document.querySelector(".zoom-area2"), {
  maxScale: 6
});
document.querySelector(".zoom-wrapper2").addEventListener("wheel", panzoom2.zoomWithWheel);

Teraz jak na moje oko jest dobrze cool

komentarz 24 czerwca 2021 przez mikolaj.k Obywatel (1,430 p.)
Zdjęcia wycentrowane są idealne, ale jest jeden problem: zostały obcięte :(
0 głosów
odpowiedź 24 czerwca 2021 przez VBService Ekspert (256,320 p.)
komentarz 24 czerwca 2021 przez mikolaj.k Obywatel (1,430 p.)
Dzięki, ale w kazdym z podanych przykładów zdjęcie nie wypełnia całkowicie diva tak jak tu: https://drive.google.com/file/d/1znFq-EJVE4Dv2j9sc3xZUZuMH0bhRsfz/view :(
0 głosów
odpowiedź 24 czerwca 2021 przez VBService Ekspert (256,320 p.)
edycja 25 czerwca 2021 przez VBService

Czy to może być coś takiego ... ?  smiley

<script src="https://timmywil.com/panzoom/demo/panzoom.js"></script>

<div class="main-container">
  <div class="zoom-wrapper">
    <div class="zoom-area">
      <img src="https://ironcodestudio.com/wp-content/uploads/2015/03/css-remove-horizontal-scrollbar.jpg" />
    </div>
  </div>

  <div class="zoom-wrapper">
    <div class="zoom-area">
      <img src="https://image.freepik.com/free-photo/vertical-view-eiffel-tower-paris-france_1258-3169.jpg" />
    </div>
  </div>
</div>
.main-container {
  display: flex;
}
.zoom-wrapper {
  position: relative;
  width: 300px;
  height: 300px;
  border: 5px solid #1C6EA4;
}
.zoom-area {
  position: absolute;
}
const zoom_wrappers = document.querySelectorAll('.zoom-wrapper');
const zoom_areas = document.querySelectorAll('.zoom-area');
 
zoom_areas.forEach((zoom_area, index) => {
  const pan_zoom = Panzoom(zoom_area, { maxScale: 6, startScale: 0.7 });
  zoom_wrappers[index].addEventListener('wheel', pan_zoom.zoomWithWheel);
   
  const w = (zoom_wrappers[index].offsetWidth - zoom_area.offsetWidth) / 2;
  const h = (zoom_wrappers[index].offsetHeight - zoom_area.offsetHeight) / 2;
   
  zoom_area.style.left = `${w}px`;
  zoom_area.style.top = `${h}px`;
});

 

komentarz 25 czerwca 2021 przez mikolaj.k Obywatel (1,430 p.)
Nistety nie :( U mnie wygląda to tak: https://drive.google.com/file/d/1cBae5MqHxdvW1UgBdJ-E0IVYZrmjXDxT/view?usp=sharing a powinny być całe kwadratowe divy zapełnione w ten sposób: https://drive.google.com/file/d/1znFq-EJVE4Dv2j9sc3xZUZuMH0bhRsfz/view
komentarz 25 czerwca 2021 przez VBService Ekspert (256,320 p.)
edycja 25 czerwca 2021 przez VBService

Ciekawe, bo u Mnie jest tak

komentarz 25 czerwca 2021 przez mikolaj.k Obywatel (1,430 p.)
edycja 25 czerwca 2021 przez mikolaj.k
OK, dzięki wielkie. U mnie na Firefox dzieje się tak: https://drive.google.com/file/d/1J4LDtqfwXHUFhn-BGKpSnB-9KY4-dIT9/view?usp=sharing

a na Chrome jest tak jak u Ciebie i to rozwiązanie jest całkiem spoko, tylko są dwa szczegóły:

1) wysokość zdjęcia o orientacji poziomej nie może wykraczać poza wysokość swojego diva, a szerokość zdjęcia o orientacji pionowej nie może wykraczać poza szerokość swojego diva (https://drive.google.com/file/d/1znFq-EJVE4Dv2j9sc3xZUZuMH0bhRsfz/view).

2) zdjęcia "zoomują się" w kierunku lewego górnego rogu, a nie w kierunku punktu wskazanego myszką.
komentarz 25 czerwca 2021 przez VBService Ekspert (256,320 p.)

No tu już trzeba "pobawić się" ze skalowaniem obrazka i "wycentrowaniem" w momencie jego załadowania.

 

BTW, jak Tobie udało się uzyskać?

bo (oryginalny rozmiar pobrany za pomocą linku z Twojego kodu: https://ironcodestudio.com/wp-content/uploads/2015/03/css-remove-horizontal-scrollbar.jpg)

komentarz 25 czerwca 2021 przez mikolaj.k Obywatel (1,430 p.)
"No tu już trzeba <<pobawić się>> ze skalowaniem obrazka i <<wycentrowaniem>> w momencie jego załadowania."

Dokładnie do tego samego wniosku doszedłem :) I właśnie zabieram się do rozgryzienia tego.

"BTW, jak Tobie udało się uzyskać? bo (oryginalny rozmiar pobrany za pomocą linku z Twojego kodu (...)"

Nie bardzo rozumiem. Narysowałem to w Paincie.
komentarz 25 czerwca 2021 przez VBService Ekspert (256,320 p.)

Chcesz uzyskać:

.zoom-wrapper {
  position: relative;
  width: 300px;  /*  TU rozmiar kontenera gdzie widać obrazek */
  height: 300px;  /*  TU rozmiar kontenera gdzie widać obrazek */
  border: 5px solid #1C6EA4;
}

 

Sam zobacz ile pokrywa kwadrat 300 x 300 wycentrowany względem orginalnego wymiaru obrazka

<img src="https://ironcodestudio.com/wp-content/uploads/2015/03/css-remove-horizontal-scrollbar.jpg" />
<div></div>

<style>
img {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
div {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 300px;
  height:300px;
  border: 4px solid yellow;
  background-color: transparent;
}
</style>

 

komentarz 25 czerwca 2021 przez mikolaj.k Obywatel (1,430 p.)
Obraz nie ma mieć orygnialnego rozmiaru, tylko ma być tak pomniejszony, aby wypełniał kwadrat na takich zasadach o jakich mówiłem wcześniej: "wysokość zdjęcia o orientacji poziomej nie może wykraczać poza wysokość swojego diva, a szerokość zdjęcia o orientacji pionowej nie może wykraczać poza szerokość swojego diva".
komentarz 25 czerwca 2021 przez VBService Ekspert (256,320 p.)

Ciekawe smiley z użyciem: transform: translate(-50%, -50%) scale(0.5); 

<img src="https://ironcodestudio.com/wp-content/uploads/2015/03/css-remove-horizontal-scrollbar.jpg" />
<div></div>
 
<style>
img {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.5);
}
div {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 300px;
  height:300px;
  border: 4px solid yellow;
  background-color: transparent;
}
</style>

 

komentarz 25 czerwca 2021 przez VBService Ekspert (256,320 p.)

Ciekawych rzeczy można się dowiedzieć analizując kody związane z panzoom-em na github-ie: [ 1 ]  [ 2 ].

komentarz 25 czerwca 2021 przez mikolaj.k Obywatel (1,430 p.)
edycja 28 czerwca 2021 przez mikolaj.k

Dzięki .::VBService::..

transform: translate(-50%, -50%) scale(0.5);  nie działa w każdym przypadku. Po za tym, gdy korzystamy z biblioteki, powinniśmy operować jej API, czyli 

panzoom1.pan(x, y)
panzoom1.zoom(z)

bo gdy używamy języka stylów, to "biblioteka nie zapamiętuje tego" (nie wiem co tam się dokładnie dzieje) i gdy klikamy na obraz myszką, to wartości pan i zoom przeskakują do ostatniej zapamiętanej pozycji. Wartości procentowe w API nie przechodzą, a przynajmniej ja nie wiem co zrobić, aby w łatwy sposób przechodziły.

komentarz 25 czerwca 2021 przez mikolaj.k Obywatel (1,430 p.)
edycja 28 czerwca 2021 przez mikolaj.k
wyśrodkowałem te dwa divy i przeniosłem kod na własny serwer: https://srv19859.microhost.com.pl/kadrowanie/ może się to przydać, łatwiej jest kadrować obrazy ręcznie
komentarz 25 czerwca 2021 przez mikolaj.k Obywatel (1,430 p.)
edycja 26 czerwca 2021 przez mikolaj.k
https://codepen.io/reti/pen/MWpMNYE

"Zoomowanie" jest prawidłowe, ale nie wiem jak to wycentrować.
komentarz 25 czerwca 2021 przez VBService Ekspert (256,320 p.)
edycja 25 czerwca 2021 przez VBService

[ edit ]

Spróbuj użyć Window.getComputedStyle()

np.:

const zoom_area1 = document.querySelector('.zoom-area1 img');
const zoom_area1_style = window.getComputedStyle(zoom_area1);
panzoom1.zoom(300 / parseInt(zoom_area1_style.getPropertyValue('height')));
 
// pełna lista dostępnych właściwości
// ale sprawdź z poziomu konsoli przeglądarki nie codepen-a
// bo to czasem jest długa list, a konsola pen ucina ;-) 
console.log(zoom_area1_style);
console.log(zoom_area1_style.getPropertyValue('height'));
console.log(parseInt(zoom_area1_style.getPropertyValue('height')));

komentarz 25 czerwca 2021 przez VBService Ekspert (256,320 p.)
edycja 25 czerwca 2021 przez VBService

Jak poruszasz obrazkiem możesz sobie zobaczyć, co panzoom ustawia w css-ie.

[ edit ]

nie znam tego API pierwszy raz się z nim stykam, ale miałem nosa co do : translate() i scale() to api też na tym bazuje

<div class="zoom-area1" 
  style="cursor: move; user-select: none; 
         touch-action: none; transform-origin: 50% 50%;
         transition: none 0s ease 0s;
         transform: scale(0.40657) translate(-357.256px, -1323.37px);">
    <img src="https://www.thesprucecrafts.com/thmb/0hfae1T5sfjBz3HGmKmQiJasKsM=/2122x1415/filters:fill(auto,1)/TravelPhotographer_Alberta-Canada_Wayne-Simpson_Getty-Images-56a97ec73df78cf772a78262.jpg">
</div>

 

komentarz 25 czerwca 2021 przez mikolaj.k Obywatel (1,430 p.)

" Musisz użyć Window.getComputedStyle() "

dlaczego muszę? co mi to da?

"Jak poruszasz obrazkiem możesz sobie zobaczyć, co panzoom ustawia w css-ie."

to wiem, to mi bardzo pomogło

" nie znam tego API pierwszy raz się z nim stykam”

to się da rozwiązać raczej tylko przez API, jestem już blisko; zoomowanie działa tak jak chcę: https://srv19859.microhost.com.pl/kadrowanie/ teraz chciałbym pozyskiwać jakoś tego typu wartości:

https://drive.google.com/file/d/17p9MkqKWS55E4kdVQyYUA_q8KETsL3Jd/view?usp=sharing

stąd już niedaleka droga do wyliczania wycentrowanej pozycji obrazka w px, a wartości w px można podać do funkcji pan()

wiem, że odległość diva od jego rodzica można mierzyć za pomocą offset, ale to nie działa; nie wiem czemu; div . zoom-area1 w jakiejkolwiek pozycji by nie był, to jego offsetTop zawsze wynosi 322:

https://drive.google.com/file/d/1lW6tgoveQzLt4XzHTtR60waIdQVOPP2P/view?usp=sharing

o co tutaj chodzi?

„ale miałem nosa co do : transform: translate(-50%, -50%) scale(0.5); to api też na tym bazuje "

ok, ale do czego potrzebujemy tej wiedzy?

komentarz 25 czerwca 2021 przez mikolaj.k Obywatel (1,430 p.)
edycja 25 czerwca 2021 przez mikolaj.k
[usunięty]

Podobne pytania

0 głosów
1 odpowiedź 150 wizyt
0 głosów
1 odpowiedź 380 wizyt
pytanie zadane 13 kwietnia 2018 w JavaScript przez anna135B Początkujący (270 p.)
0 głosów
0 odpowiedzi 167 wizyt
pytanie zadane 8 kwietnia 2019 w JavaScript przez Ola Piątek Nowicjusz (240 p.)

93,172 zapytań

142,184 odpowiedzi

321,965 komentarzy

62,496 pasjonatów

Advent of Code 2024

Top 15 użytkowników

  1. 918p. - dia-Chann
  2. 902p. - Łukasz Piwowar
  3. 901p. - CC PL
  4. 894p. - Łukasz Eckert
  5. 872p. - Michal Drewniak
  6. 867p. - Marcin Putra
  7. 858p. - rafalszastok
  8. 856p. - rucin93
  9. 842p. - Dawid128
  10. 840p. - Adrian Wieprzkowicz
  11. 830p. - Piotr Aleksandrowicz
  12. 826p. - Michał Telesz
  13. 819p. - Mariusz Fornal
  14. 814p. - Mikbac
  15. 812p. - TheLukaszNs
Szczegóły i pełne wyniki

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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...