资讯专栏INFORMATION COLUMN

360°产品展示

MASAILA / 3604人阅读

摘要:是一款可以对产品图片进行度全方位旋转展示的插件。动画帧通过切换的速度,默认值为毫秒。动画帧改编之后的回调函数以当前帧和总帧数为参数。返回对象的总的动画帧数。显示对象的元素节点。

Circlr是一款可以对产品图片进行360度全方位旋转展示的插件。Circlr通过按一定角度规律拍摄的产品图片,制作出可以使用鼠标拖动、鼠标滚轮和移动触摸来进行图片逐帧旋转的效果。比先前的Rollerblade,动画顺畅了许多,也更易于控制,该插件非常适合于商品的展示。它的特点有:
1、支持水平或垂直方向旋转。
2、支持移动触摸事件。
3、支持滚动事件。
4、图片预加载处理。
5、可以反向和循环旋转图片。

页面引用核心jquery.js和circlr.js文件


对于circlr.js可以去自行下载
原文件展示给大家,以供预览:

// Circlr © 2014-2015 Andrey Polischuk
// github.com/andrepolischuk/circlr

!function() {

  "use strict";

  /**
   * Mutable parameters
   */

  var mutable = [
    "vertical",
    "reverse",
    "cycle",
    "speed",
    "playSpeed"
  ];

  /**
   * Initialize module
   * @param {Object} el
   * @param {Object} options
   */

  function Circlr(options) {

    /**
     * Mouse events enabled
     */

    options.mouse = options.mouse || true;

    /**
     * Scroll events enabled
     */

    options.scroll = options.scroll || false;

    /**
     * Orientation
     */

    options.vertical = options.vertical || false;

    /**
     * Turning reverse
     */

    options.reverse = options.reverse || false;

    /**
     * Turning cycle
     */

    options.cycle = options.cycle || true;

    /**
     * Start frame
     */

    options.start = options.start || 0;

    /**
     * Turn speed (ms)
     */

    options.speed = options.speed || 50;

    /**
     * Autoplay
     */

    var autoplay = options.autoplay || false;

    /**
     * Play speed (ms)
     */

    options.playSpeed = options.playSpeed || 100;

    /**
     * DOM element
     */

    var el = this.el = options.element;

    /**
     * Exclude duplication
     */

    el.setAttribute("data-circlr", true);

    /**
     * DOM loader
     */

    var loader = options.loader ? document.getElementById(options.loader) : undefined;

    /**
     * Frames length
     */

    var length = this.length = el.getElementsByTagName("img").length;

    /**
     * Frames area height
     */

    var height = options.height || undefined;

    /**
     * Frames area width
     */

    var width = options.width || undefined;

    /**
     * Move enable
     */

    var movable = false;

    /**
     * Loaded images length
     */

    var loaded = [];

    /**
     * Not loaded length
     */

    var errored = [];

    /**
     * Current frame
     */

    var current;

    /**
     * Prevous options
     */

    var pre   = {};

    pre.Y     = null;
    pre.X     = null;
    pre.frame = 0;

    /**
     * Callbacks
     */

    var callbacks = {};

    // all images loaded callback
    callbacks.ready = options.ready || undefined;

    // turn callback
    callbacks.change = options.change || undefined;

    /**
     * Scroll events
     */

    var scrollEvents = [
      "wheel",
      "mousewheel",
      "scroll",
      "DOMMouseScroll"
    ];

    /**
     * Add event listener
     * @param {Object} target
     * @param {String} event
     * @param {Function} fn
     * @api private
     */

    function onEventListener(target, event, fn) {

      if (target.addEventListener) {
        target.addEventListener(event, fn, false);
      } else {
        target.attachEvent("on" + event, function() {
          fn.call(target, window.event);
        });
      }

    }

    /**
     * Prevent default
     * @param {Object} e
     */

    function preventDefault(e) {

      if (e.preventDefault) {
        e.preventDefault();
      } else {
        e.returnValue = false;
      }

    }

    /**
     * Pre moving event
     * @param {Object} e
     * @api private
     */

    function preMove(e) {

      autoplay = false;

      preventDefault(e);
      e = e.type === "touchstart" ? e.changedTouches[0] : e;

      movable = true;

      if (options.vertical) {
        pre.Y = e.clientY - el.offsetTop;
      } else {
        pre.X = e.clientX - el.offsetLeft;
      }

    }

    /**
     * Normalize current frame
     * @param  {Number} cur
     * @return {Number}
     * @api private
     */

    function normalize(cur) {

      if (cur < 0) {
        cur = options.cycle ? cur + length : 0;
      } else if (cur > length - 1) {
        cur = options.cycle ? cur - length : length - 1;
      }

      return cur;

    }

    /**
     * Moving event
     * @param {Object} e
     * @api private
     */

    function isMove(e) {

      if (movable) {

        preventDefault(e);
        e = e.type === "touchmove" ? e.changedTouches[0] : e;

        // current offset (px)
        var offset = (options.vertical) ? ((e.clientY - el.offsetTop) - pre.Y) : ((e.clientX - el.offsetLeft) - pre.X);
        offset = options.reverse ? -offset : offset;

        // frame step (px)
        var step = width / length;

        // prevous frame
        var previous = current;

        // current offset (frame)
        offset = Math.floor(offset / step);

        if (offset !== current) {

          current = normalize(pre.frame + offset);

          if (previous !== current) {

            // show current frame
            el.getElementsByTagName("img")[previous].style.display = "none";
            el.getElementsByTagName("img")[current].style.display = "block";

            if (typeof callbacks.change === "function") {
              callbacks.change(current, length);
            }

          }

        }

      }

    }

    /**
     * Post moving event
     * @param {Object} e
     * @api private
     */

    function stopMove(e) {

      preventDefault(e);

      movable   = false;
      pre.frame = current;

    }

    /**
     * Moving via scroll
     * @param {Object} e
     * @api private
     */

    function scrollMove(e) {

      autoplay = false;

      preventDefault(e);

      // scroll delta
      var delta = e.deltaY || e.detail || (-e.wheelDelta);
      delta = delta / Math.abs(delta);
      delta = options.reverse ? -delta : delta;

      current = normalize(current + delta);

      // show current frame
      el.getElementsByTagName("img")[pre.frame].style.display = "none";
      el.getElementsByTagName("img")[current].style.display = "block";

      pre.frame = current;

      if (typeof callbacks.change === "function") {
        callbacks.change(current, length);
      }

    }

    /**
     * Initialize events after success images loading
     * @api private
     */

    function initEvents() {

      // loader hide
      if (loader) {
        loader.style.display = "none";
      }

      if (errored.length === 0) {

        var start = normalize(options.start);

        // all images loaded
        el.getElementsByTagName("img")[start].style.display = "block";
        current = start;

        el.style.position   = "relative";
        el.style.width      = "100%";

        if ("ontouchstart" in window || "onmsgesturechange" in window) {

            if (options.mouse || options.scroll) {
              onEventListener(el, "touchstart", preMove);
              onEventListener(el, "touchmove", isMove);
              onEventListener(el, "touchend", stopMove);
            }

        } else {

          if (options.mouse) {
            onEventListener(el, "mousedown", preMove);
            onEventListener(el, "mousemove", isMove);
            onEventListener(document, "mouseup", stopMove);
          }

          if (options.scroll) {
            for (var e = 0; e < scrollEvents.length; e++) {
              if ("on" + scrollEvents[e] in window) {
                onEventListener(el, scrollEvents[e], scrollMove);
                break;
              }
            }
          }

        }

        if (autoplay) {
          play();
        }

      }

      if (typeof callbacks.ready === "function") {
        callbacks.ready(errored);
      }

    }

    /**
     * Initialize images events
     * @param {Object} img
     */

    function loadImagesEvents(img) {

      img.onload = function() {

        loaded.push(this.src);

        // show first frame when all images loaded
        if (loaded.length + errored.length === length) {
          initEvents();
        }

      };

      img.onerror = function() {

        errored.push(this.src);

        // show first frame when images loaded
        if (loaded.length + errored.length === length) {
          initEvents();
        }

      };

      img.onreadystatechange = function() {
        this.onload();
      };

    }

    /**
     * Load Object images
     * @api private
     */

    function loadImages() {

      // adding elements
      var img;

      // show loader
      if (loader) {
        loader.style.display = "block";
      }

      for (var i = 0; i < length; i++) {

        // get object
        img = el.getElementsByTagName("img")[i];

        // set object style
        img.style.display      = "none";
        img.style.width        = "100%";

        // set object options
        img.setAttribute("src", img.getAttribute("data-src"));
        img.setAttribute("data-index", i);
        img.removeAttribute("data-src");

        loadImagesEvents(img);

      }

      // check elements sizes
      height = height || el.clientHeight;
      width  = width || el.clientWidth;

    }

    /**
     * Initialize loading
     */

    loadImages();

    /**
     * Change current frame
     * @param  {Number} i
     * @api private
     */

    function setFrame(i) {

      el.getElementsByTagName("img")[current].style.display = "none";
      el.getElementsByTagName("img")[i].style.display = "block";

      pre.frame = current = i;

    }

    /**
     * Turn to specific frame
     * @param  {Number} i
     * @api public
     */

    var turn = this.turn = function(i) {

      i = normalize(i);
      autoplay = true;

      (function turnInterval() {

        if (i !== current && autoplay) {

          setFrame(normalize(i < current ? current - 1 : current + 1));
          setTimeout(turnInterval, typeof i === "undefined" ? options.playSpeed : options.speed);

        } else if (i === current) {

          pre.frame = current = i;
          autoplay = false;

          if (typeof callbacks.change === "function") {
            callbacks.change(current, length);
          }

        }

      })();

    };

    /**
     * Go to specific frame
     * @param  {Number} i
     * @api public
     */

    this.go = function(i) {

      if (i !== current) {

        setFrame(i);

        if (typeof callbacks.change === "function") {
          callbacks.change(current, length);
        }

      }

    };

    /**
     * Play sequence
     * @api public
     */

    var play = this.play = function() {
      autoplay = true;
      turn();
    };

    /**
     * Stop sequence playng
     * @api public
     */

    this.stop = function() {
      autoplay = false;
    };

    /**
     * Show object
     * @api public
     */

    this.show = function() {
      el.style.display = "block";
    };

    /**
     * Hide object
     * @api public
     */

    this.hide = function() {
      el.style.display = "none";
    };

    /**
     * Change Object options
     * @param {Object} options
     * @api public
     */

    this.set = function(set) {
      for (var i = 0, key; i < mutable.length; i++) {
        key = mutable[i];
        options[key] = typeof set[key] !== "undefined" ? set[key] : options[key];
      }
    };

  }

  /**
   * Example creator
   */

  function Creator(element, options) {

    element = document.getElementById(element);

    if (element.getAttribute("data-circlr")) {
      return;
    }

    options = options || {};
    options.element = element;

    return new Circlr(options);

  }

  /**
   * Module exports
   */

  if (typeof define === "function" && define.amd) {

    define([], function() {
      return Creator;
    });

  } else if (typeof module !== "undefined" && module.exports) {

    module.exports = Creator;

  } else {

    this.circlr = Creator;

  }

}.call(this);

