테스트 사이트 - 개발 중인 베타 버전입니다

롤링배너(?) 갤러리

· 2년 전 · 1733 · 20

 

https://sir.kr/qa/495896 - 질문이 올라와서 예전에 만들어 두었던 것을 약간 보층해서 코드 공유합니다.

제가 별로 안 쓰는 형태라 개별버튼은 안 만들었습니다.^^

장면전환시 애니메이션 css 를 쓰지 않고 레거시(?)한 방식으로 감속탄성 코드를 자바스크립트에서 만들었습니다.

 

https://wittazzurri.com/editor/html_editor.php 에서 확인해 보세요.

 

image_1 부터 image_n 까지 원하는 대로...

 

[code]

<style>
#galleryDiv { position:relative; margin:0 auto; }
#imageDiv { overflow:hidden; }
#imageDiv div { display:flex; width:200%; }
#imageDiv img { display:block; width:50%; }
#buttonDiv { position:absolute; top:0px; width:100%; height:100%; padding:20px; display:flex; justify-content:space-between; align-items:center; box-sizing:border-box; }
#buttonDiv img { display:block; cursor:pointer; width:50px; height:50px; }
</style>
<div id="galleryDiv">
    <div id="imageDiv"><div><img><img></div></div>
    <div id="buttonDiv"><img><img></div>
