상세 컨텐츠

본문 제목

흘렁 흘렁 슬라이더 전자알밤

자바스크립트

by e7e 2023. 7. 20. 08:28

본문

 

스마트폰이  출현하기전, 디지털 카메라와 캠이 아주 유행하던 시절이 있었당.

당시 지금의 패드모양의 전자앨범이라는 것이 있는 가정들이 꽤 있었고,TV에서도

기능이 지원되어, USB 메모리에 사진을 모아서 꼬기에  꽂으면 사진들이 미끄러지듯

슬라이딩 되어 추억을 되새김질하거나, 본인의 추억을 다른 사람들에게 무참히 심하게

강요하는 잘난 체 용도로 많이 사용되었당.

 

역시 항상 그렇진 않지만 웹 어플로 만드는 거슨 우산으로 가랑비를 막는 것보다 쉽당.

(인정머리 없는 사람은 인정하지 않겠지만 인정을 가지고 인정하장.!~~)

 

물론 개별 인간마다 쪼금식 아님 크게 코드가 다를 수 있지만, 최대한 쉽게 이해 

될 수 있도록  난 아래처럼 소스를 짜보았당.(내맘!)

간단히 설명하면  div크기를 원하는 액자크기로 설정하고, overflow를 hidden으로

설정하면, 이보다 큰건 다 잘려서 보이지 않게 된당(곧 액자가 된당);

자식은 크게 이미지 4개씩을 1줄에 포함할 크기를  가진 긴 2개의 긴 div를 맹글어서

나래비로 줄 세워서 같이 천천히 움직이다가, 오른쪽 끝이 액자의 왼쪽을 벗어나는 

순간 다시 해당 div는 다른 div의 뒤로 이동한당. 

이 흐름을 누느로 화긴 할 수 있게, 오버플로 (토글) 버튼을 일부러 넣었당.

참고로 document.styleSheets[0].cssRules[2] 요런 코드를 넣었는뎅,

구글 검색을 통해 공부를 해보장!(자바스크립트로 style태그에 접근하는 법이당!)

 

imgSlider.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>E7E 메롱</title>
    <style>
    * {
        margin:0px;padding:0px;
        box-sizing: border-box;
    }

    #wrapper {
        position: relative;
        margin:0 auto;
        top: 10vh;
        width: 440px;
        text-align: center;
    }
    #acja {
        position: relative;
        margin:0 auto;
        width: 440px;
        height: 440px;
        border: 20px groove gold;
        background-color: orange;
        overflow: hidden;
    }
    #leftBox{
        position:absolute;
        margin:0;
        left:0; top:0;
        width: 1620px;
        height:400px;
    }
    #rightBox{
        position:absolute;
        margin:0;
        left:1600px; top:0;
        width: 1620px;
        height:300px;
    }

    img {
        width: 400px;
        height: 400px;
    }

    input[type=button] {
        position: absolute;  
        width: 50%;
        height: 40px;
        left: 0px;
        font-weight: bolder;
    }

    input[name=btn2]{
        left:50%;
    }
    h1{
        background-color: orange;
    }
    </style>
</head>
<body>
<div id="wrapper">
    <h1>&copy; E7E 슬라이딩 전자앨범</h1>
    <div id="acja">
        <div id="leftBox">
            <img src="https://cdn.pixabay.com/photo/2016/07/11/15/43/woman-1509956_640.jpg">
            <img src="https://cdn.pixabay.com/photo/2019/07/30/06/00/rose-4372048_640.png">
            <img src="https://cdn.pixabay.com/photo/2017/05/09/13/31/spring-2298279_640.jpg">
            <img src="https://cdn.pixabay.com/photo/2017/07/25/01/22/cat-2536662_640.jpg">
        </div>
        <div id="rightBox">
            <img src="https://cdn.pixabay.com/photo/2017/11/14/13/06/kitty-2948404_640.jpg">
            <img src="https://cdn.pixabay.com/photo/2014/04/13/20/49/cat-323262_640.jpg">
            <img src="https://cdn.pixabay.com/photo/2014/11/30/14/11/cat-551554_640.jpg">
            <img src="https://cdn.pixabay.com/photo/2016/01/20/13/05/cat-1151519_640.jpg">    
        </div>
    </div>
    <input type=button name=btn1 value="슬라이딩!" onclick="fStart(this)">
    <input type=button name=btn2 value="오버플로(토글)" onclick="fOverflow()">