circle插件的运用很简单:
var crl = circlr(element, options);
// element:放置图片的容器元素的ID。
// options:参数对象。
配置参数
mouse:是否通过鼠标进行图片旋转,默认值为true。
scroll:是否通过scroll进行图片旋转,默认值为false。
vertical:是否在垂直方向上移动鼠标时旋转图片,默认值为false。
reverse:是否反转方向,默认值为false。
cycle:是否循环旋转图片,默认值为true。
start:开始动画帧,默认值为0。
speed:动画帧通过circlr.turn(i)切换的速度,默认值为50毫秒。
autoplay:是否自动进行图片360度旋转播放,默认值为false。
playSpeed:动画序列的播放速度,默认值为100毫秒。
loader:预加载DOM元素的ID。
ready:图片加载完成后的回调函数。
change:动画帧改编之后的回调函数(以当前帧和总帧数为参数)。
方法
crl.el:返回对象的DOM元素节点。
crl.length:返回对象的总的动画帧数。
crl.turn(i):动画旋转到第i帧。
crl.go(i):动画跳转到第i帧。
crl.play():开始动画序列的播放。
crl.stop():停止动画播放。
crl.hide():隐藏对象的DOM元素节点。
crl.show():显示对象的DOM元素节点。
crl.set(options):在插件初始化之后改变对象的参数:vertical 、reverse、cycle、speed、playSpeed
浏览器兼容
Internet Explorer 7+
Chrome
Safari
Firefox
Opera
以下基于circle的插件

