微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

javascript+HTML5自定义元素播放焦点图动画

这是一款基于HTML5的焦点图动画,它和其他焦点图不同的地方在于,它播放的不仅仅是图片,而是可以自定义控制的网页元素。它不仅在图片间切换有过渡动画效果,而且在切换时图片中的元素也将出现动画效果,比如图中的文字移动、打散、重新组合等,这款HTML5动画图片播放器算得上是高端大气上档次。

效果图:

HTML代码

rush:xhtml;">
arallax-bg" id="slider-wrap">
arallax-bg" id="slider">
Box">
irst"> Kendo UISmartSite Ver 2.2
智能网站管理系统

copy">采用前后台完全分离技术,通过标签支持标签循环嵌套、判断标签自定义标签文件循环嵌套等)加模板技术.全站生成纯静态页。

Kendo UI
企业网站管理系统

copy">单页面、单页面索引、新闻、产品展示、下载、友情链接、网上商城,在线支付、配送、支付方式管理、广告等模块。

Kendo UI
智能移动网站管理系统

CSS代码

这里列出的是这个焦点图相关的核心CSS代码

rush:css;"> .slider section {display: none;} .slider section.first {display: block;}

.slider-sections,.slider-sections section {width: 861px; height: 335px;}

.slider-sections {margin: 0 auto; position: relative;}
.slider-sections section {position: absolute; top: 0; left: 0px; }

.header-content h2
{
font:400 32px/1.2 "microsoft yahei",Tahoma,arial,sans-serif;
color: #fff;
margin: 0 0 26px;
}
.header-content p
{
margin: 0 0 30px;
}

.header-content .centered-content
{
padding-top: 30px;
padding-bottom: 10px;
}

