分享一款基于jqery的带3D切换效果的图片展示

  先看效果:在线演示

  这个效果并不是我想出来的,我只是对某个开源的flash图片展示(请原谅我并不知道原作的链接……)使用js重写罢了。

  起因是,我所在学校的网站(相思湖网站)要进行改版,其中各专题首页需要一个图片展示。某成员找到了一个带3D切换效果的图片展示,可惜是flash做的,并且在使用的过程中有一个问题,如果图片的宽高与原始定义的不同,就会出现一个固定的白框。

  当时我的第一反应就是为什么要flash?难道js做不到么?话虽如此,但如果可以改改代码就能解决的话,倒也省事。终归我过于乐观了,尽管as和js是近亲,我却总抓不住问题的关键所在,一部分是因为对flash的不熟悉,令一部分也因为那as代码写得也够凌乱的。总之我决定了要用js重写。

  仔细想想这个效果并不很难实现,借助jquery的animation可以轻松实现节点元素的各种动画,唯一的难点是确定图片的位置而已了。

  我是利用等比对折来确定图片的位置:  

  分享一款基于jqery的带3D切换效果的图片展示

  假设整个框架的长度是W,高度是H,图片的长为w,高为h。那么居中的图片的top为(H - h) / 2,left为(W - w) / 2,旁边图片的计算方法类同。

  源代码:

js
  1 /*

  2  * xsh slider for jquery

  3  * By: QiuXiang, [email protected]

  4  * Used In: http://xsh.gxun.edu.cn

  5  *

  6  * Copyright 2012, XSH

  7  * Free to use and abuse under the MIT license.

  8  * http://www.opensource.org/licenses/mit-license.php

  9  */

 10 (function($){

 11     $.fn.xsh_slider = function(options){

 12         var opts = $.extend({}, $.fn.xsh_slider.defawrapts, options);

 13         var $this = $(this);

 14         var wrap = $('ul', $this);

 15         var imgs = [];

 16         var current = 1;

 17         var pre_img;

 18         var cur_img;

 19         var next_img;

 20         var timeout;

 21 

 22         init();

 23 

 24         function pre()

 25         {

 26             unbind_click();

 27 

 28             next_img.li.removeClass('next_img');

 29             cur_img.li.removeClass('cur_img');

 30             pre_img.li.removeClass('pre_img');

 31 

 32             current = (current == 0 ? imgs.length - 1 : current - 1);

 33             var pre_i = (current == 0 ? imgs.length - 1 : current - 1);

 34             var _next_img = next_img;

 35             next_img = cur_img;

 36             cur_img = pre_img;

 37             pre_img = imgs[pre_i];

 38 

 39             next_img.li.addClass('next_img');

 40             cur_img.li.addClass('cur_img');

 41             pre_img.li.addClass('pre_img');

 42 

 43             // 动画切换

 44             next_hide(_next_img);

 45             goto_next(next_img);

 46             goto_cur(cur_img);

 47             pre_init(pre_img);

 48             goto_pre(pre_img);

 49 

 50             alt_hide(next_img);

 51             alt_show(cur_img);

 52 

 53             bind_click();

 54             timeout_reset();

 55         }

 56 

 57         // 切换下一张图片

 58         function next()

 59         {

 60             unbind_click();

 61 

 62             pre_img.li.removeClass('pre_img');

 63             cur_img.li.removeClass('cur_img');

 64             next_img.li.removeClass('next_img');

 65 

 66             current = ((current == imgs.length - 1) ? 0 : current + 1);

 67             var next_i = (current == imgs.length - 1) ? 0 : current + 1;

 68             var _pre_img = pre_img;

 69             pre_img = cur_img;

 70             cur_img = next_img;

 71             next_img = imgs[next_i];

 72 

 73             pre_img.li.addClass('pre_img');

 74             cur_img.li.addClass('cur_img');

 75             next_img.li.addClass('next_img');

 76 

 77             // 动画切换

 78             pre_hide(_pre_img);

 79             goto_pre(pre_img);

 80             goto_cur(cur_img);

 81             next_init(next_img);

 82             goto_next(next_img);

 83 

 84             alt_hide(pre_img);

 85             alt_show(cur_img);

 86 

 87             bind_click();

 88             timeout_reset();

 89         }

 90 

 91         // pre_img 的消逝

 92         function pre_hide(img)

 93         {

 94             img.li.animate({

 95                 width: 0,

 96                 height: 0,

 97                 left: 0,

 98                 top: opts.height / 2,

 99                 opacity: 0

100             }, {

101                 duration: opts.speed,

102                 easing: 'easeOutExpo',

103                 queue: false

104             });

105         }

106 

107         // next_img 的消逝

108         function next_hide(img)

109         {

110             img.li.animate({

111                 width: 0,

112                 height: 0,

113                 left: opts.width,

114                 top: opts.height / 2,

115                 opacity: 0

116             }, {

117                 duration: opts.speed,

118                 easing: 'easeOutExpo',

119                 queue: false

120             });

121         }

122 

123         // 切换到 pre_img

124         function goto_pre(img)

125         {

126             img.li.animate({

127                 width: img.pre.width,

128                 height: img.pre.height,

129                 left: img.pre.left,

130                 top: img.pre.top,

131                 opacity: 1

132             }, {

133                 duration: opts.speed,

134                 easing: 'easeOutExpo',

135                 queue: false

136             });

137         }

138 

139         // 切换到 cur_img

140         function goto_cur(img)

141         {

142             img.li.animate({

143                 width: img.center.width,

144                 height: img.center.height,

145                 left: img.center.left,

146                 top: img.center.top,

147                 opacity: 1

148             }, {

149                 duration: opts.speed,

150                 easing: 'easeOutExpo',

151                 queue: false

152             });

153         }

154 

155         // 切换到 next_img

156         function goto_next(img)

157         {

158             img.li.animate({

159                 width: img.next.width,

160                 height: img.next.height,

161                 left: img.next.left,

162                 top: img.next.top,

163                 opacity: 1

164             }, {

165                 duration: opts.speed,

166                 easing: 'easeOutExpo',

167                 queue: false

168             });

169         }

170 

171         // 绑定图片的点击切换事件

172         function bind_click()

173         {

174             $('.pre_img', $this).click(function(){

175                 pre();

176                 return false;

177             });

178             $('.next_img', $this).click(function(){

179                 next();

180                 return false;

181             });

182         }

183         

184         // 取消绑定图片的点击切换事件

185         function unbind_click()

186         {

187             $('.pre_img').unbind();

188             $('.next_img').unbind();

189         }

190 

191         // 重置自动播放

192         function timeout_reset()

193         {

194             clearInterval(timeout);

195             auto_play();

196         }

197 

198         // 显示图片说明

199         function alt_show(img)

200         {

201             if (img.div.text() != '')

202                 img.div.css({'display': 'block'});

203         }

204 

205         // 隐藏图片说明

206         function alt_hide(img)

207         {

208             img.div.css({'display': 'none'});

209         }

210 

211         // 创建图片切换按钮

212         function btn_create()

213         {

214             wrap.append('<div class="btn_pre"><a>' + opts.pre_text + '</a></div>');

215             wrap.append('<div class="btn_next"><a>' + opts.next_text + '</a></div>');

216 

217             var btn_pre = $('.btn_pre', $this);

218             var btn_next = $('.btn_next', $this);

219 

220             btn_pre.css({'top': (opts.height - btn_pre.height()) / 2});

221             btn_next.css({'top': (opts.height - btn_next.height()) / 2});

222 

223             btn_pre.click(function(){

224                 pre();

225             });

226             btn_next.click(function(){

227                 next();

228             });

229         }

230 

231 

232         // 作为上一个图片

233         function as_pre(img)

234         {

235             img.li.css({

236                 'width': img.pre.width,

237                 'height': img.pre.height,

238                 'left': img.pre.left,

239                 'top': img.pre.top,

240                 'opacity': 1

241             });

242         }

243 

244         // 作为当前图片

245         function as_cur(img)

246         {

247             img.li.css({

248                 'width': img.center.width,

249                 'height': img.center.height,

250                 'left': img.center.left,

251                 'top': img.center.top,

252                 'opacity': 1

253             });

254         }

255 

256         // 作为下一个图片

257         function as_next(img)

258         {

259             img.li.css({

260                 'width': img.next.width,

261                 'height': img.next.height,

262                 'left': img.next.left,

263                 'top': img.next.top,

264                 'opacity': 1

265             });

266         }

267 

268         // 下一个图片出现的初始化

269         function next_init(img)

270         {

271             img.li.css({

272                 'width': 0,

273                 'height': 0,

274                 'left': opts.width,

275                 'top': opts.height / 2,

276                 'opacity': 0

277             });

278         }

279 

280         // 上一个图片出现的初始化

281         function pre_init(img)

282         {

283             img.li.css({

284                 'width': 0,

285                 'height': 0,

286                 'left': 0,

287                 'top': opts.height / 2,

288                 'opacity': 0

289             });

290         }

291 

292         // 图片初始化

293         function img_init()

294         {

295             // 遍历图片,创建图片状态缓存

296             $('li', $this).each(function(){

297                 var _this = $(this);

298                 var img = $('img', _this);

299                 var alt = img.attr('alt') || '';

300                 var width = img.width();

301                 var height = img.height();

302 

303                 _this.append('<div class="alt"><p>' + alt + '</p></div>');

304                 imgs.push({

305                     img: img,

306                     li: _this,

307                     div: $('div', _this),

308                     center: {

309                         width: width,

310                         height: height,

311                         left: (opts.width - width) / 2,

312                         top: (opts.height - height) / 2

313                     },

314                     pre: {

315                         width: width / 2,

316                         height: height / 2,

317                         left: (opts.width - width) / 4,

318                         top: opts.height / 2 - height / 4

319                     },

320                     next: {

321                         width: width / 2,

322                         height: height / 2,

323                         left: opts.width * 3 / 4- width / 4,

324                         top: opts.height / 2 - height / 4

325                     }

326                 });

327                 img.width('100%').height('100%');

328             });

329 

330             pre_img = imgs[0];

331             cur_img = imgs[1];

332             next_img = imgs[2];

333             current = 1;

334 

335             pre_img.li.addClass('pre_img');

336             cur_img.li.addClass('cur_img');

337             next_img.li.addClass('next_img');

338 

339             as_pre(pre_img);

340             as_cur(cur_img);

341             as_next(next_img);

342 

343             pre_img.li.show();

344             cur_img.li.show();

345             next_img.li.show();

346             alt_show(cur_img);

347         }

348 

349         function wrap_init()

350         {

351             wrap.addClass('xsh_slider');

352             wrap.css({

353                 'width': opts.width,

354                 'height': opts.height

355             });

356         }

357 

358         // 自动播放

359         function auto_play()

360         {

361             if (opts.auto)

362             {

363                 timeout = setInterval(function(){

364                     next();

365                 }, opts.delay);

366             }

367         }

368 

369         // 初始化

370         function init()

371         {

372             wrap_init();

373             btn_create();

374             img_init();

375             bind_click();

376             auto_play();

377             mousewheel();

378         }

379 

380         // 鼠标滚轮事件

381         function mousewheel()

382         {

383             wrap.mousewheel(function(event, delta, deltaX, deltaY){

384                 if (delta > 0)

385                     next();

386                 else

387                     pre();

388 

389                 return false;

390             });

391         }

392     };

393 

394     // 默认参数

395     $.fn.xsh_slider.defawrapts = {

396         pre_text: '<',

397         next_text: '>',

398         width: 960,

399         height: 400,

400         speed: 500,

401         delay: 5000,

402         auto: true

403     };

404 

405     // 阻尼动画切换效果

406     $.extend(

407         $.easing, {

408             easeOutExpo: function (x, t, b, c, d) {

409                 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;

410             }

411         }

412     );

413 })(jQuery);

