用canvas做图片切换,用到 drawImage() 这个API.
将图片用各种办法画到canvas上,在每种画法之间切换.图片画到canvas上是宽度等比缩放的.
html结构是一个容器DIV,里面有多个IMG,需要给容器一个高度.
图片img在第一个子div里,是隐藏的.动态添加图片时要加到这个容器里.
<div class="slider" id="sliderBox" style="width:380px;height:260px"> // 图片在这个div里,div不可见. <div class="slider-imgs d-none"> <img src="slider1.jpg" /> <img src="slider2.jpg" /> <img src="slider3.jpg" /> <img src="slider4.jpg" /> <img src="slider5.jpg" /> <img src="slider6.jpg" /> </div> // 会加入canvas对象,图片就是画在这个对象上的. </div>
类和主要方法
// slider对象 let slid = {}; // canvas 2d绘画 slid.ctx = null; // 图片容器div slid.box = null; // 图片数组 slid.imgs = null; // 当前动画显示的图片 slid.imgIndex = -1; // 每个动画的时间间隔 slid.skipTime = 2000; // 动画函数数组,函数加入数组的顺序决定动画顺序 slid.aniArr = null; slid.aniIndex = 0; // 动画速度 slid.speed=1; // 等待加载图片完成后开始动画: 定时检查图片是否加载完成,加载中时,画面显示loading.加载完成后开始动画 slid.loadImgAndStart = (...index) => {} // 开始动画: 不会等待图片加载完成 slid.start = (...index) => {} // 每个动画是一个函数,新增动画时,添加一个函数.然后在 aniArr 数组中加入这个函数. function newAniFun(slider){} // 当前已有的动画,函数加入数组的顺序决定动画顺序 slid.aniArr = [block, middleCir, left, top, leftZoom, rotate, fade];
// 动画函数示例: 图片从中心扩大显示 function middleCir(sld) { let ctx = sld.ctx; let img = sld.nextImg(); let r = 0, w = sld.w, h = sld.h, imgW = img.width, imgH = img.height; let scale = w / imgW, imgHScale = imgH * scale; // 动画函数 let step = (timestamp) => { // 结束动画条件 if (r > Math.max(w, h) * 0.707) { // 调用下一个动画 sld.next(); return; } ctx.save(); ctx.clearRect(0, 0, w, h); ctx.beginPath(); ctx.arc(w / 2, h / 2, r, 0, Math.PI * 2); ctx.clip(); ctx.drawImage(img, 0, 0, w, imgHScale); ctx.restore(); r++; window.requestAnimationFrame(step); } // 使用requestAnimationFrame()开始动画 window.requestAnimationFrame(step); }
let slid = slider('sliderBox'); // 定时检查所有图片加载完成后开始动画. id: 装img的div容器Id slid.loadImgAndStart(); // 不检查加载情况,直接开始动画 slid.start();