본문으로 바로가기

다형성 및 합성을 이용한 심플 롤링 배너 - 단계별 학습 #4

이 글에서는 단계별 #3에 이은 마지막 스텝으로 객체 지향 프로그래밍의 핵심 기능인 다형성과 합성을 활용한 기능 확장 방법에 대해 알아봅니다.

전 단계에서는 롤링 효과가 한가지였으나 여기서는 4가지의 독립적인 롤링 효과를 합성하여 사용해보도록 합니다.




HTML

4가지 롤링 효과를 적용하기 위한 다음과 같은 마크업이 있습니다.

html
<div id="banner1" class="rolling-banner">
    <img src="http://lorempixel.com/400/200/sports/1/">
    <img src="http://lorempixel.com/400/200/sports/2/">
    <img src="http://lorempixel.com/400/200/sports/3/">
    <img src="http://lorempixel.com/400/200/sports/5/">
    <img src="http://lorempixel.com/400/200/sports/6/">
    <img src="http://lorempixel.com/400/200/sports/7/">
</div>
<div id="banner2"class="rolling-banner">

    <img src="http://lorempixel.com/400/200/fashion/9/">
    <img src="http://lorempixel.com/400/200/fashion/8/">
    <img src="http://lorempixel.com/400/200/fashion/3/">
    <img src="http://lorempixel.com/400/200/fashion/5/">
    <img src="http://lorempixel.com/400/200/fashion/6/">
    <img src="http://lorempixel.com/400/200/fashion/7/">
</div>
<div id="banner3" class="rolling-banner">
    <img src="http://lorempixel.com/400/200/nightlife/1/">
    <img src="http://lorempixel.com/400/200/nightlife/2/">
    <img src="http://lorempixel.com/400/200/nightlife/3/">
    <img src="http://lorempixel.com/400/200/nightlife/5/">
    <img src="http://lorempixel.com/400/200/nightlife/6/">
    <img src="http://lorempixel.com/400/200/nightlife/7/">
</div>
<div id="banner4"class="rolling-banner">

    <img src="http://lorempixel.com/400/200/transport/9/">
    <img src="http://lorempixel.com/400/200/transport/8/">
    <img src="http://lorempixel.com/400/200/transport/3/">
    <img src="http://lorempixel.com/400/200/transport/5/">
    <img src="http://lorempixel.com/400/200/transport/6/">
    <img src="http://lorempixel.com/400/200/transport/7/">
</div>



CSS

css
body {
    margin: 20px auto;
    width: 700px;
}
.rolling-banner{
    position:relative;
    float: left;
    overflow:hidden;
    border:2px solid #000;
    width:40%;
    height:150px;
    margin: 10px;
}
.rolling-banner img{
    position:absolute;
    top:0;
    left:0;
    width:100%;
    height:100%;
}



JavaScript

javascript
$(function () {
    // 인스턴스 생성
    var rolling1 = new RollingBanner("#banner1", 2000,600, BTRollingEffect);
    var rolling2 = new RollingBanner("#banner2", 2000,600, TBRollingEffect);
    var rolling3 = new RollingBanner("#banner3", 2000,600, RLRollingEffect);
    var rolling4 = new RollingBanner("#banner4", 2000,600, LRRollingEffect);
});

// 메서드와 프로퍼티를 담을 생성자(클래스)를 생성
function RollingBanner(selector, speed, animateSpeed, effect) {
    // 프로퍼티 생성 및 초기화

    this._$banners = null;
    this._currentIndex = 0;
    this._timerID = -1;
    this._bannerHeight = 0;
    this._bannerWidth = 0;
    this._speed = speed;
    this._aniSpeed = animateSpeed;

    // 롤링효과 인스턴스를 저장할 변수
    this._effect = effect;

    this._init(selector);
    this._initEvent();

}

