3D渐变的轮播图效果,有点儿意思!

阅读原文:原文地址

一、前言

在Web开发中,轮播图(Carousel)是一种非常常见的功能,用于展示图片或内容,通过自动或手动的方式切换不同的视图,在网页设计中扮演着重要的角色。

吸引注意力:轮播图通常位于页面的显眼位置,如首页的顶部或中心区域,能够立即吸引访问者的注意力。通过展示精美、引人注目的图片或视频,轮播图能够激发访问者的兴趣,促使他们进一步探索网站的内容。

展示重要信息:轮播图是一种高效展示重要信息或促销活动的方式。商家可以在轮播图中展示最新的产品、优惠活动、重要公告等,以吸引潜在客户的注意并促进销售。

增加互动性:一些轮播图设计会包含导航按钮(如前后翻页按钮)或指示器(如小圆点),允许用户手动切换图片。这种交互性设计能够提升用户体验,让用户更加主动地参与到内容浏览中来。

节省空间:在有限的网页空间内,轮播图提供了一种有效的方式来展示多个内容项。通过自动或手动切换,轮播图能够在不占用过多页面空间的情况下,展示更多的图片或信息。

提升网站美观度:轮播图通常采用高质量的图片和动画效果,能够提升网站的整体美观度和视觉吸引力。一个设计精良的轮播图不仅可以吸引访问者的眼球,还能增加网站的专业感和可信度。

引导用户行为:轮播图有时也用作引导用户行为的工具。例如,在电商网站的轮播图中,可以放置“立即购买”、“了解更多”等按钮,直接引导用户进行购买或查看更多信息。

3D轮播图是一种通过添加3D变换效果使轮播图呈现出立体感的展示方式。它通过在轮播过程中,对图片的旋转、缩放、移动等动画效果的处理,使得图片在视觉上产生深度感,给用户一种身临其境的视觉体验。

CSS3中的transform、perspective、animation等属性是实现3D轮播图的重要工具。transform属性用于对元素进行旋转、缩放、移动或倾斜,而perspective属性则用于设置观察者与屏幕之间的距离,从而创建出3D效果。

二、实现过程及分析

2.1 基础布局代码

<!DOCTYPE html>
<html>
  <head>
      <meta charset="utf-8">
      <title>c.html</title>
      <style type="text/css">
          .carousel {
              width: 100%;
              position: relative;
              height: 400px;
              overflow: hidden;
              margin-top: 2em;
          }
          .carousel-list {
              width: 100%;
              height: 100%;
              position: relative;
              perspective: 1000px;
          }
          .carousel-item {
              width: 600px;
              height: 100%;
              position: absolute;
              user-select: none;
              transition: 0.4s;
              left: 50%;
              top: 0;
              margin-left: -300px;
          }
          .arrow {
              position: absolute;
              top: 50%;
              margin-top: -50px;
          }
          .arrow img {
              width: 100px;
          }
          .prev {
              left: 30px;
          }
          .next {
              right: 30px;
          }
      </style>
  </head>
  <body>
      <div class="carousel">
          <div class="carousel-list">
              <img class="carousel-item" src="./img/carousel-1.jpeg" alt="" />
              <img class="carousel-item" src="./img/carousel-2.jpeg" alt="" />
              <img class="carousel-item" src="./img/carousel-3.jpeg" alt="" />
              <img class="carousel-item" src="./img/carousel-4.jpeg" alt="" />
              <img class="carousel-item" src="./img/carousel-5.jpeg" alt="" />
              <img class="carousel-item" src="./img/carousel-6.jpeg" alt="" />
              <img class="carousel-item" src="./img/carousel-7.jpeg" alt="" />
          </div>
          <div class="prev arrow">
              <img src="./img/arrow-left.png" alt="" />
          </div>
          <div class="next arrow">
              <img src="./img/arrow.png" alt="" />
          </div>
      </div>
  </body>
</html>

2.2 左右切换事件

获取所有的轮播图元素,声明index变量记录当前是第几张轮播图索引,在获取向左和向右的按钮,并注册事件。

// 获取所有的轮播元素
const items = document.querySelectorAll('.carousel-item');
// 当前显示的第几张轮播图
let index = 0;

function layout() {}

layout();

const prev = document.querySelector('.prev');
const next = document.querySelector('.next');
// 向左
prev.addEventListener('click', () => {
    index --;
    if(index < 0) {
        index = 0;
    }
    layout();
})
// 向右
next.addEventListener('click', () => {
    index ++;
    if(index > items.length - 1) {
        index = items.length - 1;
    }
    layout();
})
// 点击图片切换
items.forEach((item, i) => {
    item.addEventListener('click', () => {
        index = i;
        layout()
    })
})

2.3 实现layout函数