</div>
<script>
const mov = 5;          // 움직임 튜닝값
const loopTime = 100;   // 반복타이머 튜닝값
const maxWidth = 1610;  // 튜닝값
const myLeftBox = document.querySelector("#leftBox");
const myRightBox = document.querySelector("#rightBox");

let isStart=false; // 시작 안한 상태
let timer;
//슬라이딩 버튼 눌러도 속도 안빨라지겡, Proxy(대리) 적용
function fStart(pThis){
    if(!isStart){
        fSlide();
        isStart = true;
        pThis.value = "멈춤";
        return;
    }
    clearTimeout(timer);
    pThis.value = "슬라이딩!";
    isStart = false;
}

//슬라이딩 함숭
function fSlide(){
    // inline 스타일이 정의되어 있지 않을 땡 초기황
    if(!myLeftBox.style.left) myLeftBox.style.left = "0px";
    if(!myRightBox.style.left) myRightBox.style.left =`${maxWidth}px`;

    // 이미지4개 그룹단위 이동
    myLeftBox.style.left = parseInt(myLeftBox.style.left) - mov + "px";
    myRightBox.style.left = parseInt(myRightBox.style.left) - mov + "px";
    
    // 액자 왼쪽 벗어나면 다시 오른쪽으로... 
    if(parseInt(myLeftBox.style.left) < -maxWidth)  myLeftBox.style.left = `${maxWidth}px`;
    if(parseInt(myRightBox.style.left) < -maxWidth) myRightBox.style.left = `${maxWidth}px`;
    
    // 재귀호출로 반뽁!
    timer = setTimeout(fSlide,loopTime);
}

//OverFlow 토글링 함숭
const acjaRule = document.styleSheets[0].cssRules[2];
function fOverflow(){
    if(acjaRule.style.overflow == "hidden"){
        acjaRule.style.overflow = "visible";
    } else {
        acjaRule.style.overflow = "hidden";
    }
}
</script>
</body>
</html>

아래 그림은 내게로 다가 온 결과이당.

잘 이해되었는지 확인하려면 세로로 움직이는 걸 직접 한번 맹글어보길 추천한당.

 

이제 이미지 슬라이더를 이해했다면

2023.07.16 - [자바스크립트] - 대충 이미지 검색 왕창 다운로띵 ajax 1

글의 이미지 검색 기능과 합쳐서, 일일이 이미지를 넣지 않고, 검색된 이미지를 이용하여,

슬라이딩 되도록 쪼메 쓸모있게 맹글어 보장.

난 아래처럼 맹글었당.(맘에 안 든다면 맘껏 고쳐랑. 적극 추천한당)

 

사실 성능을 위한 개선 뽀인토가 있지만, 조건이 마니 들어가면 흐름이 어려워질 수 있어

그냥 내버려두공, 간단히 로딩화면을 모달로  넣어 보았당. 

Style과 HTML을 빼면 기럭지도 사실 그리 길지 않공, 핵심만 이해되면 소스는 역시 별거없당.

카.복 해서 실행해 보고, 마음껏 자유롭게 고치고, 기능 추가를 통해 실력을 올리고 올리장!

브라우져 플러그인 Cross-Origin을 켜는 걸 잊지말장!, 안 켜면 동작 안한당.

 

imgSlideUp.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>E7E 메롱</title>
    <style>
    * {
        margin:0px;padding:0px;
        box-sizing: border-box;
    }

    #wrapper {
        position: relative;
        margin:0 auto;
        top: 10vh;
        width: 440px;
        text-align: center;
    }
    #acja {
        position: relative;
        margin:5px auto;
        width: 440px;
        height: 440px;
        border: 20px groove gold;
        background-color: orange;
        overflow: hidden;
    }
    #leftBox{
        position:absolute;
        margin:0;
        left:0; top:0;
        width: 1620px;
        height:400px;
    }
    #rightBox{
        position:absolute;
        margin:0;
        left:1600px; top:0;
        width: 1620px;
        height:300px;
    }

    img {
        width: 400px;
        height: 400px;
    }

    input[type=button] {
        position: absolute;  
        width: 50%;
        height: 40px;
        left: 0px;
        font-weight: bolder;
    }

    input[name=btn2]{
        left:50%;
    }
    h1{
        background-color: orange;
    }
    #modal {
        position: fixed;
        width:50vw;height: 8vh;
        left:25vw; top:25vh;
        border:3px solid yellowgreen;
        background-color:blueviolet;
        z-index: 100;
        color:white;
        text-align: center;
        padding-top: 10px;
        font-size: 1.5em;
        display: none;
    }
    #bar {
        margin-left: 10px;
        height:2vh;
        background-color: orange;
    }
    #icnt {
        color:red;
        font-weight: bolder;
    }
    </style>
