/** * 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 = [ // 二维 $(''), // 一维x方向切片 $(''), // 一维y方向切片 $(''), // 单整张 $(''), // 2整张x方向 $(''), // 2整张y方向 $('') ]; 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 = '
      ' + 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);