/** * @name jQuery.touchFlow * @author dohoons ( http://dohoons.com/ ) * * @version 1.5.0 * @since 201602 * * @param Object settings 환경변수 오브젝트 * axis - 드래그 방향 (String, default "x") * page - 초기 페이지 (Number or String, default 0) * speed - 애니메이션 속도 (Number, default 200) * snap - 스냅 기능 (Boolean, default false) * scrollbar - 스크롤바 표시 (Boolean, default false) * scrollbarAutoHide - 스크롤바 자동 숨김 (Boolean, default true) * initComplete - 초기화 콜백 (Function, default null) * stopped - 정지 콜백 (Function, default null) * resizeend - 윈도우 리사이즈 콜백 (Function, default null) * * @example $("#target").touchFlow({ page : 2 }); $("#target").data("touchFlow").go_page(4); */ /* global jQuery */ ;(function ($) { "use strict"; var supportsCssTransitions = 'transition' in document.documentElement.style || 'WebkitTransition' in document.documentElement.style; var TouchFlow = function (el, settings){ var defaults = { axis : "x", page : 0, speed : 200, side: 0.15, snap : false, scrollbar : false, scrollbarAutoHide : true, initComplete : null, stopped : null, resizeend : null }; this.opts = $.extend({}, defaults, settings); this.target = el; this.wrap = $(el); this.list = this.wrap.children(); this.wrapw = null; this.wraph = null; this.listw = null; this.listh = null; this.tmp = null; this.ticker = null; this.duration = this.opts.speed; this.side = this.opts.side; this.delay = 17; this.posx = 0; this.posy = 0; this.startx = 0; this.starty = 0; this.speedx = 0; this.speedy = 0; this.prevx = 0; this.prevy = 0; this.tempx = 0; this.tempy = 0; this.right = 0; this.bottom = 0; this.state = false; this.link = true; this.lastmove = null; this.scroll = {}; this.init(); }; TouchFlow.prototype = { init: function () { this.list = this.wrap.children(); this.state = false; if(typeof(this.opts.page) === "string") { this.opts.page = $(this.target).find(this.opts.page).eq(0).index(); } this.set_limit(); this.go_page(this.opts.page); this.list .off("touchstart", this, this.touchstart) .off("touchmove", this, this.touchmove) .off("touchend touchcancel", this.touchend) .off("dragstart", this, this.touchstart) .off("drag", this, this.touchmove) .off("dragend", this, this.touchend) .off("transitionend", this, this.transitionend) .off("wheel", this, this.wheel) .on("touchstart", this, this.touchstart) .on("touchmove", this, this.touchmove) .on("touchend touchcancel", this, this.touchend) .on("dragstart", this, this.touchstart) .on("drag", this, this.touchmove) .on("dragend", this, this.touchend) .on("transitionend", this, this.transitionend) .on('wheel', this, this.wheel); $(window).off("resize", this, this.resize).on("resize", this, this.resize); this.list.find("a").on("click", this, function (e) { if(!e.data.link) { return false; } }); if(this.opts.scrollbar) { this.scrollbar_init(); } if(typeof(this.opts.initComplete) === "function") { this.opts.initComplete.call(this, this.get_event_data()); } return this; }, scrollbar_init : function () { if(this.scroll.wrap === undefined) { this.scroll.wrap = $('
'); this.scroll.bar = this.scroll.wrap.find(" > div"); this.wrap.append(this.scroll.wrap); this.scrollbar_pos(); } }, scrollbar_pos : function (f) { if(this.opts.scrollbar) { var wrap = this.scroll.wrap, bar = this.scroll.bar, full, pos, transition = (f) ? "300ms" : "0ms"; if(this.opts.axis === "x") { full = this.wrapw / this.listw * 100; pos = -this.posX() / this.listw * 100; wrap.css({ width : "100%", height : "5px", opacity : 1 }); bar.css({ width : full + "%", height : "5px", left : pos + "%", transition : transition }); } else if(this.opts.axis === "y") { full = this.wraph / this.listh * 100; pos = -this.posY() / this.listh * 100; wrap.css({ width : "5px", height : "100%", opacity : 1 }); bar.css({ width : "5px", height : full + "%", top : pos + "%", transition : transition }); } if(this.opts.scrollbarAutoHide) { setTimeout(function () { if(f) { wrap.css({ opacity : 0 }); } }, 300); } } }, touchstart : function (e) { var obj = e.data; obj.startx = e.originalEvent.touches ? e.originalEvent.touches[0].pageX : e.pageX; obj.starty = e.originalEvent.touches ? e.originalEvent.touches[0].pageY : e.pageY; obj.posx = obj.startx - $(this).position().left; obj.posy = obj.starty - $(this).position().top; if(typeof(obj.opts.stopped) === "function" && obj.speedx !== 0) { obj.opts.stopped.call(obj, obj.get_event_data()); } obj.speedx = 0; obj.speedy = 0; obj.prevx = 0; obj.prevy = 0; obj.tempx = 0; obj.tempy = 0; obj.stop_animation(); obj.start_animation(); obj.state = true; obj.lastmove = e; e.stopPropagation(); }, touchmove : function (e) { var obj = e.data, pageX = e.originalEvent.touches ? e.originalEvent.touches[0].pageX : e.pageX, pageY = e.originalEvent.touches ? e.originalEvent.touches[0].pageY : e.pageY, left = pageX - obj.startx, top = pageY - obj.starty, w = left < 0 ? left * -1 : left, h = top < 0 ? top * -1 : top, thisx = pageX - obj.posx, thisy = pageY - obj.posy, limitx = obj.get_limit({x:thisx}), limity = obj.get_limit({y:thisy}), gapx = thisx - limitx, gapy = thisy - limity; if(obj.opts.axis == "x" && w > h) { obj.link = false; e.preventDefault(); if(Math.abs(gapx) > 0) { thisx -= gapx / 2; } obj.set_pos({x:thisx}); } else if(obj.opts.axis == "y" && w < h) { obj.link = false; e.preventDefault(); if(Math.abs(gapy) > 0) { thisy -= gapy / 2; } obj.set_pos({y:thisy}); } obj.lastmove = e; e.stopPropagation(); }, touchend : function (e) { var obj = e.data, pageX = obj.lastmove.originalEvent.touches ? obj.lastmove.originalEvent.touches[0].pageX : obj.lastmove.pageX, pageY = obj.lastmove.originalEvent.touches ? obj.lastmove.originalEvent.touches[0].pageY : obj.lastmove.pageY, left = pageX - obj.startx, top = pageY - obj.starty, thisx = $(this).position().left, thisy = $(this).position().top, to = 0; obj.state = false; obj.speedx = obj.tempx; obj.speedy = obj.tempy; if(obj.opts.axis == "x" && !obj.limit_chk({x:thisx})) { if(left < 0) { to = obj.right; } else { to = 0; } obj.stop_animation(); obj.set_pos({x:to}, obj.duration); } else if(obj.opts.axis == "y" && !obj.limit_chk({y:thisy})) { if(top < 0) { to = obj.bottom; } else { to = 0; } obj.stop_animation(); obj.set_pos({y:to}, obj.duration); } setTimeout(function () { obj.link = true; },50); e.stopPropagation(); }, transitionend : function (e) { var obj = e.data; if(typeof(obj.opts.stopped) === "function") { obj.opts.stopped.call(obj, obj.get_event_data()); } obj.scrollbar_pos(true); }, resize : function (e) { var obj = e.data; clearTimeout(obj.tmp); obj.tmp = setTimeout(function () { obj.set_limit(); obj.pos_control(); if(typeof(obj.opts.resizeend) === "function") { obj.opts.resizeend.call(obj, obj.get_event_data()); } obj.scrollbar_pos(true); }, 200); }, wheel : function (e) { var obj = e.data, pos = 0, chk = {}, gap = 100; if(e.originalEvent.deltaY > 0) { if(obj.opts.axis === "x") { pos = obj.posX(); chk = {x:pos - 1}; obj.posX( pos - gap ); } else { pos = obj.posY(); chk = {y:pos - 1}; obj.posY( pos - gap ); } } else if(e.originalEvent.deltaY < 0) { if(obj.opts.axis === "x") { pos = obj.posX(); chk = {x:pos + 1}; obj.posX( pos + gap ); } else { pos = obj.posY(); chk = {y:pos + 1}; obj.posY( pos + gap ); } } else { return true; } if(obj.limit_chk(chk) === true) { e.preventDefault(); } obj.scrollbar_pos(true); }, get_nearby_page : function (n) { var pos = (typeof n === "number") ? Math.abs(n) : null, arr = [], list_pos = this.list.offset(), li = this.list.children(), len = li.length, tg = ""; if(this.opts.axis === "x") { tg = "left"; if(pos === null) { pos = Math.abs(list_pos.left); } } else { tg = "top"; if(pos === null) { pos = Math.abs(list_pos.top); } } for(var i=0; i