</head>
<body>
<div id="modal">
    <div id="cont">
        <span>껌색 & 로딩 주웅.. 쪼메망</span>
        <div id="bar" style="width:5%"></div>
    </div>    
</div>
<div id="wrapper">
    <h1>&copy; E7E 슬라이딩 전자앨범</h1>
    <span id="icnt"></span>&nbsp;&nbsp;&nbsp;&nbsp;
    <input type="text" id="schWord" value="" placeholder="검색할 이미지 적어주삼" autofocus>
    <button id="schBtn">껌색</button><br>
    <div id="acja">
        <div id="leftBox">
            <img class="mimg" src="">
            <img class="mimg" src="">
            <img class="mimg" src="">
            <img class="mimg" src="">
        </div>
        <div id="rightBox">
            <img class="mimg" src="">
            <img class="mimg" src="">
            <img class="mimg" src="">
            <img class="mimg" src="">    
        </div>
    </div>
    <input type=button name=btn1 value="슬라이딩!" onclick="fStart(this)" disabled>
    <input type=button name=btn2 value="오버플로(토글)" onclick="fOverflow()" disabled>
</div>
<script>
const firstImg="https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname="+
  "https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtP7jD%2FbtslULIgpW3%2FYodBq2rXAE7zteNfkFsdy1%2Fimg.jpg";
//필요한 전역변수 선언
const mov = 5;          // 움직임 튜닝값
const loopTime = 100;   // 반복타이머 튜닝값
const maxWidth = 1610;  // 튜닝값
let mImgCnt = 8;        // 이미지 index로 사용
const currImgCnt =8;    //이미지갯수
let isStart=false;      // 시작 안한 상태
let timer=null;         // 타이머
let time2=null;         // modal(로딩용)
let imgUrlArr; 

const myIcnt = document.querySelector("#icnt");
const myModal = document.querySelector("#modal");
const myBar = document.querySelector("#bar");
const myLeftBox = document.querySelector("#leftBox");
const myRightBox = document.querySelector("#rightBox");
const myBtn1 = document.querySelector("[name=btn1]");
const myBtn2 = document.querySelector("[name=btn2]");
const myMimg = document.querySelectorAll(".mimg");
myMimg[0].src = firstImg;

const mySchWord = document.querySelector("#schWord");
const mySchBtn = document.querySelector("#schBtn");
//구글 이미지 검색 URL
const preSchURL = "https://www.google.com/search?q=";
const postSchURL = "&tbm=isch";   // 이미지 서치

//검색버튼 이벤트, 엔터키 이벤트
mySchBtn.onclick = fSch;
mySchWord.onkeydown = function(){
    if(event.keyCode == 13){
        fSch();
    }
}

// 초기화
function fInit(){
    myBtn1.disabled=true;
    myBtn2.disabled=true;
    myLeftBox.style.left = "0px";
    myRightBox.style.left =`${maxWidth}px`;
}

// 로딩 중 모달
function fLoading(){
    if(parseInt(myBar.style.width) > 95) myBar.style.width="5%"; 
    myBar.style.width = parseInt(myBar.style.width)+5+"%";
    timer2=setTimeout(fLoading,500);
}