const items = document.querySelectorAll('.carousel-item');
// 当前显示的第几张轮播图
let index = 3;

function layout() {
    // 图片之间的间隔
    const xOffsetStep = 100;
    // 两张轮播图之间的递减缩放倍率
    const scaleStep = 0.6;
    // 两张轮播图之间的透明度递减倍率
    const opacityStep = 0.5;
    for (let i = 0; i < items.length; i++) {
        const item = items[i];
        // 计算每张图片i距离当前图片index之间间隔几张
        const dis = Math.abs(i - index);
        // 返回1,-1,0,-0,当做一个正负号
        const sign = Math.sign(i - index);
        
        let xOffset = (i - index) * xOffsetStep;
        // 每张图片的初始偏移量,解决初始偏移距离太小的问题
        if (i !== index) {
            // sign为正数,右边的每张图片加上100的偏移量;
            // sign为负数,左边的每张图片减去100的偏移量。
            xOffset = xOffset + 100 * sign;
        }
        // 每张图片缩放倍数
        const scale = scaleStep ** dis;
        // 如果是当前的不旋转,否则左边旋转45度,右边旋转-45度
        const rotateY = i === index ? 0 : 45 * -sign;
        item.style.transform = `translateX(${xOffset}px) scale(${scale}) rotateY(${rotateY}deg)`;
        // scale同理,每张图片的透明度,越远透明度越小
        const opacity = opacityStep ** dis;
        item.style.opacity = opacity;
        // 设置每张图片的层级,距离当前index越远的,层级越低
        const zIndex = items.length - dis;
        item.style.zIndex = zIndex;
    }
}
  

解析1:

let xOffset = (i - index) * xOffsetStep;
在这里插入图片描述

解析2:

const dis = Math.abs(i - index);

const zIndex = items.length - dis;
item.style.zIndex = zIndex;
图片

解析3:

const dis = Math.abs(i - index);
// 每张图片缩放倍数
const scale = scaleStep ** dis;
图片

效果如下:图片

三、完整代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>3D渐变的轮播图效果</title>
        <style type="text/css">
            .carousel {
                width: 100%;
                position: relative;
                height: 400px;
                overflow: hidden;
                margin-top: 2em;
            }

            .carousel-list {
                width: 100%;
                height: 100%;
                position: relative;
                perspective: 1000px;
            }

            .carousel-item {
                width: 600px;
                height: 100%;
                position: absolute;
                user-select: none;
                transition: 0.4s;
                left: 50%;
                top: 0;
                margin-left: -300px;
            }

            .arrow {
                position: absolute;
                top: 50%;
                margin-top: -50px;
            }

            .arrow img {
                width: 60px;
            }

            .prev {
                left: 30px;
            }

            .next {
                right: 30px;
            }
        </style>
    </head>
    <body>
        <div class="carousel">
            <div class="carousel-list">
                <img class="carousel-item" src="./img/carousel-1.jpeg" alt="" />
                <img class="carousel-item" src="./img/carousel-2.jpeg" alt="" />
                <img class="carousel-item" src="./img/carousel-3.jpeg" alt="" />
                <img class="carousel-item" src="./img/carousel-4.jpeg" alt="" />
                <img class="carousel-item" src="./img/carousel-5.jpeg" alt="" />
                <img class="carousel-item" src="./img/carousel-6.jpeg" alt="" />
                <img class="carousel-item" src="./img/carousel-7.jpeg" alt="" />
            </div>
            <div class="prev arrow">
                <img src="./img/arrow-left.png" alt="" />
            </div>
            <div class="next arrow">
                <img src="./img/arrow.png" alt="" />
            </div>
        </div>
    </body>
    <script>
        const items = document.querySelectorAll('.carousel-item');
        // 当前显示的第几张轮播图
        let index = 3;

        function layout() {
            // 图片之间的间隔
            const xOffsetStep = 100;
            // 两张轮播图之间的递减缩放倍率
            const scaleStep = 0.6;
            // 两张轮播图之间的透明度递减倍率
            const opacityStep = 0.5;
            for (let i = 0; i < items.length; i++) {
                const item = items[i];
                // 计算每张图片i距离当前图片index之间间隔几张
                const dis = Math.abs(i - index);
                // 返回1,-1,0,-0,当做一个正负号
                const sign = Math.sign(i - index);

                let xOffset = (i - index) * xOffsetStep;
                // 每张图片的初始偏移量,解决初始偏移距离太小的问题
                if (i !== index) {
                    // sign为正数,右边的每张图片加上100的偏移量;
                    // sign为负数,左边的每张图片减去100的偏移量。
                    xOffset = xOffset + 100 * sign;
                }
                // 每张图片缩放倍数
                const scale = scaleStep ** dis;
                // 如果是当前的不旋转,否则左边旋转45度,右边旋转-45度
                const rotateY = i === index ? 0 : 45 * -sign;
                item.style.transform = `translateX(${xOffset}px) scale(${scale}) rotateY(${rotateY}deg)`;
                // scale同理,每张图片的透明度,越远透明度越小
                const opacity = opacityStep ** dis;
                item.style.opacity = opacity;
                // 设置每张图片的层级,距离当前index越远的,层级越低
                const zIndex = items.length - dis;
                item.style.zIndex = zIndex;
            }
        }

        layout();

        const prev = document.querySelector('.prev');
        const next = document.querySelector('.next');

        prev.addEventListener('click', () => {
            index--;
            if (index < 0) {
                index = 0;
            }
            layout();
        })
        next.addEventListener('click', () => {
            index++;
            if (index > items.length - 1) {
                index = items.length - 1;
            }
            layout();
        })

        // 点击图片切换
        items.forEach((item, i) => {
            item.addEventListener('click', () => {
                index = i;
                layout()
            })
        })
    </script>
