/**
* vmc.slide 图片轮播jquery插件 v2.0.0
* 维米客网页工作室 vomoc.com
* https://github.com/vomoc/vmc.slide
* vomoc@qq.com
* 2017/03/20
**/
;(function ($, undefined) {
var datakey = 'vomoc';
var ie6 = !-[1,] && !window.xmlhttprequest;
var ie9plus = navigator.appname !== 'microsoft internet explorer' || parseint(navigator.appversion.split(';')[1].replace(/[ ]/g, '').replace('msie', '')) >= 9;
var effects = {
// 默认转场效果,淡入淡出,兼容低版本ie
'fade': function (index) {
var the = this,
opts = the.options;
the.transfer[3].fadein(opts.speed, function () {
the._resettransfer(index);
});
}
};
/**
* 轮播图插件
* @param settings
* @returns {*}
*/
$.fn.vmcslide = function (settings) {
var run = $.type(settings) === 'string',
args = [].slice.call(arguments, 1);
if (!this.length) return;
return this.each(function () {
var $element = $(this),
instance = $element.data(datakey);
if (run && settings.charat(0) !== '_' && instance) {
vmcslide.prototype[settings] && vmcslide.prototype[settings].apply(instance, args);
} else if (!run && !instance) {
instance = new vmcslide($element, settings);
instance._init();
$element.data(datakey, instance);
}
});
};
/**
* 注册转场效果
*/
$.vmcslideeffects = function () {
if ($.isplainobject(arguments[0])) {
effects = $.extend({}, effects, arguments[0]);
} else if ($.type(arguments[0]) === 'string' && $.type(arguments[1]) === 'function') {
effects[arguments[0]] = arguments[1];
}
};
/**
* 构造函数
* @param $element dom元素
* @param settings 选项
*/
var vmcslide = function ($element, settings) {
var the = this;
// 合并后的参数
the.options = $.extend({}, the.options, settings);
// 整个元素
the.elem = $element;
// 要被替换掉的原元素
the.original = $element.children();
// 模拟的新元素,将替换掉原元素
the.mimic = null;
// 过场舞台
the.transfer = [];
// 从原元素和data参数合并的原数据,场景数据
the.data = [];
// 当前显示的数据索引
the.index = 0;
// 当前使用的效果索引
the.effectindex = 0;
// 动画播放状态
the.animatestatus = false;
// 轮播图宽度
the.width = 0;
// 轮播图高度
the.height = 0;
// 图片宽度
the.imgwidth = 0;
// 图片高度
the.imgheight = 0;
// 是否自动播放
the.auto = the.options.autoplay;
// 计时器
the.timer = null;
};
// 默认选项
vmcslide.prototype.options = {
// 场景数据
data: [],
// 宽度 (像素)
width: 'auto',
// 高度 (像素)
height: 'auto',
// 图片宽度 为0时同width
imgwidth: 0,
// 图片高度 为0时同height
imgheight: 0,
// 最小宽度
minwidth: 0,
// 最小高度
minheight: 0,
// 二维网格x轴切割份数(列数)
gridtdx: 10,
// 二维网格y轴切割份数(行数)
gridtdy: 5,
// 一维栅格x轴切割份数(列数)
gridodx: 30,
// 一维栅格y轴切割份数(行数)
gridody: 10,
// 是否显示侧边按钮
sidebutton: true,
// 是否显示导航按钮
navbutton: true,
// 是否显示文本
showtext: 'auto',
// 文本信息是否是html
ishtml: false,
// 自动播放
autoplay: true,
// 图片按照升序播放
ascending: true,
// 转场动画效果
effects: ['fade'],
// ie6下精简效果
ie6tidy: false,
// 随机使用转场动画效果
random: true,
// 图片停留时长(毫秒)
duration: 4000,
// 转场效果时长(毫秒)
speed: 800,
// 鼠标悬停则停止播放
hoverstop: true,
// 翻页回调
flip: function (fromindex, toindex) {
},
// 创建完成回调
created: function () {
}
};
/**
* 设置选项
* @param name
* @param value
*/
vmcslide.prototype.option = function (name, value) {
var the = this,
opts = the.options;
opts[name] = value;
if ($.inarray(name, ['data', 'gridtdx', 'gridtdy', 'gridodx', 'gridody', 'sidebutton', 'navbutton']) > 0) {
the._buildstage();
}
if ($.inarray(name, ['data', 'gridtdx', 'gridtdy', 'gridodx', 'gridody', 'sidebutton', 'navbutton', 'width', 'height', 'imgwidth', 'imgheight', 'minwidth', 'minheight',]) > 0) {
the._setsize();
}
switch (name) {
case 'autoplay':
the.auto = value;
break;
}
};
/**
* 初始化
* @private
*/
vmcslide.prototype._init = function () {
var the = this,
opts = the.options;
// 初始化数据
the._setscenedata();
// 创建舞台
the._buildstage();
// 初始化尺寸
the._setsize();
// 初始化场景
the._resettransfer(the.index);
// 创建完成回调
opts.created.call(the);
// 事件
the.mimic
.on('click', '.vui-slide-handle-button', function () {
// 圆点按钮
the._goto($(this).index());
})
.on('click', '.vui-slide-side-button', function () {
// 侧边按钮
if ($(this).hasclass('next')) {
the._next();
} else {
the._prev();
}
})
.on('mouseenter', function () {
// 鼠标进入停止自动播放
the.mimic.find('.vui-slide-side-buttons').children().addclass('hover');
if (opts.hoverstop) {
cleartimeout(the.timer);
the.auto = false;
}
})
.on('mouseleave', function () {
the.mimic.find('.vui-slide-side-buttons').children().removeclass('hover');
if (opts.hoverstop) {
the.auto = the.options.autoplay;
if (!the.animatestatus) {
the._resettransfer(the.index);
}
}
});
// 浏览器事件
$(window).on('resize', function () {
the._setsize();
});
};
/**
* 设置场景数据
* @private
*/
vmcslide.prototype._setscenedata = function () {
var the = this,
opts = the.options;
var scenedata = the.original.children().map(function () {
var $this = $(this);
return {
src: $this.data('src') || $this.find('img').attr('src'),
text: $this.data('text'),
href: $this.data('href') || $this.find('a').attr('href'),
target: $this.data('target') || $this.find('a').attr('target')
};
}).toarray();
the.data = scenedata.concat(opts.data);
};
/**
* 设置场景
* @param index 场景索引
* @private
*/
vmcslide.prototype._setscene = function (index) {
var the = this;
var $scene = the.mimic.children('.vui-slide-scene');
$scene.attr('href', the.data[index].href || 'javascript:void(0);').css({
backgroundimage: 'url(' + the.data[index].src + ')'
});
if (the.data[index].target) {
$scene.attr('target', the.data[index].target);
}
if (!ie9plus) {
$scene.children('img').attr('src', the.data[index].src);
}
};
/**
* 设置转场切片图片
* @param index
* @private
*/
vmcslide.prototype._settransfergrid = function (index) {
var the = this;
the.mimic.find('.vui-slide-grid').css({
backgroundimage: 'url(' + the.data[index].src + ')'
});
if (index > the.index) {
the.transfer[4].children('.vui-slide-grid').first().css({
backgroundimage: 'url(' + the.data[the.index].src + ')'
});
the.transfer[5].children('.vui-slide-grid').first().css({
backgroundimage: 'url(' + the.data[the.index].src + ')'
});
} else {
the.transfer[4].children('.vui-slide-grid').last().css({
backgroundimage: 'url(' + the.data[the.index].src + ')'
});
the.transfer[5].children('.vui-slide-grid').last().css({
backgroundimage: 'url(' + the.data[the.index].src + ')'
});
}
if (!ie9plus) {
the.transfer[3].children().find('img').attr('src', the.data[index].src);
the.transfer[4].children().find('img').attr('src', the.data[index].src);
the.transfer[5].children().find('img').attr('src', the.data[index].src);
}
};
/**
* 设置当前导航按钮
* @param index
* @private
*/
vmcslide.prototype._sethandlebuttonactive = function (index) {
var the = this;
the.mimic
.find('.vui-slide-handle-button')
.removeclass('active')
.eq(index)
.addclass('active');
};
/**
* 设置文本
* @param index
* @private
*/
vmcslide.prototype._settext = function (index) {
var the = this,
opts = the.options;
var text = the.data[index].text || '';
var isshow = $.type(opts.showtext) === 'boolean' ? opts.showtext : !!text;
var $text = the.mimic.children('.vui-slide-text');
if (opts.ishtml) {
$text.html(text);
} else {
$text.html($('
').addclass('text').text(text));
}
the.mimic
.children('.vui-slide-mask,.vui-slide-text')
.toggle(isshow);
};
/**
* 创建舞台
* @private
*/
vmcslide.prototype._buildstage = function () {
var the = this;
the._buildmimic();
the._buildscene();
the._buildtransfer();
the._buildhandlebutton();
the._buildsidebutton();
the._buildtext();
the.elem.empty().append(the.mimic);
};
/**
* 创建模拟元素
* @private
*/
vmcslide.prototype._buildmimic = function () {
var the = this;
the.mimic = $('
').addclass('vui-slide-mimic');
};
/**
* 创建场景
* @private
*/
vmcslide.prototype._buildscene = function () {
var the = this;
var $scene = $('
').addclass('vui-slide-scene');
if (!ie9plus) {
$scene.append('');
}
the.mimic.append($scene);
};
/**
* 创建转场舞台
* @private
*/
vmcslide.prototype._buildtransfer = function () {
var the = this,
opts = the.options;
the.transfer = [
// 二维
$('' + the._buildtransfergrid(opts.gridtdx * opts.gridtdy) + '
'),
// 一维x方向切片
$('' + the._buildtransfergrid(opts.gridodx) + '
'),
// 一维y方向切片
$('' + the._buildtransfergrid(opts.gridody) + '
'),
// 单整张
$('' + the._buildtransfergrid(1) + '
'),
// 2整张x方向
$('' + the._buildtransfergrid(2) + '
'),
// 2整张y方向
$('' + the._buildtransfergrid(2) + '
')
];
if (!ie9plus) {
the.transfer[3].children().append('');
the.transfer[4].children().append('');
the.transfer[5].children().append('');
}
the.mimic.append(the.transfer);
};
/**
* 创建过场网格
* @param count
* @returns {string}
* @private
*/
vmcslide.prototype._buildtransfergrid = function (count) {
var html = '';
for (var i = 0; i < count; i++) {
html += '';
}
return html;
};
/**
* 创建导航按钮
* @private
*/
vmcslide.prototype._buildhandlebutton = function () {
var the = this,
opts = the.options;
if (opts.navbutton) {
var html = '';
for (var i = 0; i < the.data.length; i++) {
html += '';
}
html = '';
the.mimic.append(html);
}
};
/**
* 创建侧边按钮
* @private
*/
vmcslide.prototype._buildsidebutton = function () {
var the = this,
opts = the.options;
if (opts.sidebutton) {
var html = '';
the.mimic.append(html);
}
};
/**
* 创建文本
* @private
*/
vmcslide.prototype._buildtext = function () {
var the = this;
var $textmask = $('');
var $text = $('');
the.mimic
.append($textmask)
.append($text);
};
/**
* 设置舞台尺寸
* @private
*/
vmcslide.prototype._setsize = function () {
var the = this,
$elem = the.elem,
opts = the.options;
// 定义显示范围长宽
the.width = opts.width === 'auto' ? $elem.width() : opts.width;
the.height = opts.height === 'auto' ? $elem.height() : opts.height;
// 保持长宽最小值
the.width = the.width < opts.minwidth ? opts.minwidth : the.width;
the.height = the.height < opts.minheight ? opts.minheight : the.height;
// 定义默认图片长宽
the.imgwidth = opts.imgwidth <= 0 ? the.width : opts.imgwidth;
the.imgheight = opts.imgheight <= 0 ? the.height : opts.imgheight;
// 定义图片显示尺寸和图片位置
var imgheight, imgwidth, imgtop, imgleft;
if (the.imgwidth / the.imgheight > the.width / the.height) {
// 图片高是短边
imgheight = the.height;
imgwidth = math.round(imgheight * the.imgwidth / the.imgheight);
imgleft = math.round((imgwidth - the.width) / 2);
imgtop = 0;
} else {
// 图片宽度是短边
imgwidth = the.width;
imgheight = math.round(imgwidth * the.imgheight / the.imgwidth);
imgtop = math.round((imgheight - the.height) / 2);
imgleft = 0;
}
// 如果长宽不是自动获取,则设置最外层元素尺寸
opts.width === 'auto' || $elem.width(the.width);
opts.height === 'auto' || $elem.height(the.height);
// 设置模拟元素尺寸
the.mimic.height(the.height).width(the.width);
// 设置舞台背景图尺寸和位置
the.mimic.children('.vui-slide-scene').height(the.height).width(the.width).css({
backgroundsize: imgwidth + 'px ' + imgheight + 'px',
backgroundposition: '-' + imgleft + 'px -' + imgtop + 'px'
});
// 设置二维转场切片位置尺寸
var xyheight = math.round(the.height / opts.gridtdy);
var xywidth = math.round(the.width / opts.gridtdx);
var lastxyheight = the.height - xyheight * (opts.gridtdy - 1);
var lastxywidth = the.width - xywidth * (opts.gridtdx - 1);
the.transfer[0].children('.vui-slide-grid').each(function (index) {
var width = (index + 1) % opts.gridtdx === 0 ? lastxywidth : xywidth;
var height = index >= (opts.gridtdy - 1) * opts.gridtdx ? lastxyheight : xyheight;
var top = xyheight * math.floor(index / opts.gridtdx);
var left = xywidth * (index % opts.gridtdx);
$(this)
.height(height)
.width(width)
.data({
width: width,
height: height,
left: left,
top: top,
imgleft: imgleft + left,
imgtop: imgtop + top
})
.css({
top: top,
left: left,
backgroundsize: imgwidth + 'px ' + imgheight + 'px',
backgroundposition: '-' + (imgleft + left) + 'px -' + (imgtop + top) + 'px'
});
});
// 设置一维转场x轴切片位置尺寸
var xwidth = math.round(the.width / opts.gridodx);
var lastxwidth = the.width - xwidth * (opts.gridodx - 1);
the.transfer[1].children('.vui-slide-grid').each(function (index) {
var width = index >= opts.gridodx - 1 ? lastxwidth : xwidth;
var height = the.height;
var top = 0;
var left = xwidth * index;
$(this)
.height(height)
.width(width)
.data({
width: width,
height: height,
left: left,
top: top,
imgleft: imgleft + left,
imgtop: imgtop + top
})
.css({
top: top,
left: left,
backgroundsize: imgwidth + 'px ' + imgheight + "px",
backgroundposition: '-' + (imgleft + left) + 'px -' + (imgtop + top) + 'px'
});
});
// 设置一维转场y轴切片位置尺寸
var yheight = math.round(the.height / opts.gridody);
var lastyheight = the.height - yheight * (opts.gridody - 1);
the.transfer[2].children('.vui-slide-grid').each(function (index) {
var width = the.width;
var height = index >= opts.gridody - 1 ? lastyheight : yheight;
var top = yheight * index;
var left = 0;
$(this)
.height(height)
.width(width)
.data({
width: width,
height: height,
left: left,
top: top,
imgleft: imgleft + left,
imgtop: imgtop + top
})
.css({
top: top,
left: left,
backgroundsize: imgwidth + 'px ' + imgheight + "px",
backgroundposition: '-' + (imgleft + left) + 'px -' + (imgtop + top) + 'px'
});
});
// 单张场景
the.transfer[3].children('.vui-slide-grid')
.height(the.height)
.width(the.width)
.data({
width: the.width,
height: the.height,
left: 0,
top: 0,
imgleft: imgleft,
imgtop: imgtop
})
.css({
top: 0,
left: 0,
backgroundsize: imgwidth + 'px ' + imgheight + "px",
backgroundposition: '-' + imgleft + 'px -' + imgtop + 'px'
});
// 横向两张场景
the.transfer[4]
.width(the.width * 2)
.children('.vui-slide-grid')
.each(function (index) {
var left = index * the.width;
$(this)
.height(the.height)
.width(the.width)
.data({
width: the.width,
height: the.height,
left: left,
top: 0,
imgleft: imgleft,
imgtop: imgtop
})
.css({
top: 0,
left: left,
backgroundsize: imgwidth + 'px ' + imgheight + "px",
backgroundposition: '-' + imgleft + 'px -' + imgtop + 'px'
});
});
the.transfer[5]
.height(the.height * 2)
.children('.vui-slide-grid')
.each(function (index) {
var top = index * the.height;
$(this)
.height(the.height)
.width(the.width)
.data({
width: the.width,
height: the.height,
left: 0,
top: top,
imgleft: imgleft,
imgtop: imgtop
})
.css({
top: top,
left: 0,
backgroundsize: imgwidth + 'px ' + imgheight + "px",
backgroundposition: '-' + imgleft + 'px -' + imgtop + 'px'
});
});
};
/**
* 下一张
* @private
*/
vmcslide.prototype._next = function () {
var the = this;
var index = the.index + 1;
index = index >= the.data.length ? 0 : index;
the._play(index);
};
/**
* 上一张
* @private
*/
vmcslide.prototype._prev = function () {
var the = this;
var index = the.index - 1;
index = index < 0 ? the.data.length - 1 : index;
the._play(index);
};
/**
* 跳转到指定张
* @param index 跳转目标图片索引
* @private
*/
vmcslide.prototype._goto = function (index) {
var the = this;
index = index > the.data.length - 1 ? the.data.length - 1 : index;
index = index < 0 ? 0 : index;
if (index - the.index === 0) {
return;
}
the._play(index);
};
/**
* 播放
* @param index 目标场景索引
* @private
*/
vmcslide.prototype._play = function (index) {
var the = this,
opts = the.options;
cleartimeout(the.timer);
if (!the.animatestatus && the.data.length > 1) {
the.animatestatus = true;
// 设置当前园标
the._sethandlebuttonactive(index);
// 设置说明文本
the._settext(index);
// 设置转场切片
the._settransfergrid(index);
// 翻页回调
opts.flip.call(the, the.index, index);
// 调用转场效果
effects[the._geteffect()].call(the, index);
}
};
/**
* 重置转场
* @param index 目标场景索引
* @private
*/
vmcslide.prototype._resettransfer = function (index) {
var the = this,
opts = the.options;
the._setscene(index);
the._sethandlebuttonactive(index);
the._settext(index);
the.mimic.find('.vui-slide-grid').clearqueue();
the.mimic.children('.vui-slide-transfer').hide();
the.index = index;
the.animatestatus = false;
if (the.auto) {
the.timer = settimeout(function () {
if (opts.ascending) {
the._next();
} else {
the._prev();
}
}, opts.duration);
}
};
/**
* 获取转场效果名称
* 如果浏览器是ie6,并开启ie6精简模式,则一定返回fade
* 如果浏览器是ie,版本低于9,并且图片尺寸与显示尺寸不一致时,返回fade
* @returns {string}
* @private
*/
vmcslide.prototype._geteffect = function () {
var the = this,
opts = the.options,
ie6tidy = ie6 && opts.ie6tidy,
ie9tidy = !ie9plus && (the.width - opts.imgwidth !== 0 || the.height - opts.imgheight !== 0);
if (ie6tidy || ie9tidy) {
return 'fade';
} else {
if (opts.random) {
the.effectindex = math.floor(opts.effects.length * math.random());
} else {
the.effectindex++;
}
if (the.effectindex >= opts.effects.length) {
the.effectindex = 0;
}
return opts.effects[the.effectindex];
}
};
})(jquery);