circlr-config.js的源码

/*
 *     @author: 21-sun
 *     @version 1.0.0
 *     @date 2017-05-10
*/
;
(function($){
    
    var defaults = {
        ID : "",
        filePath : "",  // 小图路径:本地
        imgFormat : ".png",  // 图片格式
        len : 50, // 张数配置
        scroll: true, //滚动发滚轮自动旋转
        playSpeed : 400,  // 播放速度
        autoplay : true, // 是否自动播放
        delay : 3 // 不操作后开始自传
        };
    
    $.fn.show360 = function(options, undefined){
        
        var opts = $.extend({}, defaults, options, undefined);
        
        obj = $(this);
        
        var timer = null;
        var isLoaded = false; //判断图片是否加载完成
        var crl = null;
        
        var show = {
            init : function (){
                this.create();
                this.crlFn();
                
                if(opts.autoplay){
                    this.play();
                    this.stop();
                    }
                },
            create : function (){
                var html = "";
                html += "
"; html += "
"; html += "
"; html += "
"; html += "
"; html += "
"; html += "
"; html += "
"; html += "
"; html += "
"; html += "
"; html += "
"; html += "
"; html += "
"; obj.html(html); var step = 0; var imgList = ""; for(var i = 0; i < opts.len; i ++){ imgList += ""; } $(".img-wrap").html(imgList); }, crlFn : function(){ crl = circlr("circlr-" + opts.ID, { scroll: opts.scroll, loader: "loading-" + opts.ID, autoplay : opts.autoplay, playSpeed: opts.playSpeed }); }, play : function(){ $("#circlr-" + opts.ID).on("touchend || mouseup", function() { timer = setTimeout(function (){ crl.play(); }, opts.delay * 1000); }); }, stop : function(){ $("#circlr-" + opts.ID).on("touchstart || mousedown", function() { if(timer !== null){ clearTimeout(timer); timer = null; } crl.stop(); }); } }; return show.init(); }; })(jQuery);

html页面就更简单了:





test







页面中引入show.css
源码:

#effect_4{
    height: 100%;
    width: 100%;
}
#effect_4 .loading-center{
    width: 100%;
    height: 100%;
    position: relative;
}
#effect_4 .loading-center-absolute {
    position: absolute;
    left: 50%;
    top: 50%;
    height: 50px;
    width: 50px;
    margin-top: -25px;
    margin-left: -25px;
   -ms-transform: rotate(45deg); 
       -webkit-transform: rotate(45deg);
    transform: rotate(45deg); 
    -webkit-animation: loading-center-absolute 1.5s infinite;
    animation: loading-center-absolute 1.5s infinite;

}
#effect_4 .object{
    width: 25px;
    height: 25px;
    background-color: #FFF;
    float: left;
    
}

#effect_4 .object_one {
    -webkit-animation: object_one_4 1.5s infinite;
    animation: object_one_4 1.5s infinite;
    }