414 

415 // 引用的鼠标滚轮 jquery 插件

416 /*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)

417  * Licensed under the MIT License (LICENSE.txt).

418  *

419  * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.

420  * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.

421  * Thanks to: Seamus Leahy for adding deltaX and deltaY

422  *

423  * Version: 3.0.6

424  *

425  * Requires: 1.2.2+

426  */

427 (function($){

428     var types = ['DOMMouseScroll', 'mousewheel'];

429 

430     if ($.event.fixHooks) {

431         for ( var i=types.length; i; ) {

432             $.event.fixHooks[ types[--i] ] = $.event.mouseHooks;

433         }

434     }

435 

436     $.event.special.mousewheel = {

437         setup: function() {

438             if ( this.addEventListener ) {

439                 for ( var i=types.length; i; ) {

440                     this.addEventListener( types[--i], handler, false );

441                 }

442             } else {

443                 this.onmousewheel = handler;

444             }

445         },

446 

447         teardown: function() {

448             if ( this.removeEventListener ) {

449                 for ( var i=types.length; i; ) {

450                     this.removeEventListener( types[--i], handler, false );

451                 }

452             } else {

453                 this.onmousewheel = null;

454             }

455         }

456     };

457 

458     $.fn.extend({

459         mousewheel: function(fn) {

460             return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");

461         },

462 

463         unmousewheel: function(fn) {

464             return this.unbind("mousewheel", fn);

465         }

466     });

467 

468     function handler(event) {

469         var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;

470         event = $.event.fix(orgEvent);

471         event.type = "mousewheel";

472 

473         // Old school scrollwheel delta

474         if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; }

475         if ( orgEvent.detail ) { delta = -orgEvent.detail/3; }

476 

477         // New school multidimensional scroll (touchpads) deltas

478         deltaY = delta;

479 

480         // Gecko

481         if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {

482             deltaY = 0;

483             deltaX = -1*delta;

484         }

485 

486         // Webkit

487         if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; }

488         if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; }

489 

490         // Add event and delta to the front of the arguments

491         args.unshift(event, delta, deltaX, deltaY);

492 

493         return ($.event.dispatch || $.event.handle).apply(this, args);

494     }

495 

496 })(jQuery);
css
 1 .xsh_slider {

 2     padding: 0;

 3     list-style: none;

 4     overflow: hidden;

 5     position: relative;

 6 }

 7 .xsh_slider li {

 8     position: absolute;

 9     overflow: hidden;

10     opacity: 0;

11     filter: alpha(opacity = 0);

12 }

13 .xsh_slider .alt {

14     position: absolute;

15     bottom: 0;

16     display: none;

17 }

18 .xsh_slider img {

19     border: none;

20 }

21 .xsh_slider .pre_img, .xsh_slider .next_img {

22     z-index: 1;

23     cursor: pointer;

24 }

25 .xsh_slider .cur_img {

26     z-index: 2;

27 }

28 .xsh_slider .btn_pre, .xsh_slider .btn_next {

29     position: absolute;

30     cursor: pointer;

31 }

32 .xsh_slider .btn_pre {

33     left: 0;

34 }

35 .xsh_slider .btn_next {

36     right: 0;

37 }

  惭愧的说,代码写得不怎么样,纯粹面向过程写法。

  最后附上下载:xsh_slide.7z

你可能感兴趣的:(图片)