123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408 |
- /*
- * Cloud 9 Carousel 2.0
- * Cleaned up, refactored, and improved version of CloudCarousel
- *
- * See the demo and get the latest version on GitHub:
- * http://specious.github.io/cloud9carousel/
- *
- * Copyright (c) 2014 by Ildar Sagdejev ( http://twitter.com/tknomad )
- * Copyright (c) 2011 by R. Cecco ( http://www.professorcloud.com )
- * MIT License
- *
- * Please retain this copyright header in all versions of the software
- *
- * Requires:
- * - jQuery 1.3.0 or later -OR- Zepto 1.1.1 or later
- *
- * Optional (jQuery only):
- * - Reflection support via reflection.js plugin by Christophe Beyls
- * http://www.digitalia.be/software/reflectionjs-for-jquery
- * - Mousewheel support via mousewheel plugin
- * http://plugins.jquery.com/mousewheel/
- */
- ;(function ($) {
- //
- // Detect CSS transform support
- //
- var transform = (function () {
- var vendors = ['webkit', 'moz', 'ms']
- var style = document.createElement('div').style
- var trans = 'transform' in style ? 'transform' : undefined
- for (var i = 0, count = vendors.length; i < count; i++) {
- var prop = vendors[i] + 'Transform'
- if (prop in style) {
- trans = prop
- break
- }
- }
- return trans
- })()
- var Item = function (element, options) {
- element.item = this
- this.element = element
- if (element.tagName === 'IMG') {
- this.fullWidth = element.width
- this.fullHeight = element.height
- } else {
- element.style.display = 'inline-block'
- this.fullWidth = element.offsetWidth
- this.fullHeight = element.offsetHeight
- }
- element.style.position = 'absolute'
- if (options.mirror && this.element.tagName === 'IMG') {
- // Wrap image in a div together with its generated reflection
- this.reflection = $(element).reflect(options.mirror).next()[0]
- var $reflection = $(this.reflection)
- this.reflection.fullHeight = $reflection.height()
- $reflection.css('margin-top', options.mirror.gap + 'px')
- $reflection.css('width', '100%')
- element.style.width = '100%'
- // The item element now contains the image and reflection
- this.element = this.element.parentNode
- this.element.item = this
- this.element.alt = element.alt
- this.element.title = element.title
- }
- if (transform && options.transforms) this.element.style[transform + 'Origin'] = '0 0'
- this.moveTo = function (x, y, scale) {
- this.width = this.fullWidth * scale
- this.height = this.fullHeight * scale
- this.x = x
- this.y = y
- this.scale = scale
- var style = this.element.style
- style.zIndex = ('' + scale * 100) | 0
- if (transform && options.transforms) {
- style[transform] = 'translate(' + x + 'px, ' + y + 'px) scale(' + scale + ')'
- } else {
- // The gap between the image and its reflection doesn't resize automatically
- if (options.mirror && this.element.tagName === 'IMG')
- this.reflection.style.marginTop = options.mirror.gap * scale + 'px'
- style.width = this.width + 'px'
- style.left = x + 'px'
- style.top = y + 'px'
- }
- }
- }
- var time = (function () {
- return !window.performance || !window.performance.now
- ? function () {
- return +new Date()
- }
- : function () {
- return performance.now()
- }
- })()
- //
- // Detect requestAnimationFrame() support
- //
- // Support legacy browsers:
- // http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
- //
- var cancelFrame = window.cancelAnimationFrame || window.cancelRequestAnimationFrame
- var requestFrame = window.requestAnimationFrame
- ;(function () {
- var vendors = ['webkit', 'moz', 'ms']
- for (var i = 0, count = vendors.length; i < count && !cancelFrame; i++) {
- cancelFrame =
- window[vendors[i] + 'CancelAnimationFrame'] ||
- window[vendors[i] + 'CancelRequestAnimationFrame']
- requestFrame = requestFrame && window[vendors[i] + 'RequestAnimationFrame']
- }
- })()
- let myTime = -1
- var Carousel = function (element, options) {
- var self = this
- // 邵根
- myTime = window.setInterval(() => {
- try {
- clearInterval(myTime)
- window.moveFu(self)
- } catch (error) {}
- }, 200)
- var $container = $(element)
- this.items = []
- this.xOrigin = options.xOrigin === null ? $container.width() * 0.5 : options.xOrigin
- this.yOrigin = options.yOrigin === null ? $container.height() * 0.1 : options.yOrigin
- this.xRadius = options.xRadius === null ? $container.width() / 2.3 : options.xRadius
- this.yRadius = options.yRadius === null ? $container.height() / 6 : options.yRadius
- this.farScale = options.farScale
- this.rotation = this.destRotation = Math.PI / 2 // start with the first item positioned in front
- this.speed = options.speed
- this.smooth = options.smooth
- this.fps = options.fps
- this.timer = 0
- this.autoPlayAmount = options.autoPlay
- this.autoPlayDelay = options.autoPlayDelay
- this.autoPlayTimer = 0
- this.onLoaded = options.onLoaded
- this.onRendered = options.onRendered
- this.itemOptions = {
- transforms: options.transforms
- }
- if (options.mirror) {
- this.itemOptions.mirror = $.extend({ gap: 2 }, options.mirror)
- }
- $container.css({ position: 'relative', overflow: 'hidden' })
- // Rotation:
- // * 0 : right
- // * Pi/2 : front
- // * Pi : left
- // * 3 Pi/2 : back
- this.rotateItem = function (itemIndex, rotation) {
- var item = this.items[itemIndex]
- var sin = Math.sin(rotation)
- var farScale = this.farScale
- var scale = farScale + (1 - farScale) * (sin + 1) * 0.5
- item.moveTo(
- this.xOrigin + scale * (Math.cos(rotation) * this.xRadius - item.fullWidth * 0.5),
- this.yOrigin + scale * sin * this.yRadius,
- scale
- )
- }
- this.render = function () {
- var count = this.items.length
- var spacing = (2 * Math.PI) / count
- var radians = this.rotation
- for (var i = 0; i < count; i++) {
- this.rotateItem(i, radians)
- radians += spacing
- }
- if (typeof this.onRendered === 'function') this.onRendered(this)
- }
- this.playFrame = function () {
- var rem = self.destRotation - self.rotation
- var now = time()
- var dt = (now - self.lastTime) * 0.002
- self.lastTime = now
- if (Math.abs(rem) < 0.003) {
- self.rotation = self.destRotation
- self.pause()
- } else {
- // Rotate asymptotically closer to the destination
- self.rotation = self.destRotation - rem / (1 + self.speed * dt)
- self.scheduleNextFrame()
- }
- self.render()
- }
- this.scheduleNextFrame = function () {
- this.lastTime = time()
- this.timer =
- this.smooth && cancelFrame
- ? requestFrame(self.playFrame)
- : setTimeout(self.playFrame, 1000 / this.fps)
- }
- this.itemsRotated = function () {
- return (this.items.length * (Math.PI / 2 - this.rotation)) / (2 * Math.PI)
- }
- this.floatIndex = function () {
- var count = this.items.length
- var floatIndex = this.itemsRotated() % count
- // Make sure float-index is positive
- return floatIndex < 0 ? floatIndex + count : floatIndex
- }
- this.nearestIndex = function () {
- return Math.round(this.floatIndex()) % this.items.length
- }
- let myIndex = -1
- this.nearestItem = function () {
- // 获取索引
- if (this.nearestIndex() !== myIndex) {
- // 邵根
- window.getIndexFu(this.nearestIndex())
- myIndex = this.nearestIndex()
- }
- return this.items[this.nearestIndex()]
- }
- this.play = function () {
- if (this.timer === 0) this.scheduleNextFrame()
- }
- this.pause = function () {
- this.smooth && cancelFrame ? cancelFrame(this.timer) : clearTimeout(this.timer)
- this.timer = 0
- }
- //
- // Spin the carousel. Count is the number (+-) of carousel items to rotate
- //
- this.go = function (count) {
- this.destRotation += ((2 * Math.PI) / this.items.length) * count
- this.play()
- }
- this.deactivate = function () {
- this.pause()
- clearInterval(this.autoPlayTimer)
- options.buttonLeft.unbind('click')
- options.buttonRight.unbind('click')
- $container.unbind('.cloud9')
- }
- this.autoPlay = function () {
- this.autoPlayTimer = setInterval(function () {
- self.go(self.autoPlayAmount)
- }, this.autoPlayDelay)
- }
- this.enableAutoPlay = function () {
- // Stop auto-play on mouse over
- $container.bind('mouseover.cloud9', function () {
- clearInterval(self.autoPlayTimer)
- })
- // Resume auto-play when mouse leaves the container
- $container.bind('mouseout.cloud9', function () {
- self.autoPlay()
- })
- this.autoPlay()
- }
- this.bindControls = function () {
- options.buttonLeft.bind('click', function () {
- self.go(-1)
- return false
- })
- options.buttonRight.bind('click', function () {
- self.go(1)
- return false
- })
- if (options.mouseWheel) {
- $container.bind('mousewheel.cloud9', function (event, delta) {
- self.go(delta > 0 ? 1 : -1)
- return false
- })
- }
- if (options.bringToFront) {
- $container.bind('click.cloud9', function (event) {
- var hits = $(event.target).closest('.' + options.itemClass)
- if (hits.length !== 0) {
- // var idx = self.items.indexOf(hits[0].item)
- // var count = self.items.length
- // var diff = idx - (self.floatIndex() % count)
- // // Choose direction based on which way is shortest
- // if (2 * Math.abs(diff) > count) diff += diff > 0 ? -count : count
- // self.destRotation = self.rotation
- // self.go(-diff)
- }
- })
- }
- }
- var items = $container.find('.' + options.itemClass)
- this.finishInit = function () {
- //
- // Wait until all images have completely loaded
- //
- for (var i = 0; i < items.length; i++) {
- var item = items[i]
- if (
- item.tagName === 'IMG' &&
- (item.width === undefined || (item.complete !== undefined && !item.complete))
- )
- return
- }
- clearInterval(this.initTimer)
- // Init items
- for (i = 0; i < items.length; i++)
- this.items.push(new Item(items[i], this.itemOptions))
- // Disable click-dragging of items
- $container.bind('mousedown onselectstart', function () {
- return false
- })
- if (this.autoPlayAmount !== 0) this.enableAutoPlay()
- this.bindControls()
- this.render()
- if (typeof this.onLoaded === 'function') this.onLoaded(this)
- }
- this.initTimer = setInterval(function () {
- self.finishInit()
- }, 50)
- }
- //
- // The jQuery plugin
- //
- $.fn.Cloud9Carousel = function (options) {
- return this.each(function () {
- /* For full list of options see the README */
- options = $.extend(
- {
- xOrigin: null, // null: calculated automatically
- yOrigin: null,
- xRadius: null,
- yRadius: null,
- farScale: 0.5, // scale of the farthest item
- transforms: true, // enable CSS transforms
- smooth: true, // enable smooth animation via requestAnimationFrame()
- fps: 30, // fixed frames per second (if smooth animation is off)
- speed: 4, // positive number
- autoPlay: 0, // [ 0: off | number of items (integer recommended, positive is clockwise) ]
- autoPlayDelay: 4000,
- bringToFront: false,
- itemClass: 'cloud9-item',
- handle: 'carousel'
- },
- options
- )
- $(this).data(options.handle, new Carousel(this, options))
- })
- }
- })(window.jQuery || window.Zepto)
|