.button {
float: left;
width: auto !important;
list-style: none;
}
.button a,.button button,.button input { / Standard black button /
font-size: 15px;
/font-family: 'lucida sans',helvetica,sans-serif;/
line-height: 18px;
color: #fff !important;

text-decoration: none;

padding: 5px 14px 6px 13px;
display: block;
width: auto;
position: relative;
z-index: 2;

border: none;
-moz-border-radius: 3px;
border-radius: 3px;
cursor: pointer;

background: #313131; / Old browsers /
background: -moz-linear-gradient(top,#313131 0%,#222222 100%); / FF3.6+ /
background: -webkit-linear-gradient(top,#222222 100%); / Chrome10+,Safari5.1+ /
background: -o-linear-gradient(top,#222222 100%); / Opera11.10+ /
background: -ms-linear-gradient(top,#222222 100%); / IE10+ /
background: linear-gradient(top,#222222 100%); / W3C /

-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
transition: all 0.3s ease;
}

.button a:hover,.button input:hover,.button button:hover,.button a:focus,.button input:focus,.button button:focus
{
background: #464646; / Old browsers /
background: -moz-linear-gradient(top,#464646 0%,#393939 100%); / FF3.6+ /
background: -webkit-linear-gradient(top,#393939 100%); / Chrome10+,#393939 100%); / Opera11.10+ /
background: -ms-linear-gradient(top,#393939 100%); /
IE10+ /
background: linear-gradient(top,#393939 100%); /
W3C */
}

header .header-content .button a,#content .button a:hover
{
text-decoration: none;
}

.header-content .beta-ribbons {
position: absolute;
height: 120px;
width: 85px;
text-indent: -200px;
overflow: hidden;
background: url(../images/kendo-ribbons.png) no-repeat 0 0;
}

.header-content .beta-ribbons.ribbon-1 {
background-position: -170px 0;
top: -3px;
right: -145px;
}

.header-content p.copy .beta-ribbons.ribbon-1 {
top: -135px;
left: 900px;
}

.header-content .beta-ribbons.ribbon-4 {
background-position: -255px 0;
left: -62px;
top: -30px;
z-index: 10;
text-indent: -2000px;
}

JavaScript代码

下面是这个焦点图插件代码

rush:js;"> /** * @author Alexander Farkas * v. 1.22 */ (function ($) { if (!document.defaultview || !document.defaultview.getComputedStyle) { // IE6-IE8 var oldCurCSS = $.curCSS; $.curCSS = function (elem,name,force) { if (name === 'background-position') { name = 'backgroundPosition'; } if (name !== 'backgroundPosition' || !elem.currentStyle || elem.currentStyle[name]) { return oldCurCSS.apply(this,arguments); } var style = elem.style; if (!force && style && style[name]) { return style[name]; } return oldCurCSS(elem,'backgroundPositionX',force) + ' ' + oldCurCSS(elem,'backgroundPositionY',force); }; }

var oldAnim = $.fn.animate;
$.fn.animate = function (prop)
{
if ('background-position' in prop)
{
prop.backgroundPosition = prop['background-position'];
delete prop['background-position'];
}
if ('backgroundPosition' in prop)
{
prop.backgroundPosition = '(' + prop.backgroundPosition;
}
return oldAnim.apply(this,arguments);
};

function toArray(strg)
{
strg = strg.replace(/left|top/g,'0px');
strg = strg.replace(/right|bottom/g,'100%');
strg = strg.replace(/([0-9.]+)(\s|)|$)/g,"$1px$2");
var res = strg.match(/(-?[0-9.]+)(px|\%|em|pt)\s(-?[0-9.]+)(px|\%|em|pt)/);
return [parseFloat(res[1],10),res[2],parseFloat(res[3],res[3]];
}

$.fx.step.backgroundPosition = function (fx)
{
if (!fx.bgPosReady)
{
var start = $.curCSS(fx.elem,'backgroundPosition');
if (!start)
{//FF2 no inline-style fallback
start = '0px 0px';
}

start = toArray(start);
fx.start = [start[0],start[2]];
var end = toArray(fx.end);
fx.end = [end[0],end[2]];

fx.unit = [end[1],end[3]];
fx.bgPosReady = true;
}
//return;
var NowPosX = [];
NowPosX[0] = ((fx.end[0] - fx.start[0]) fx.pos) + fx.start[0] + fx.unit[0];
NowPosX[1] = ((fx.end[1] - fx.start[1])
fx.pos) + fx.start[1] + fx.unit[1];
fx.elem.style.backgroundPosition = NowPosX[0] + ' ' + NowPosX[1];

};
})(jQuery);

/*
tlrkSlider

example usage:

$("#slider").tlrkSlider({
autoStart: false,elements: {
"img": {delay: 10},"h2": {delay: 500},".copy": {delay: 800},".button": {delay: 1000}
}
});

to go to a specific frame:
$("#slider").tlrkSlider("go",position);
"position" can have one of the following values:
"next","prev","first","last","+1","-1" or a numeric value

to start/stop the automatic loop:
$("#slider").tlrkSlider("start");
$("#slider").tlrkSlider("stop");

to change the delay between automatic transitions:
$("#slider").tlrkSlider("option","delayAnimation",1000);

to change any option:
$("#slider").tlrkSlider("option",option_name,option_value);

Changing the "elements" object is not tested.

Changing the following options: "navigation","navigationClass","framesSelector","autoStart" won't have any effect for Now.
They are used only during the initialization.

$("#slider").data("tlrkSlider") will return the plugin instance and the methods/properties can be accessed from there.

The plugin contructor defaults are accessable through TlrkSlider.defaults

The function that actually sweep the elements in/out can be overriden from
TlrkSlider.prototype._animationIn and TlrkSlider.prototype._animationOut

See sweepIn/sweepOut

*/

;(function( $,window,document,undefined ){

// utility function that generates the "dots" navigation
function generateNavigation($el,count,config) {
var i,html = "",width = count * 24;

html += "

    ";
    for (i = 0; i < count; i++) {
    html += "
  1. <a " + (i === 0 ? "class='selected'" : "" ) + " href='#" + (i) + "'>slide
  2. ";
    }
    html += "
";

$el.append(html);
}

function sweepOut($el,windowWidth) {
var dfr = $.Deferred(),pos = $el.position(),width = $el.width(),delta,final,options = $el.data("tlrkAnimOptions");

windowWidth = windowWidth || $(window).width(); // check if the windowWidth is passed,if not - get it

delta = windowWidth - pos.left;
final = -(delta);

setTimeout(function(){
$el.animate({left: final,opacity: "toggle"},options.speed,options.easing,function(){
dfr.resolve();
});
},options.delay);

return dfr.promise();
}

function sweepIn($el,windowWidth,frameLeft) {
var dfr = $.Deferred(),options = $el.data("tlrkAnimOptions"),positionData = $el.data("tlrkOriginalPos"),final = positionData.position.left,rightEdge;

windowWidth = windowWidth || $(window).width(); // check if the windowWidth is passed,if not - get it

$el.css({opacity: 0,display: "block"}); // move it outside the right edge of the screen
$el.css("left",function(current){
return current + windowWidth - frameLeft;
});

setTimeout(function(){
$el.animate({left: final,opacity: 1},options.delay);

return dfr.promise();
}

// two pass function that first iterates all the elements and gets their position/width/height
// and then sets their position to absolute
function absolutize($elements) {

// todo - move it to separate function and do it just once
// gather the original position/dimension data for all elements
$elements.each(function(){
var $t = $(this);

if ($t.data("tlrkOriginalPos")) return

$t.data("tlrkOriginalPos",{
position: $t.position(),width: $t.width(),height: $t.height(),css_pos: $t.css("position"),css_left: $t.css("left"),css_top: $t.css("top"),css_width: $t.css("width") || "auto",css_height: $t.css("height") || "auto"
});

});

// set the absolute position
$elements.each(function(){
var $t = $(this),opos = $t.data("tlrkOriginalPos");

$t.css({
position: "absolute",left: opos.position.left,top: opos.position.top,width: opos.width,height: opos.height
});
});
}

function restoreFrameElements($elements) {
$elements.each(function(){
var $t = $(this),opos = $t.data("tlrkOriginalPos");

if (!opos) return

$t.css({
position: opos.css_pos,left: opos.css_left,top: opos.css_top,width: opos.css_width,height: opos.css_height
});
});

}

var TlrkSlider = function( elem,options ){
this.elem = elem;
this.$elem = $(elem);
this.options = options;
};

// the plugin prototype
TlrkSlider.prototype = {
defaults: {

defaultElementOptions: {
speed: 1200,easing: "easeInOutBack",// interval before the element starts moving when the fadeIn/Out functions are called
// it's a good idea to give different delays for the different elements
// if all have the same delay they'll start moving all together
delay: 100
},// dispose elements are these that are not included in the elements object
// but affect the document flow and will be fadedIn/Out
disposeDelay: 100,// delay for the dispose elements
disposeSpeed: 1000,// how quickly they'll fadeOut/In

delayBetweenTransition: 1000,// time between starting fadeOut and fadeIn
delayAnimation: 7000,// time between auto changing the current frame

loop: true,// if true when clicking next on the last frame the slider jumps to the first one

autoStart: true,// start the automatic looping through the frames on init

framesSelector: "section",// selector for the frames inside the slider

elements: {
"p": {delay: 100,speed: 1000,easing: "easeInOutBack"}
},navigation: true,// the dots navigation on the bottom
navigationClass: "slider-nav",// callbacks
// another way to "catch" these events is with
// $(-slider-element-).bind("animationStart")
animationStart: null,animationEnd: null
},init: function() {
var c,e,element,$element,that = this,$firstFrame;

c = this.config = $.extend({},this.defaults,this.options);

this.elem.style.position = "relative"; // make the wrapping element relative

// basics
this.$frames = this.$elem.find(c.framesSelector);
this.framesCount = this.$frames.length;
this.currentFrame = 0;
this.queue = [];

this.$elementsByFrame = {};
this.
$disposeElementsByFrame = {};

for (i = 0; i < this.framesCount; i++) {
this._$elementsByFrame[i] = this.getFrameElements(i); // cache the $elements by frame
this.
$disposeElementsByFrame[i] = this._getdisposeFrameElements(i); // cache the rest of the tree for each frame
}

if (c.navigation) {
generateNavigation(this.$elem,this.framesCount,c);
this.$navigation = this.$elem.find("."+c.navigationClass);
}

// bindings
this.$elem.find(".slider-nav").delegate("a","click",function(e){
var frame = this.getAttribute("href").split("#")[1];
that.go.call(that,frame);
return false;
});

this.$elem // internal bindings for the callbacks
.bind("animationStart",function(){
if ($.isFunction(c.animationStart)) {c.animationStart.apply(that,arguments);}
})
.bind("animationEnd",function(){
if ($.isFunction(c.animationEnd)) {c.animationEnd.apply(that,arguments);}
})
;

// start animation?
if (c.autoStart) {
this.start();
} else {
this.running = false;
}

return this;
},start: function(instant) {
var that = this;

if (this.timer) { // we'll clear the current timer
window.clearTimeout(this.timer);
}

this.running = true;

if (instant) {
that.nextFrame();
} else {
this.timer = window.setTimeout(function(){ that.nextFrame.call(that) },that.config.delayAnimation);
}
},stop: function() {
if (!this.running) return; // we are not running

this.running = false;
window.clearTimeout(this.timer);
},// main function for changing frames
selectFrame: function(frame,dfr) {
var c = this.config,// shorthand for the config
that = this,dfr = dfr || $.Deferred(),dFadeIn = $.Deferred(),dFadeOut = $.Deferred();

if (isNaN(frame) || frame < 0 || frame > this.framesCount || frame === this.currentFrame) {
dfr.reject();
return dfr.promise();
}

// clear the animation loop interval if the animation is running
if (this.running && this.timer) {
window.clearTimeout(this.timer);
}

// check if we are currenly running an animation.
if (this.animated && this.queue.length > 0) {
// wait for the last item in the queue to finish
this.queue[this.queue.length-1].done(function(){
that.selectFrame(frame,dfr); // and call again the selectFrame
})
return dfr.promise();
}

this.animated = true;
this.$elem.trigger("animationStart",[this,frame]);

this.queue.push(dfr);

// fade the frames
dFadeOut = this._fadeOutFrame(this.currentFrame);

// hide the fadetout frame
dFadeOut.done(function(){
that.$frames.eq(that.currentFrame).hide();
});

window.setTimeout(function(){ // then wait delayBetweenTransition and fadeIn the new frame
dFadeIn = that._fadeInFrame.call(that,frame).done(function(){
// when both the fadeIn and fadeOut are done we'll resolve the selectFrame promise
$.when(dFadeOut,dFadeIn).done(function(){
that.animated = false;
that.queue.shift();
that.$elem.trigger("animationEnd",[that]);
that.currentFrame = frame;
dfr.resolve();
});
});
},c.delayBetweenTransition);

// navigation html change
if (this.config.navigation) {
this.$navigation.find(".selected").removeClass("selected").end()
.find("a").eq(frame).addClass("selected");
}

dfr.done(function(){ // we'll resume the loop animation after the transitions are done
if (that.running) {
that.start();
}
});

return dfr.promise();
},fadeFrame: function(frame,callback,direction) {
var dfr = $.Deferred(),$frame = this.$frames.eq(frame),$elements = this.
$elementsByFrame[frame],windowWidth = $(window).width(),// cache it before the animations,so we don't have to check it for each element
i,len,elementAnimations = [],$disposeElements = this._$disposeElementsByFrame[frame],$affectedElements,frameLeft = $frame.offset().left;

direction = direction || "out";

if (!$.isFunction(callback)) return; // do nothing if there's no callback passed

$affectedElements = $elements.add($disposeElements);

// position absolute the animation and dispose elements
absolutize($affectedElements);

// toggle the dispose elements
if ($disposeElements.length > 0) {
window.setTimeout(function(){
$disposeElements[direction === "out" ? "fadeOut" : "fadeIn"](that.config.disposeSpeed);
},this.config.disposeDelay);
}

// invoke the callback for each element
// the callback must return a promise
$elements.each(function(){
elementAnimations.push( callback.call(that,$(this),frameLeft) );
});

// wait for all the elements to finish their animation
$.when.apply(this,elementAnimations).done(function(){
//restoreFrameElements($affectedElements); // and restore the elements' position
dfr.resolve(); // resolve the fade function
});

return dfr.promise();
},_fadeOutFrame: function(frame) {
var dfr = $.Deferred(),$disposeElements = this._$disposeElementsByFrame[frame];

this._fadeFrame(frame,this._animationOut,"out").done(function(){
dfr.resolve();
})

return dfr.promise();
},fadeInFrame: function(frame) {
var dfr = $.Deferred(),$elements = this.
$elementsByFrame[frame];

this._restoreFrame(frame);

$frame.show();

this._fadeFrame(frame,this._animationIn,"in").done(function(){
dfr.resolve();
});

return dfr.promise();
},restoreFrame: function(frame){
if (!frame) return
restoreFrameElements( this.
$elementsByFrame[frame].add(this._$disposeElementsByFrame[frame]) );
},nextFrame: function() {
var frame = this.currentFrame+1,dfr = $.Deferred();

if (frame > this.framesCount-1) {
if (this.config.loop) {
frame = 0;
} else {
dfr.reject();
}
};

this.selectFrame(frame).done(function(){
dfr.resolve();
});

return dfr.promise();
},prevFrame: function() {
var frame = this.currentFrame-1,dfr = $.Deferred();

if (frame < 0) {
if (this.config.loop) {
frame = this.framesCount-1;
} else {
dfr.reject();
return dfr.promise();
}
}

this.selectFrame(frame).done(function(){
dfr.resolve();
});

return dfr.promise();
},go: function(str) { // shorthand
switch (str) {
case "next":
case "+1":
this.nextFrame();
break;

case "prev":
case "-1":
this.prevFrame();
break;

case "first":
this.selectFrame(0);
break;

case "last":
this.selectFrame(this.framesCount-1);
break;

default:
if (isNaN(str)) return;
this.selectFrame(Number(str));
}
},// returns jquery collection of animation elements
_getFrameElements: function(frame) {
var $frame = this.$frames.eq(frame),elements = this.config.elements,elementOptions,$found,$frameElements = $([]);

for (e in elements) {
elementOptions = elements[e];
$found = $frame.find(e);
$found.addClass("t-frame-element").data("tlrkAnimOptions",$.extend({},this.defaults.defaultElementOptions,elementOptions ));
$frameElements = $frameElements.add($found);
}

return $frameElements;
},// returns jquery collection of elements that have to be faded out
// i.e. elements on the same level as the animation elements
// that doesn't contain other animation elements
_getdisposeFrameElements: function(frame) {
var $disposeElements = $([]),$elements = this._$elementsByFrame[frame];

$elements.each(function(){
var $t = $(this),$siblings = $t.siblings().not(".t-frame-element");

$siblings.each(function(){
var $t = $(this);
// check if the node is not already marked and doesn't contains other frame elements
if (!$t.hasClass("t-frame-dispose") && $t.find(".t-frame-element").length === 0) {
$t.addClass("t-frame-dispose");
$disposeElements = $disposeElements.add($t);
}
});

});
return $disposeElements;
},// expose the internal animationIn/Out functions that are called for each element in the frame
// two arguments are passed - the $element which have to be animated and the window width
_animationIn: sweepIn,_animationOut: sweepOut

}

TlrkSlider.defaults = TlrkSlider.prototype.defaults;

$.fn.tlrkSlider = function(options) {
var otherArgs = Array.prototype.slice.call(arguments,1);

return this.each(function() {
var $el = $(this),pluginData = $el.data("tlrkSlider");

if (!pluginData) { // check if the slider is already attached
pluginData = new TlrkSlider(this,options).init();
$el.data("tlrkSlider",pluginData);
return;
}

//change the options or call a method
if (typeof options === "string") {

// setting / getting option(s)
if (options === "option") {

if (typeof otherArgs[0] === "string" && typeof otherArgs[1] !== "undefined") { // set an option value
pluginData.config[otherArgs[0]] = otherArgs[1];
}

if (typeof otherArgs[0] === "object") { // extend the config with new options
pluginData.config = $.extend(pluginData.config,otherArgs[0]);
}

} else { // call a method?
try {
pluginData[options].apply(pluginData,otherArgs);
} catch(ex) {
throw "Error calling a plugin method (" + ex + ")";
}
}
}
});
};

window.TlrkSlider = TlrkSlider;

})( jQuery,document );

下面是页面调用的JS代码

rush:js;"> $(document).ready(function(){ var $backgrounds = $(".header-content").find(".parallax-bg"),LAYER_OFFSET = 30,PRLX_SPEED = 1500,$slider;

$slider = $("#slider").tlrkSlider({
autoStart: true,animationStart: function(ev,slider,step){
var max_steps = this.framesCount;
$backgrounds.each(function(idx,el){
var pos = (step (100 / max_steps)) + (LAYER_OFFSET idx);
$(this).animate({"backgroundPosition": pos + "% 0"},PRLX_SPEED);
});
},".button": {delay: 1000}
}
});

$(".header-content")
.hover(
function(){$(this).find(".slider-prev,.slider-next").show();},function(){$(this).find(".slider-prev,.slider-next").hide();}
)
.find(".slider-prev").click(function(){$slider.tlrkSlider("go","prev"); return false; }).end()
.find(".slider-next").click(function(){$slider.tlrkSlider("go","next"); return false; });

});

希望本文对大家学习javascript程序设计有所帮助。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