#effect_4 .object_two {
    -webkit-animation: object_two_4 1.5s infinite;
    animation: object_two_4 1.5s infinite;
    }
#effect_4 .object_three {
    -webkit-animation: object_three_4 1.5s infinite;
    animation: object_three_4 1.5s infinite;
    }
#effect_4 .object_four {
    -webkit-animation: object_four_4 1.5s infinite;
    animation: object_four_4 1.5s infinite;
    }

@-webkit-keyframes loading-center-absolute {
  100% { -webkit-transform: rotate(-45deg); }

}

@keyframes loading-center-absolute {
  100% { 
    transform:  rotate(-45deg);
    -webkit-transform:  rotate(-45deg);
  }
}

@-webkit-keyframes object_one_4 {
  25% { -webkit-transform: translate(0,-50px) rotate(-180deg); }
  100% { -webkit-transform: translate(0,0) rotate(-180deg); }

}

@keyframes object_one_4 {
  25% { 
    transform: translate(0,-50px) rotate(-180deg);
    -webkit-transform: translate(0,-50px) rotate(-180deg);
  } 
  100% { 
    transform: translate(0,0) rotate(-180deg);
    -webkit-transform: translate(0,0) rotate(-180deg);
  }
}

@-webkit-keyframes object_two_4 {
  25% { -webkit-transform: translate(50px,0) rotate(-180deg); }
  100% { -webkit-transform: translate(0,0) rotate(-180deg); }
}

