/**
* jQuery.flickSimple v1.2.2
*
* Copyright (c) 2011 Makog. http://d.hatena.ne.jp/makog/
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
*/
(function($){
$.flickSimple = function( obj, param ) {
this.setup( $(obj), param );
};
$.extend( $.flickSimple.prototype, {
elm: null,
target: null,
disabled: false,
snap: 'element',
ratio: 5,
duration: 600,
lock: false,
onChange: null,
onResize: null,
onAnimationEnd: null,
onClick: null,
vertical: false,
horizontal: true,
paginate: 'x',
elmWidth: 0,
elmHeight: 0,
page: 1,
pageWidth: 0,
pageHeight: 0,
pageLength: 0,
android: false,
touchable: ( typeof ontouchstart !== 'undefined' ),
vender: (function() {
var props = [
[ '-webkit-transition', '-webkit-transition', '-webkit-transform', 'webkitTransitionEnd' ],
[ 'MozTransition', '-moz-transition', '-moz-transform', 'transitionend' ],
[ 'OTransition', '-o-transition', '-o-transform', 'oTransitionEnd' ],
[ '-ms-transition', '-ms-transition', '-ms-transform', 'msTransitionEnd' ],
[ 'transition', 'transition', 'transform', 'transitionEnd' ]
];
var div = document.createElement('div');
var vender = {};
for( var i=0,len=props.length; i this.pageLength ) {
pagenum = this.pageLength;
}
pagenum--;
var pageX, pageY, rownum;
if ( this.paginate === 'y' ) {
rownum = Math.ceil( this.elmHeight / this.pageHeight ) +1;
pageX = Math.floor( pagenum / rownum );
pageY = pagenum % rownum;
} else {
rownum = Math.ceil( this.elmWidth / this.pageWidth ) +1;
pageY = Math.floor( pagenum / rownum );
pageX = pagenum % rownum;
}
var posX = pageX * this.pageWidth;
var posY = pageY * this.pageHeight;
return this.move( -posX, -posY );
},
// 指定されたX座標に移動
move: function( posX, posY ) {
var o = this;
if ( ! o.horizontal || posX >= 0 ) {
posX = 0;
} else if ( posX < -o.elmWidth ) {
posX = -o.elmWidth;
}
if ( ! o.vertical || posY >= 0 ) {
posY = 0;
} else if ( posY < -o.elmHeight ) {
posY = -o.elmHeight;
}
if ( ! o.useCSSAnim ) {
o.target.animate( { left: posX + 'px', top: posY + 'px' },
function (e) {
if ( o.onAnimationEnd ) {
o.onAnimationEnd(e);
}
} );
} else {
var css = {};
css[o.vender.transition] = o.vender.transform + ' 0.3s ease-in';
css[o.vender.transform] = o.use3d
? 'translate3d(' + posX + 'px,' + posY + 'px,0)'
: 'translate(' + posX + 'px,' + posY + 'px)';
o.target.css(css);
}
o.nextX = posX;
o.nextY = posY;
return o.update( posX, posY );
},
// 表示が変更されたら、各エレメントの大きさを計算し直す
updateSize: function() {
var o = this;
var ori = typeof( window.orientation ) !== 'undefined'
? ( window.orientation === 0 ? 'portrait' : 'landscape' )
: ( window.innerWidth < window.innerHeight ? 'portrait' : 'landscape' );
// var lis = o.target.find('li');
var lis = o.target.children();
o.elm.removeClass('landscape portrait').addClass( ori );
// うまく反映されない場合があるので、エレメント自体にclassを振る
o.target.removeClass('landscape portrait').addClass( ori );
lis.removeClass('landscape portrait').addClass( ori );
var targw = o.target.width();
var targh = o.target.height();
var elmw = o.elm.width();
var elmh = o.elm.height();
o.elmWidth = targw - elmw;
o.elmHeight = targh - elmh;
o.pageWidth = 0;
o.pageHeight = 0;
o.pageLength = 0;
if ( o.snap ) {
if ( o.snap === 'element' ) {
o.pageWidth = elmw;
o.pageHeight = elmh;
} else if ( o.snap === 'first' ) {
o.pageWidth = $(lis.get(0)).width();
o.pageHeight = $(lis.get(0)).height();
} else if ( o.snap === 'smallest' ) {
var smaller = 0;
lis.each( function() {
var w = $(this).width();
if ( smaller > w || smaller == 0 ) {
smaller = w;
}
} );
o.pageWidth = smaller;
smaller = 0;
lis.each( function() {
var h = $(this).height();
if ( smaller > h || smaller == 0 ) {
smaller = h;
}
} );
o.pageHeight = smaller;
} else if ( typeof o.snap === 'object' ) {
o.pageWidth = o.snap[0];
o.pageHeight = o.snap[1];
} else if ( ! isNaN(o.snap) ) {
o.pageWidth = o.snap;
o.pageHeight = o.snap;
}
o.pageLength = Math.ceil( targw / o.pageWidth );
if ( targh > o.pageHeight ) {
o.pageLength *= Math.ceil( targh / o.pageHeight );
}
}
if ( o.onResize ) {
o.onResize();
}
if ( o.snap ) {
o.goTo( o.page );
}
return o;
},
touchstart: function(e) {
var o = this;
var te = o.touchable ? e.originalEvent.touches[0] : e;
if ( o.disabled ) { return; }
o.startX = o.preX = te.clientX;
o.startY = o.preY = te.clientY;
o.touchhold = false;
var anc = e.target.tagName === 'A'
? $(e.target)
: $(e.target).closest('a');
if ( anc.length > 0 ) {
o.anc = anc;
}
// 長押し対応
setTimeout( function() {
if ( o.anc ) {
// o.startX = null;
o.touchhold = true;
var anc = o.anc;
var link = $.data(anc.get(0), 'flickSimple.link' );
if ( link ) {
anc.attr('href', link);
setTimeout( function() {
anc && anc.attr('href', 'javascript:;');
}, 200 );
}
}
}, 600 );
},
touchmove: function(e) {
var o = this;
if ( o.disabled ) { return; }
if ( o.android || o.lock ) {
e.preventDefault();
}
if ( o.startX === null || o.startY === null ) {
o.anc = null;
return;
}
var te = o.touchable ? e.originalEvent.touches[0] : e;
var nowX = te.clientX;
var nowY = te.clientY;
if ( Math.abs( o.startX - nowX ) > 16 || Math.abs( o.startY - te.clientY ) > 16 ) {
o.anc = null;
}
o.nextX = o.horizontal ? (o.currentX || 0) + ( nowX - o.startX ) : 0;
o.nextY = o.vertical ? (o.currentY || 0) + ( nowY - o.startY ) : 0;
if ( ! o.useCSSAnim ) {
o.target.css( { left: o.nextX + 'px', top: o.nextY + 'px' } );
} else {
var css = {};
css[o.vender.transition] = 'none';
css[o.vender.transform] = o.use3d
? 'translate3d(' + o.nextX + 'px,' + o.nextY + 'px,0)'
: 'translate(' + o.nextX + 'px,' + o.nextY + 'px)';
o.target.css( css );
}
o.flickX = o.preX - nowX;
o.flickY = o.preY - nowY;
o.preX = nowX;
o.preY = nowY;
},
touchend: function(e) {
var o = this;
if ( o.disabled || o.startX === null || o.startY === null ) { return; }
o.startX = null;
o.startY = null;
if ( o.anc && ! o.touchhold ) {
if ( o.onClick ) {
o.onClick( o.anc );
}
var ancr = o.anc.get(0);
var link = $.data(ancr, 'flickSimple.link' );
var targ = $.data(ancr, 'flickSimple.target' );
if ( link ) {
if ( targ && targ !== '_self' ) {
if ( targ === '_blank' ) {
targ = '';
}
window.open( link, targ );
} else {
location.href = link;
}
}
e.preventDefault();
}
o.touchhold = false;
var nposX = o.nextX + (o.flickX * -o.ratio);
var nposY = o.nextY + (o.flickY * -o.ratio);
if ( o.pageWidth ) {
var thrX = nposX % o.pageWidth;
if ( thrX < -o.pageWidth / 2 ) {
nposX -= thrX + o.pageWidth;
} else {
nposX -= thrX;
}
var thrY = nposY % o.pageHeight;
if ( thrY < -o.pageHeight / 2 ) {
nposY -= thrY + o.pageHeight;
} else {
nposY -= thrY;
}
}
if ( ! o.horizontal || nposX >= 0 ) {
nposX = 0;
} else if ( nposX < -o.elmWidth ) {
nposX = -o.elmWidth;
}
if ( ! o.vertical || nposY >= 0 ) {
nposY = 0;
} else if ( nposY < -o.elmHeight ) {
nposY = -o.elmHeight;
}
if ( ! o.useCSSAnim ) {
o.target.animate( { left: nposX + 'px', top: nposY + 'px' }, o.duration,
function (x, t, b, c, d) {
if ( o.onAnimationEnd ) {
o.onAnimationEnd(e);
}
return -c *(t/=d)*(t-2) + b;
} );
} else {
var css = {};
css[o.vender.transition] = o.vender.transform
+ ' ' + (o.duration / 1000) + "s ease-out";
css[o.vender.transform] = o.use3d
? 'translate3d(' + nposX + 'px,' + nposY + 'px,0)'
: 'translate(' + nposX + 'px,' + nposY + 'px)';
o.target.css( css );
}
o.update( nposX, nposY );
},
update: function( posX, posY ) {
var o = this;
if ( o.pageWidth || o.pageHeight ) {
var rownum;
if ( o.paginate === 'y' ) {
rownum = Math.ceil( this.elmHeight / this.pageHeight ) +1;
o.page = Math.ceil( -posY / o.pageHeight )
+ ( Math.ceil( -posX / o.pageWidth ) * rownum) +1;
} else {
rownum = Math.ceil( this.elmWidth / this.pageWidth ) +1;
o.page = Math.ceil( -posX / o.pageWidth )
+ (Math.ceil( -posY / o.pageHeight ) * rownum) +1;
}
}
if ( o.currentX !== posX || o.currentY !== posY ) {
o.currentX = posX;
o.currentY = posY;
if ( o.onChange ) {
o.onChange();
}
}
return o;
},
no_mousedown: function(e) {
e.preventDefault();
},
// 初期化(内容に変更があった場合には、呼び出すこと)
init: function() {
var o = this;
o.target.find('a').each( function() {
var obj = $(this);
var link = obj.attr('href');
var targ = obj.attr('target');
if ( link && link !== 'javascript:;' ) {
$.data(this, 'flickSimple.link', link );
}
$.data(this, 'flickSimple.target', targ || '' );
obj.attr('href', 'javascript:;').removeAttr('target');
if ( ! o.touchable ) {
obj.unbind( 'mousedown', o.no_mousedown )
.bind( 'mousedown', o.no_mousedown );
}
} );
// 画像のドラッグをさせない
if ( ! o.touchable ) {
o.target.find('img')
.unbind( 'mousedown', o.no_mousedown )
.bind( 'mousedown', o.no_mousedown );
}
return o;
}
} );
$.fn.flickSimple = function( param ) {
var res = this;
if ( typeof param === "string" ) { // 引数が文字列の場合
var args = Array.prototype.slice.call(arguments, 1);
this.each( function() {
var instance = $.data(this, 'flickSimple');
var val;
if ( instance ) {
if ( $.isFunction(instance[param]) ) {
val = instance[param].apply(instance, args);
} else {
if ( args.length > 0 ) {
instance[param] = args[1];
}
val = instance[param];
}
}
if ( val !== instance ) {
res = val
}
});
} else {
this.each( function() {
var instance = $.data(this, 'flickSimple');
if (! instance) {
$.data(this, 'flickSimple', new $.flickSimple( this, param || {} ) );
} else {
res = instance;
}
} );
}
return res;
};
})(jQuery);