摘要:是一款可以對產品圖片進行度全方位旋轉展示的插件。動畫幀通過切換的速度,默認值為毫秒。動畫幀改編之后的回調函數以當前幀和總幀數為參數。返回對象的總的動畫幀數。顯示對象的元素節點。
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 += ""; 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 += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += "
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了,有興趣,可以嘗試一下奧。
如果文章有問題,請大家積極指正,共同進步。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/50764.html
摘要:第一部分包括一個視圖示例以及在構建視圖時需要考慮的要點概述,第二部分將介紹一個示例數據模型的實現,第三部分將深入探討如何將數據遷移到的機制。讓我們假設你已經有創建一個視圖的想法了。 本文源地址:http://www.mongoing.com/archives/884 本系列的三篇博客將會提供一個關于在MongoDB上構建360°視圖的介紹。第一部分包括一個360°視圖示例以及在構建...
摘要:第一部分包括一個視圖示例以及在構建視圖時需要考慮的要點概述,第二部分將介紹一個示例數據模型的實現,第三部分將深入探討如何將數據遷移到的機制。讓我們假設你已經有創建一個視圖的想法了。 本文源地址:http://www.mongoing.com/archives/884 本系列的三篇博客將會提供一個關于在MongoDB上構建360°視圖的介紹。第一部分包括一個360°視圖示例以及在構建...
閱讀 2837·2023-04-25 20:02
閱讀 1435·2021-11-11 16:55
閱讀 614·2021-09-26 09:46
閱讀 6205·2021-09-22 15:55
閱讀 1823·2021-08-09 13:41
閱讀 1572·2019-08-30 15:52
閱讀 2372·2019-08-30 14:13
閱讀 3289·2019-08-26 13:48