</html>

四、总结

3D轮播图效果就是利用CSS3中transform属性用于对元素进行旋转、缩放、移动或倾斜,而perspective属性则用于设置观察者与屏幕之间的距离,从而创建出3D效果。

优点:

提升用户体验:3D立体轮播效果可以给用户带来沉浸式的视觉体验,增强轮播图的吸引力,提升用户对内容的关注度。

增加页面互动性:通过添加3D旋转、缩放等效果,使轮播图具有更多的动态感,增加页面的互动性和趣味性。

增强品牌形象:采用3D立体轮播效果展示产品或品牌相关的图片可以更好地突出产品特点和品牌形象,提高用户对品牌的认知和记忆度。

缺点:

在实现3D轮播图时,需要注意兼容性问题。虽然现代浏览器大多支持CSS3的3D变换效果,但仍需考虑旧版浏览器的兼容情况。

3D轮播图的动画效果可能会增加页面的加载时间和资源消耗,因此需要合理控制动画的复杂度和数量,以确保页面的流畅性和性能。

阅读原文:原文地址

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用Java 3D库来创建渐变散点图。Java 3D是一个用于创建3D图形应用程序的API,它提供了一组类和方法,可以帮助您创建各种3D图形效果。 要创建渐变散点图,您需要使用Java 3D中的PointArray类来创建点集合,并使用ColorInterpolator类来定义颜色插值器。然后,您可以将这些点添加到场景图中,并使用Java 3D中的Canvas3D类来显示场景。 以下是一个简单的Java 3D渐变散点图示例: ```java import javax.media.j3d.*; import javax.vecmath.*; public class GradientScatterPlot extends javax.swing.JFrame { public GradientScatterPlot() { // 创建3D场景 SimpleUniverse universe = new SimpleUniverse(); BranchGroup group = new BranchGroup(); // 创建点集合 PointArray points = new PointArray(100, PointArray.COORDINATES | PointArray.COLOR_3); // 添加点到集合中 for (int i = 0; i < 100; i++) { float x = (float) Math.random() * 2 - 1; float y = (float) Math.random() * 2 - 1; float z = (float) Math.random() * 2 - 1; points.setCoordinate(i, new Point3f(x, y, z)); points.setColor(i, new Color3f(getGradientColor(i / 100.0f))); } // 创建颜色插值器 ColorInterpolator colorInterpolator = new ColorInterpolator(new Alpha(1), points.getColorRef(), new float[]{0, 1}); // 创建渐变颜色 GradientColor gradientColor = new GradientColor(); gradientColor.setColor(0, new Color3f(1, 0, 0)); gradientColor.setColor(0.5f, new Color3f(0, 1, 0)); gradientColor.setColor(1, new Color3f(0, 0, 1)); // 设置颜色插值器的渐变颜色 colorInterpolator.setSchedulingBounds(new BoundingSphere()); colorInterpolator.setGradient(gradientColor); // 将点集合和颜色插值器添加到场景中 group.addChild(new Shape3D(points)); group.addChild(colorInterpolator); // 将场景添加到3D宇宙中 universe.getViewingPlatform().setNominalViewingTransform(); universe.addBranchGraph(group); // 创建3D画布并将其添加到窗口中 Canvas3D canvas = new Canvas3D(SimpleUniverse.getPreferredConfiguration()); getContentPane().add(canvas); pack(); } // 获取渐变颜色 private Color getGradientColor(float value) { float r = Math.max(0, Math.min(1, value * 2 - 1)); float g = Math.max(0, Math.min(1, 2 - value * 2)); float b = Math.max(0, Math.min(1, 2 * value)); return new Color(r, g, b); } public static void main(String[] args) { GradientScatterPlot plot = new GradientScatterPlot(); plot.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE); plot.setVisible(true); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值