body { margin:0; min-height:100vh; background:black; display:flex; justify-content:center; align-items:center; overflow:hidden; } image-box { display:block; position:relative; --box-width:75vw; --box-height:80vh; width:var(--box-width); height:var(--box-height); perspective:var(--box-width); transform-style:preserve-3d; } image-box > * { position:absolute; display:block; height:100%; width:100%; object-fit:cover; transition:transform .4s ease; transform:translateZ(-1000vw); visibility:hidden; } image-box >:is(.current,.next,.previous) { visibility:visible; transform:translateZ(calc(-0.5 * var(--box-width))) rotateY(var(--rotation,0deg)) translateZ(calc(0.5 * var(--box-width))); } image-box > .current { --rotation:0deg; } image-box > .next { --rotation:90deg; } image-box > .previous { --rotation:-90deg; } aside { position:fixed; bottom:5vh; border-radius:12px; padding:12px; background:rgba(255,255,255,.1); back-filter:blur(4px); box-shadow:0 0 30px black; } aside button { border:none; border-radius:50px; margin:0; padding:0; color:white; height:50px; min-width:50px; text-align:center; line-height:50px; font-size:30px; background:rgba(0,0,0,.3); back-filter:blur(4px); transition:background .2s ease; } aside button:hover { background:rgba(0,0,0,.4); } aside button:active { background:rgba(0,0,0,.7); } image-box > section { background:teal; color:white; display:flex; justify-content:center; align-items:center; flex-direction:column; }
更新时间:2021-08-31 01:03:36
应用方法:复制粘贴 css 和 js (去掉最下边那两个加按钮事件的)代码,在想添加这个盒子的地方,加上这样的代码
<image-box> <img src="..." alt="..." /> <!--图片--> <div style="background: lightgreen;">hello, world!</div> <!--非图片内容--> <!--如果要放的话,样式可能会有小问题,需要自己调整--> </image-box>
然后调用 next 和 previous 控制翻页:
next(); // 下一页 previous(); //上一页 $('button').click(next); //可以直接绑定到按钮上 setinterval(next, 3000); //可以每过一段时间自动翻页
需要注意的是,想要修改宽高的话,需要修改 --box-width 和 --box-height 这两个 css 变量,而不是直接修改 width 和 height:
/*正确示例*/ image-box { --box-width: 640px; --box-height: 480px; }
/*错误示例,会导致效果异常* / image-box { width: 640px!important; height: 480px!important; }
需要在页面用到多个翻页盒子的话,js代码换成这样:
customelements.define('image-box', class extends htmlelement {# operations = [0]; //只支持 chrome,如果需要支持其它浏览器的话,请使用 babel 等预处理器,或者用下划线之类的替换掉“#”。 # index = 0# animating = false; constructor() { super(); this.#animate(); } async# animate() { if (!this.#operations.length) return (this.#animating = false); const operation = this.#operations.shift(); for (let child of this.children) child.classlist.remove('current', 'next', 'previous'); this.#index += operation; while (this.#index < 0) this.#index += this.children.length; const current = this.children[this.#index % this.children.length]; current.classlist.add('current'); (current.previouselementsibling || this.children[this.children.length - 1]).classlist.add('previous'); (current.nextelementsibling || this.children[0]).classlist.add('next'); settimeout(this.#animate.bind(this), operation && 400); } next() { this.#operations.push(1); this.#animating || this.#animate(this.#animating = true); } previous() { this.#operations.push(-1); this.#animating || this.#animate(this.#animating = true); } });
然后这样切换:
let box = document.queryselector('image-box'); //按需更换选择器 box.next(); //下一页 box.previous(); //上一页 setinterval(box.next.bind(box), //注意需要 bind 一下,不然会报错 3000 ); //隔一段时间翻页 setinterval(() => box.next(), //当然这么写可以免去 bind 的麻烦 3000 ); //也是隔一段时间翻页