@keyframes object_two_4 {
  25% { 
    transform: translate(50px,0) rotate(-180deg);
    -webkit-transform: translate(50px,0) rotate(-180deg);
  } 
  100% { 
    transform: translate(0,0) rotate(-180deg);
    -webkit-transform: translate(0,0) rotate(-180deg);
  }
}

@-webkit-keyframes object_three_4 {
  25% { -webkit-transform: translate(-50px,0) rotate(-180deg); }
  100% { -webkit-transform: translate(0,0) rotate(-180deg); }
}

@keyframes object_three_4 {
  25% { 
    transform:  translate(-50px,0) rotate(-180deg);
    -webkit-transform:  translate(-50px,0) rotate(-180deg);
  } 
  100% { 
    transform: translate(0,0) rotate(-180deg);
    -webkit-transform: rtranslate(0,0) rotate(-180deg);
  }
}

@-webkit-keyframes object_four_4 {
  25% { -webkit-transform: translate(0,50px) rotate(-180deg); }
  100% { -webkit-transform: translate(0,0) rotate(-180deg); }
}

@keyframes object_four_4 {
  25% { 
    transform: translate(0,50px) rotate(-180deg); 
    -webkit-transform: translate(0,50px) rotate(-180deg);  
  } 
  100% { 
    transform: translate(0,0) rotate(-180deg);
    -webkit-transform: translate(0,0) rotate(-180deg);
  }
}

这样就ok了,有兴趣,可以尝试一下奥。
如果文章有问题,请大家积极指正,共同进步。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/50764.html

相关文章

  • 创建一个360°视图 第一部分:概述&数据分析

    摘要:第一部分包括一个视图示例以及在构建视图时需要考虑的要点概述,第二部分将介绍一个示例数据模型的实现,第三部分将深入探讨如何将数据迁移到的机制。让我们假设你已经有创建一个视图的想法了。 本文源地址:http://www.mongoing.com/archives/884 本系列的三篇博客将会提供一个关于在MongoDB上构建360°视图的介绍。第一部分包括一个360°视图示例以及在构建...

    joywek 评论0 收藏0
  • 创建一个360°视图 第一部分:概述&数据分析

    摘要:第一部分包括一个视图示例以及在构建视图时需要考虑的要点概述,第二部分将介绍一个示例数据模型的实现,第三部分将深入探讨如何将数据迁移到的机制。让我们假设你已经有创建一个视图的想法了。 本文源地址:http://www.mongoing.com/archives/884 本系列的三篇博客将会提供一个关于在MongoDB上构建360°视图的介绍。第一部分包括一个360°视图示例以及在构建...

    winterdawn 评论0 收藏0

发表评论

0条评论

MASAILA

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<