RollingBanner.prototype = {
    // 요소 초기화
    '_init' : function (selector) {
        this._$banners = $(selector).children("img");
        this._bannerHeight = this._$banners.eq(0).height();

    },
    // 이벤트 처리
    '_initEvent' : function () {
        var _self = this;
        // 롤링 배너 위치값 자동 설정하기 위해 높이값 구하기
        // 이미지와 같은 리소스까지 모두 읽어들여야 높이값을 구할 수 있기 때문에
        // onload 이벤트를 이용
        this._$banners.eq(0).one('load', function () {
            _self._bannerHeight = $(this).height();

            // 배너 너비 구하기
            _self._bannerWidth = $(this).width();

            _self._start();
        })
    },
    '_start' : function () {
        this._initBannerPos();
        this.startAutoPlay();
    },
    '_initBannerPos' : function () {
        // 배너 위치 화면에서 모두 숨기기
        this._$banners.css({
            top : this._bannerHeight
        });
        // 0번째 배너 활성화
        this._$banners.eq(this._currentIndex).css({
            top : 0
        });
    },
    'startAutoPlay' : function () {
        var _self = this;

        // 타이머가 두 번이상 실행되지 않도록 조건 처리
        if(this._timerID == -1) {
            this._timerID = setInterval(function () {
                _self.nextBanner();
            }, this._speed); // 인터벌 지정
        }
    },
    'nextBanner' : function () {
        // 현재 인덱스값 구하기
        var outIndex = this._currentIndex;

        // 다음 배너 인덱스값 구하기
        this._currentIndex++;

        // 마지막 배너까지 롤링되면 다시 0번째부터 롤링되도록 인덱스값 설정하기
        if (this._currentIndex >= this._$banners.length) {
            this._currentIndex = 0;
        }

        // 현재 배너 구하기
        var $outBanner = this._$banners.eq(outIndex);

        // 다음 배너 구하기
        var $inBanner = this._$banners.eq(this._currentIndex);

        /**
         * 기존 효과 주석 처리
         */
        // 롤링 준비 - 나타날 다음 배너 위치 초기화
        // $inBanner.css({
        //    top: this._bannerHeight,
        //    opacity : 0
        // });
        //
        // 현재 배너 사라지게 하기
        // $outBanner.stop().animate({
        //    top: -this._bannerHeight,
        //    opacity : 0
        // }, this._aniSpeed); // 애니메이션 스피드 지정
        //
        // 다음 배너 나타나게 하기
        // $inBanner.stop().animate({
        //    top : 0,
        //    opacity : 1
        // }, this._aniSpeed); // 애니메이션 스피드 지정

        if(this._effect) {
            // 롤링 효과로 넘길 데이터 만들기
            var info = {
                '$inBanner' : $inBanner,
                '$outBanner' : $outBanner,
                bannerWidth : this._bannerWidth,
                bannerHeight : this._bannerHeight,
                speed : this._aniSpeed
            };

            // 롤링 효과 호출
            this._effect.effect(info);

        } else {
            return console.log('롤링 효과가 없습니다.');

        }
    }
};
/**
 * ---------------------------------------------------------------------
 * 롤링 효과 선언부분 만들기
 * 자바스크립트는 다형성의 선언부분을 정의하는 문법인
 * 인터페이스나 추상클래스를 제공해주지 않기 때문에 만들었다는 가정하에 진행한다.
 * ---------------------------------------------------------------------
 **/
// 여기서는 공통적으로 상,하,좌,우 롤링 효과 기능을 담을 선언부분을 effect 선언한다.
// 있다는 가정하에 진행하기 때문에 실제 코드는 주석처리했음
// function effect(info){ }


/**
 * ----------------------------------
 * 선언부분 후에 구현 부분을 작성한다.
 * 롤링 효과 구현 부분
 * ----------------------------------
 **/
// 구현해야 할 롤링 효과는 상,하,좌,우 롤링으로 총 4개이며 객체 리터럴 방식으로 구현

// 아래에서 위로 롤링되는 효과
var BTRollingEffect = {
    effect : function (info) {
        // 다음 배너 위치 초기화
        info.$inBanner.css({
            top: info.bannerHeight,
            opacity: 0
        });

        // 현재 배너 사라지게 하기
        info.$outBanner.stop().animate({
            top: -info.bannerHeight,
            opacity:0
        }, info.speed);

        // 다음 배너 나타나게 하기
        info.$inBanner.stop().animate({
            top: 0,
            opacity: 1
        }, info.speed);
    }
};

// 위에서 아래로 롤링되는 효과
var TBRollingEffect = {
    effect : function (info) {
        // 다음 배너 위치 초기화
        info.$inBanner.css({
            top: -info.bannerHeight,
            opacity: 0
        });

        // 현재 배너 사라지게 하기
        info.$outBanner.stop().animate({
            top: info.bannerHeight,
            opacity: 0
        }, info.speed);

        // 다음 배너 나타나게 하기
        info.$inBanner.stop().animate({
            top: 0,
            opacity: 1
        }, info.speed);
    }
};

// 왼쪽에서 오른쪽으로 롤링되는 효과
var LRRollingEffect = {
    effect : function (info) {
        // 다음 배너 위치 초기화
        info.$inBanner.css({
            left: -info.bannerWidth,
            top : 0,
            opacity: 0
        });

        // 현재 배너 사라지게 하기
        info.$outBanner.stop().animate({
            left: info.bannerWidth,
            opacity: 0
        }, info.speed);

        // 다음 배너 나타나게 하기
        info.$inBanner.stop().animate({
            left: 0,
            top: 0,
            opacity: 1
        }, info.speed);
    }
};

// 오른쪽에서 왼쪽으로 롤링되는 효과
var RLRollingEffect = {
    effect : function (info) {
        // 다음 배너 위치 초기화
        info.$inBanner.css({
            left: info.bannerWidth,
            top : 0,
            opacity: 0
        });

        // 현재 배너 사라지게 하기
        info.$outBanner.stop().animate({
            left: -info.bannerWidth,
            opacity: 0
        }, info.speed);

        // 다음 배너 나타나게 하기
        info.$inBanner.stop().animate({
            left: 0,
            top: 0,
            opacity: 1
        }, info.speed);
    }
};

롤링 효과는 이제 독립적으로 구현된 상태이기 때문에 nextBanner() 메서드에서 기존(단계#3) 롤링 효과 코드를 지워주고 그 자리에 롤링 효과를 합성하여 사용했습니다.



Result View

See the Pen 심플롤링배너(다형성,합성) #4 by jaeheekim (@jaehee) on CodePen.





Jaehee's WebClub