</div>
<script>
autoSec = 5; // 자동넘기기 - 초단위
targetSpeed = 10; // 장면전환 속도 - 숫자가 커질수록 느려짐
leftButton = "https://blog.kakaocdn.net/dn/I1GYB/btq8bL8uxVv/guiZYpTMedre9zj97Y1jk0/img.png"; // 좌버튼 이미지
rightButton = "https://blog.kakaocdn.net/dn/bniCh0/btq8bsg19MB/PJUsaJdJkpJdbkHcWUC9wk/img.png"; // 우버튼 이미지
image_1 = "https://blog.kakaocdn.net/dn/bS0Wvp/btr8J1cQhlx/hl8E8tv5M9rfwvuma8q6Fk/img.jpg";
image_2 = "https://blog.kakaocdn.net/dn/zYSgG/btr8P0DskTO/i6JzVmVy3gsM5by353o3E0/img.jpg";
image_3 = "https://blog.kakaocdn.net/dn/bD8PyW/btr8LgN5SsY/AvjSnqZ0xgsM3FvpHsaDh1/img.jpg";
image_4 = "https://blog.kakaocdn.net/dn/dSddpv/btr8Mn64wqT/b5P6xKyDYfVXuDOeEtcKtK/img.jpg";
image_5 = "https://blog.kakaocdn.net/dn/cBCuTv/btr8J48xbjE/e5z35o9vMjSJeYJA8auRJ1/img.jpg";
buttonDiv.querySelectorAll("img")[0].src = leftButton;
buttonDiv.querySelectorAll("img")[1].src = rightButton;
for (imgTotal = 0; this["image_" + (imgTotal + 1)]; imgTotal++);
function imageMode() {
    imageDiv.querySelectorAll("img")[0].src = this["image_" + arguments[0]];
    imageDiv.querySelectorAll("img")[1].src = this["image_" + (arguments[0] === imgTotal ? 1 : ++arguments[0])];
    targetCount = 0;
}
addEventListener("resize", galleryMode = () => {

    galleryDiv.style.width = "100%";
    galleryWidth = Math.floor(galleryDiv.offsetWidth);
    galleryDiv.style.width = galleryWidth + "px"; 
    galleryPoint = -galleryWidth;
    imageDiv.querySelector("div").style.marginLeft = "0px";
} );
galleryMode();
imageMode(img = 1);
buttonDiv.querySelectorAll("img")[0].onclick = () => {
    targetCount = autoSec * 100;
    for (ic of document.querySelectorAll("#imageDiv, #imageDiv img")) ic.style.transform = "rotateY(180deg)";
}
buttonDiv.querySelectorAll("img")[1].onclick = () => {
    targetCount = autoSec * 100;
    for (ic of document.querySelectorAll("#imageDiv, #imageDiv img")) ic.style.transform = "rotateY(0deg)";

setInterval(() => {
    ++targetCount;
    changePoint = Number(imageDiv.querySelector("div").style.marginLeft.slice(0, -2));
    if (Math.abs(changePoint - galleryPoint) <= 0.5) {
        imageDiv.querySelector("div").style.marginLeft = "0px";
        imageMode(img = img === imgTotal ? 1 : ++img);
    }
    else {
        if (targetCount >= 0 && targetCount < autoSec * 100) changePoint = 0;
        else changePoint += (galleryPoint - changePoint) / targetSpeed;
        imageDiv.querySelector("div").style.marginLeft = changePoint + "px";
    }
}, 10);
</script>

[/code]

댓글 작성

댓글을 작성하시려면 로그인이 필요합니다.

로그인하기

댓글 20개

2년 전
좋아요, 감사 합니다.
2년 전
@들레아빠 감사합니다. 참고로
image_1 에서 image_n 까지 최종숫자 n 을 추출하는 코드는 아래처럼 imgTotal 을 추출하는 것이 좋습니다. 최종숫자를 입력할 필요가 없거든요.

for (imgTotal = 0; this["image_" + (imgTotal + 1)]; imgTotal++);

https://sir.kr/g5_tip/16115
2년 전
@비타주리 네, 감사 합니다.
[code]
for (var i = 1; i <= 5; i++){
this['image_' + i] = ["/img/banner/"+i+".jpg"];
}
[/code]
2년 전
@들레아빠
<script>
image_1 = ["1.jpg"];
document.write(typeof image_1);
</script>
<br>
<script>
image_1 = "1.jpg";
document.write(typeof image_1);
</script>

이리하면 변수의 타입이 처음은 오브젝트(배열등) 다음은 스트링(문자열)으로 나타납니다.
단순 문자열을 굳이 배열에 담아 리소스를 키울 필요가 없거든요.
아래처럼 바꾸세요.

this['image_' + i] = "/img/banner/"+i+".jpg";
2년 전
@비타주리 역시 !! 대단히 감사 합니다.
좋습니다^^
자바스크립트로 만든 갤러리가 오류도 안나고 그누보드 버전에 관계없이 사용할 수있어서 좋은것 같습니다
이미지에 링크를 주려면 이미지 앞에 a 태그를 사용해서 하는데요.
<a href="https://sir.kr">image_1 = "https://blog.kakaocdn.net/dn/bS0Wvp/btr8J1cQhlx/hl8E8tv5M9rfwvuma8q6Fk/img.jpg";</a>
이렇게 하면 될것 같은데, 적용해 보니 잘 안되는데요.
링크에도 for 문을 사용해야 되는지요.
감사합니다.
2년 전
@김철용
1. 링크영역의 최대확보를 위해 #buttonDiv 의 padding 을
padding:20px; 에서 padding:0px 20px; 으로 바꿉니다.

2. css 에서 a 를 정의해 주구요. 시각화를 위해 배경색을 red 로 깔아줍니다.
#buttonDiv a { width:100%; height:100%; background-color:red; }

3. <div id="buttonDiv"><img><img></div> 를 아래처럼 고치고요.
<div id="buttonDiv"><img><a target="_blank"></a><img></div>

4. image_1 부터 image_5 아래에 같은 숫자의 링크 변수를 만들어 줍니다.
link_1 = "1번링크주소";
link_2 = "2번링크주소";
link_3 = "3번링크주소";
link_4 = "4번링크주소";
link_5 = "5번링크주소";

5. function imageMode() 의 가장 상단에 링크코드를 한줄만 더 첨가합니다.
[code]
function imageMode() {
buttonDiv.querySelector("a").href = this["link_" + arguments[0]];
imageDiv.querySelectorAll("img")[0].src = this["image_" + arguments[0]];
imageDiv.querySelectorAll("img")[1].src = this["image_" + (arguments[0] === imgTotal ? 1 : ++arguments[0])];
targetCount = 0;
}
[/code]
6. 확인이 끝났으면 2번에서 배경 빨간색을 삭제합니다.
#buttonDiv a { width:100%; height:100%; }

그래서 최종으로...
[code]
<style>
#galleryDiv { position:relative; margin:0 auto; }
#imageDiv { overflow:hidden; }
#imageDiv div { display:flex; width:200%; }
#imageDiv img { display:block; width:50%; }
#buttonDiv { position:absolute; top:0px; width:100%; height:100%; padding:0px 20px; display:flex; justify-content:space-between; align-items:center; box-sizing:border-box; }
#buttonDiv img { display:block; cursor:pointer; width:50px; height:50px; }
#buttonDiv a { width:100%; height:100%; }
</style>
<div id="galleryDiv">
<div id="imageDiv"><div><img><img></div></div>
<div id="buttonDiv"><img><a target="_blank"></a><img></div>
</div>
<script>
autoSec = 5; // 자동넘기기 - 초단위
targetSpeed = 10; // 슬라이드 속도 - 숫자가 커질수록 느려짐
leftButton = "https://blog.kakaocdn.net/dn/I1GYB/btq8bL8uxVv/guiZYpTMedre9zj97Y1jk0/img.png"; // 좌버튼 이미지
rightButton = "https://blog.kakaocdn.net/dn/bniCh0/btq8bsg19MB/PJUsaJdJkpJdbkHcWUC9wk/img.png"; // 우버튼 이미지
image_1 = "https://blog.kakaocdn.net/dn/bS0Wvp/btr8J1cQhlx/hl8E8tv5M9rfwvuma8q6Fk/img.jpg";
image_2 = "https://blog.kakaocdn.net/dn/zYSgG/btr8P0DskTO/i6JzVmVy3gsM5by353o3E0/img.jpg";
image_3 = "https://blog.kakaocdn.net/dn/bD8PyW/btr8LgN5SsY/AvjSnqZ0xgsM3FvpHsaDh1/img.jpg";
image_4 = "https://blog.kakaocdn.net/dn/dSddpv/btr8Mn64wqT/b5P6xKyDYfVXuDOeEtcKtK/img.jpg";
image_5 = "https://blog.kakaocdn.net/dn/cBCuTv/btr8J48xbjE/e5z35o9vMjSJeYJA8auRJ1/img.jpg";
link_1 = "https://blog.kakaocdn.net/dn/bS0Wvp/btr8J1cQhlx/hl8E8tv5M9rfwvuma8q6Fk/img.jpg";
link_2 = "https://blog.kakaocdn.net/dn/zYSgG/btr8P0DskTO/i6JzVmVy3gsM5by353o3E0/img.jpg";
link_3 = "https://blog.kakaocdn.net/dn/bD8PyW/btr8LgN5SsY/AvjSnqZ0xgsM3FvpHsaDh1/img.jpg";
link_4 = "https://blog.kakaocdn.net/dn/dSddpv/btr8Mn64wqT/b5P6xKyDYfVXuDOeEtcKtK/img.jpg";
link_5 = "https://blog.kakaocdn.net/dn/cBCuTv/btr8J48xbjE/e5z35o9vMjSJeYJA8auRJ1/img.jpg";
buttonDiv.querySelectorAll("img")[0].src = leftButton;
buttonDiv.querySelectorAll("img")[1].src = rightButton;
for (imgTotal = 0; this["image_" + (imgTotal + 1)]; imgTotal++);
function imageMode() {
buttonDiv.querySelector("a").href = this["link_" + arguments[0]];
imageDiv.querySelectorAll("img")[0].src = this["image_" + arguments[0]];
imageDiv.querySelectorAll("img")[1].src = this["image_" + (arguments[0] === imgTotal ? 1 : ++arguments[0])];
targetCount = 0;
}
addEventListener("resize", galleryMode = () => {
galleryDiv.style.width = "100%";
galleryWidth = Math.floor(galleryDiv.offsetWidth);
galleryDiv.style.width = galleryWidth + "px";
galleryPoint = -galleryWidth;
imageDiv.querySelector("div").style.marginLeft = "0px";
} );
galleryMode();
imageMode(img = 1);
buttonDiv.querySelectorAll("img")[0].onclick = () => {
targetCount = autoSec * 100;
for (ic of document.querySelectorAll("#imageDiv, #imageDiv img")) ic.style.transform = "rotateY(180deg)";
}
buttonDiv.querySelectorAll("img")[1].onclick = () => {
targetCount = autoSec * 100;
for (ic of document.querySelectorAll("#imageDiv, #imageDiv img")) ic.style.transform = "rotateY(0deg)";
}
setInterval(() => {
++targetCount;
changePoint = Number(imageDiv.querySelector("div").style.marginLeft.slice(0, -2));
if (Math.abs(changePoint - galleryPoint) <= 0.5) {
imageDiv.querySelector("div").style.marginLeft = "0px";
imageMode(img = img === imgTotal ? 1 : ++img);
}
else {
if (targetCount >= 0 && targetCount < autoSec * 100) changePoint = 0;
else changePoint += (galleryPoint - changePoint) / targetSpeed;
imageDiv.querySelector("div").style.marginLeft = changePoint + "px";
}
}, 10);
</script>
[/code]
감사합니다.
배울게 산더미 같군요..ㅎ
배너 공부하는데 엄청 도움이 될 것 같습니다.

그런데 브라우저 리사이즈할 때 그림이 자동 확대,축소가 되지 않아

galleryWidth = Math.floor(galleryDiv.offsetWidth);

이 라인을

galleryWidth = window.innerWidth;

이렇게 바꿨더니 제대로 되는것 같습니다.
바꿔도 별 문제 없겠지요??
2년 전
@도레미 리사이즈 이벤트의 경우 저는 모바일에서 가로 세로 전환 또는 그 역전환만 신경씁니다.
pc는 신경도 안 쓰거든요.ㅋ

그런데 도레미님처럼 하면 가령 갤러리 가로를 pc에서는 900픽셀 모바일에서는 100퍼센트로 주는 식은 힘들고 오직 가로 이빠이 이벤트만 될 터이라...

본인이 편한 방식대로 쓰면 되죠.
제가 Math.floor 을 준 이유는 예를 들어 상위 엘레먼트가 1001픽셀이고 여기에 90퍼센트로 크기를 주면 픽셀값이 소숫점으로 나와요.
그럼 셋인터벌을 오래 놔두면 사이즈 삑사리가 나서 보기가 싫어집니다.
그래서 버림값 자연수를 취해서 딱 떨어지게 맞추어야 장기간 셋인터벌에서도 소숫점 삑사리가 나지 않습니다.
2년 전
@도레미
테이블 css 에 table-layout:fixed 를 주면 소숫점 삑사리가 나지 않습니다.
그외 다른 엘레먼트로 flex 또는 grid 로 만들면 테이블처럼 정확하지 않고 문제가 발생해서...
그렇게 테이블로 코드를 짜면 웹표준이네 뭐네 하는 소리 듣기 싫어서 첨부터 버림값 자연수를 취해 마진제로오토로 중앙정렬시켜서 코드를 짜게 되더라구요.ㅋ

게시글 목록

번호 제목
17819
17818
17817
17816
17814
17811
17810
17809
17808
17803
17799
17798
17797
17795
17794
17793
JavaScript JSON Beautify
17790
17789
17786
17774
17760
17755
17750
17729
17722
17714
17708
17686
17676
17666