//이미지 URL검색함숭
function fSch(){
    if(timer){
        //clearTimeout(timer);
        myBtn1.click();
    }
    fInit(); // 초기화

    imgUrlArr = [];   // img url 담을 배열
    let schURL = `${preSchURL}${mySchWord.value}${postSchURL}`;

    let xhr = new XMLHttpRequest();
    xhr.open("get",schURL,true);

    xhr.onreadystatechange = ()=>{
        if(xhr.readyState == 4 && xhr.status == 200){
            let cont = xhr.responseText;

            // sIndex는 찾기시작 index값으로 대략 튜닝값(찾을 문자열이 실제 더 뒤에 나옴,내맘!)
            let sIndex = 50000;         
            let fIndex =1;

            myModal.style.display = "block";
            fLoading();
            while( (startIndex = cont.indexOf("[\"https://",sIndex)) != -1){
                sIndex = startIndex+2;
                let eIndex = cont.indexOf("\"",sIndex);
                let imgURL = cont.substring(sIndex,eIndex);
                // 막혔거나(403), 못찾는(404) url은 제외하고 오직 jpg만
                if(imgURL.includes(".jpg") && !imgURL.includes("chosun") 
                   && !imgURL.includes("post-phinf") && !imgURL.includes("thumbnews")
                   && !imgURL.includes("blogthumb") && !imgURL.includes("vingle")
                   && !imgURL.includes("newsen")    && !imgURL.includes("an2-img")
                   && !imgURL.includes("pstatic")
                   && !imgURL.includes("mblogthumb") && !imgURL.includes("daumcdn")){
                    console.log(imgURL);
                    imgUrlArr.push(imgURL);

                }
            }
            myIcnt.innerHTML = imgUrlArr.length + "개 발견";
            // 억지로 로딩체킁, 첫번째 이미지만
            //console.log("결과:",imgUrlArr);
            let ckImg = new Image();
            ckImg.onload = function(){
                myBar.style.width = "100%";
                clearTimeout(timer2);
                myMimg[0].src = ckImg.src;
                mImgCnt += currImgCnt/2;
                myBtn1.disabled=false;
                myBtn2.disabled=false;
                myModal.style.display="none";
                myBar.style.width="5%";
            }
            ckImg.src= imgUrlArr[0];

            // 억지롱 로딩체킁 끝

            for(let i=1; i< currImgCnt; i++){
                myMimg[i].src= imgUrlArr[i];
            }
        }
    }
    xhr.send();
}

//슬라이딩 버튼 눌러도 속도 안빨라지겡, Proxy(대리) 적용
function fStart(pThis){
    if(!isStart){
        fSlide();
        isStart = true;
        pThis.value = "멈춤";
        return;
    }
    clearTimeout(timer);
    timer=null;
    pThis.value = "슬라이딩!";
    isStart = false;
}

//슬라이딩 함숭
function fSlide(){
    // inline 스타일이 정의되어 있지 않을 땡 초기황
    if(!myLeftBox.style.left) myLeftBox.style.left = "0px";
    if(!myRightBox.style.left) myRightBox.style.left =`${maxWidth}px`;

    // 이미지4개 그룹단위 이동
    myLeftBox.style.left = parseInt(myLeftBox.style.left) - mov + "px";
    myRightBox.style.left = parseInt(myRightBox.style.left) - mov + "px";
    
    // 액자 왼쪽 벗어나면 다시 오른쪽으로...(내맘)
    if(parseInt(myLeftBox.style.left) <= -maxWidth)  {
        chgNewImg(myLeftBox,0);
    }
    if(parseInt(myRightBox.style.left) <= -maxWidth) {
        chgNewImg(myRightBox,currImgCnt/2);
    }
    // 재귀호출로 반뽁!
    timer = setTimeout(fSlide,loopTime);
}

//벗어나면 새로운 이미지로 바꾸깅!
function chgNewImg(pBox,pStart){
        pBox.style.left = `${maxWidth}px`;
        for(let i=pStart; i< (pStart+currImgCnt/2); i++){
            mImgCnt++;
            if(mImgCnt >= imgUrlArr.length) mImgCnt=0; 
            myMimg[i].src = imgUrlArr[mImgCnt];
        }
}

//OverFlow 토글링 함숭
const acjaRule = document.styleSheets[0].cssRules[2];
function fOverflow(){
    if(acjaRule.style.overflow == "hidden"){
        acjaRule.style.overflow = "visible";
    } else {
        acjaRule.style.overflow = "hidden";
    }
}
</script>
</body>
</html>

아래 그림은 나를 찾아서 온 결과를 바로 캡쳐한 결과이당.

참고로 소스에 직접 이미지에 접근하는 걸 막은 사이트들을 if문으로 쪼메 걸렀당, 계속 추가해야 할지동

아이디어를 내서 자꾸 기능추가를 해보는 연습을 통해 다린이 될 수 있당. 화이팅이당!

 

 

 

그                                                                                    녀는   멀당

그                                               녀는          조금            덜       멀당

그                        녀는                                꽤                       가깝당

그녀는                                                       정말이지         정말 멀당 

 

자기얌 자기얌  나 유체이탈 해보고  시펑

너 지금도 그렇게 온 정신 아니거든!!

 

 

자스! 너 없는 삶은 별로일거얌

https://www.youtube.com/watch?v=cRM70Jw7F4M 

 

관련글 더보기