前端:UI 交互式特效 —— Css、Js

这篇具有很好参考价值的文章主要介绍了前端:UI 交互式特效 —— Css、Js。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

😷😊🤺🤺🤺前期回顾前端:UI 交互式特效 —— Css、Js,前端,css

打造极简风格动效 —— 5 分钟轻松实现惊艳、震撼人心的视觉效果_彩色之外的博客-CSDN博客

😁

css动画 —— 把你喜欢css动画嵌入到浏览器中_css做的动画效果怎么嵌入网页_彩色之外的博客-CSDN博客

 代码已上传资源

  开头省略200字》……
念及此
  直接上图

目录

😊 进度条

🥰 唯美登录背景

 😎 蜡烛登录动画

🥵 火箭 

😶‍🌫️ 时间翻盘

🤺 复选框动画

🤪 基础表单输入动画

😃 卡包动画

😷 流光扫过动画

🥶 酷炫标题

🤖 交互式评分

🐔 动态向上箭头

 🐽 卸载对话框表情交互动画

 ✈️ 随机密码生成器代码

🧨 跟随设备切换主题

🚒 昼夜切换主题

 ❤️‍🩹 使用系统取色器

😃 右键动态菜单(已做边缘动画及边界外判断)

🎋 酷炫打字特效

🚆 方形抽奖

🚼 圆形抽奖

🛹 吸顶楼层导航

✈️ 困了盖坤

🛫 扣扣乐

🍰 签名回溯

🌍 翻盘抽奖

🪂 地址 🤺🤺🤺 

 🥰😉  谢谢观看


 图例:

前端:UI 交互式特效 —— Css、Js,前端,css

前端:UI 交互式特效 —— Css、Js,前端,css

前端:UI 交互式特效 —— Css、Js,前端,css

前端:UI 交互式特效 —— Css、Js,前端,css

前端:UI 交互式特效 —— Css、Js,前端,css

前端:UI 交互式特效 —— Css、Js,前端,css

  图片过多,不在开头一一展示了,下面图与源码会放在一起,代码设计原生JS、VUE3

前端:UI 交互式特效 —— Css、Js,前端,css

😊 进度条

前端:UI 交互式特效 —— Css、Js,前端,css

<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <title>3款漂亮的html5+css3 3D百分比进度条动画特效</title>

  <style>
    @import url("https://fonts.googleapis.com/css?family=Nunito:400,900");

    * {
      box-sizing: border-box;
    }

    body,
    html {
      font-family: "Nunito", sans-serif;
      background: linear-gradient(0deg, #EEEFED, #F9E3E9);
      margin: 0;
      padding: 0;
      color: #4D5075;
      font-weight: 300;
      width: 100%;
      height: 100%;
      margin: 0;
    }

    body {
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      padding: 7vh 15vw 0vh 15vw;
    }

    h1 {
      text-align: center;
      margin: 0 0 10vh 0;
      font-size: 7vh;
      font-weight: 500;
      text-shadow: 0px -15px 70px rgba(77, 80, 117, 0.6);
    }

    h1 b {
      font-weight: 900;
    }

    p {
      text-align: center;
      font-size: 1.3rem;
      text-shadow: 10px 5px 25px rgba(77, 80, 117, 0.6);
      margin-bottom: 8vh;
    }

    .third-bar-p {
      margin-top: 7vh;
    }

    .perspective {
      -webkit-perspective: 70vh;
      perspective: 70vh;
      text-align: center;
      -webkit-perspective-origin: 50% 50%;
      perspective-origin: 50% 50%;
      position: relative;
      transition: -webkit-transform 0.3s ease;
      transition: transform 0.3s ease;
      transition: transform 0.3s ease, -webkit-transform 0.3s ease;
    }

    .perspective:hover {
      -webkit-transform: scale(1.04);
      transform: scale(1.04);
    }

    .bar-input {
      position: absolute;
      height: 100%;
      left: 0;
      right: 0;
      margin: auto;
      opacity: 0;
    }

    #first-bar .bar-input {
      width: 55vh;
    }

    #second-bar .bar-input {
      width: 40vh;
    }

    #third-bar .bar-input {
      width: 42vh;
    }

    .bar {
      display: inline-block;
      position: relative;
      -webkit-transform: rotateX(55deg);
      transform: rotateX(55deg);
      -webkit-transform-style: preserve-3d;
      transform-style: preserve-3d;
    }

    .bar .bar-face {
      display: inline-block;
      width: 100%;
      height: 100%;
      position: absolute;
      left: 0;
      -webkit-transform-origin: 50% 100%;
      transform-origin: 50% 100%;
    }

    .bar .bar-face.front {
      -webkit-transform: rotateX(-90deg);
      transform: rotateX(-90deg);
    }

    .bar .bar-face.percentage:before {
      height: 100%;
      content: "";
      display: block;
      position: absolute;
      bottom: 0;
      margin: 0;
    }

    #first-bar .bar {
      width: 55vh;
      height: 7vh;
    }

    #first-bar .bar .bar-face {
      background: rgba(255, 255, 255, 0.5);
    }

    #first-bar .bar .bar-face.floor {
      box-shadow: 0 1.3em 1.2em -0.4em rgba(0, 0, 70, 0.25), 0 -2em 15em 0.5em #4d5075, 0 -0.75em 25em 10em rgba(255, 255, 255, 0.4);
    }

    #first-bar .bar .bar-face.percentage:before {
      box-shadow: 0 1.6em 7em -0.3em rgba(149, 65, 105, 0.5);
    }

    #first-bar .bar .bar-face.roof {
      -webkit-transform: translateZ(7vh);
      transform: translateZ(7vh);
    }

    #first-bar .bar .bar-face.back {
      -webkit-transform: rotateX(-90deg) translateZ(-7vh);
      transform: rotateX(-90deg) translateZ(-7vh);
    }

    #first-bar .bar .bar-face.percentage:before {
      background-color: rgba(149, 65, 105, 0.6);
    }

    #second-bar .bar {
      width: 40vh;
      height: 10vh;
    }

    #second-bar .bar .bar-face {
      background: rgba(60, 75, 132, 0.5);
      background-image: linear-gradient(90deg, rgba(134, 114, 146, 0.5), rgba(60, 75, 132, 0.1)), url("https://zephyo.github.io/22Days/code/5/graphics/stars.svg"), url("https://zephyo.github.io/22Days/code/5/graphics/stars2.svg");
      background-repeat: repeat repeat;
    }

    #second-bar .bar .bar-face.floor {
      box-shadow: 0 1.3em 1.2em -0.4em rgba(0, 0, 70, 0.25), 0 -2em 15em 0.5em #4d5075, 0 -0.75em 25em 10em rgba(255, 255, 255, 0.4);
    }

    #second-bar .bar .bar-face.percentage:before {
      box-shadow: 0 1.6em 7em -0.3em rgba(200, 212, 250, 0.5);
    }

    #second-bar .bar .bar-face.roof {
      -webkit-transform: translateZ(10vh);
      transform: translateZ(10vh);
    }

    #second-bar .bar .bar-face.back {
      -webkit-transform: rotateX(-90deg) translateZ(-10vh);
      transform: rotateX(-90deg) translateZ(-10vh);
    }

    #second-bar .bar .bar-face.percentage:before {
      background-image: url("https://zephyo.github.io/22Days/code/5/graphics/sky.png");
      opacity: 0.9;
    }

    #third-bar .bar {
      width: 42vh;
      height: 8vh;
    }

    #third-bar .bar .bar-face {
      background: rgba(232, 154, 173, 0.7);
    }

    #third-bar .bar .bar-face.floor {
      box-shadow: 0 1.3em 1.2em -0.4em rgba(0, 0, 70, 0.25), 0 -2em 15em 0.5em #4d5075, 0 -0.75em 25em 10em rgba(255, 255, 255, 0.4);
    }

    #third-bar .bar .bar-face.percentage:before {
      box-shadow: 0 1.6em 7em -0.3em rgba(236, 0, 113, 0.5);
    }

    #third-bar .bar .bar-face.roof {
      -webkit-transform: translateZ(8vh);
      transform: translateZ(8vh);
    }

    #third-bar .bar .bar-face.back {
      -webkit-transform: rotateX(-90deg) translateZ(-8vh);
      transform: rotateX(-90deg) translateZ(-8vh);
    }

    #third-bar .bar .bar-face.percentage:before {
      background: linear-gradient(90deg, rgba(245, 239, 200, 0.5), #ec0071);
    }

    #third-bar .bar .indicator {
      box-shadow: 0px 15px 35px rgba(236, 0, 113, 0.3);
      background: #ec0071;
      width: 8vh;
      height: 8vh;
      color: white;
      -webkit-transform: translateY(9.6vh);
      transform: translateY(9.6vh);
      text-align: center;
      font-size: 2.5vh;
      font-weight: 900;
      line-height: 8vh;
    }

    #third-bar .bar .indicator:before {
      content: "";
      position: absolute;
      background: #ec0071;
      left: 0;
      right: 0;
      margin: auto;
      top: -6px;
      width: 4vh;
      height: 4vh;
      z-index: -1;
      -webkit-transform: rotate(45deg);
      transform: rotate(45deg);
    }
  </style>

</head>

<body>
  <script src="/demos/googlegg.js"></script>

  <h1>Scalable <b>3D</b> Range Sliders</h1>

  <main class="perspective" id="first-bar">
    <section class="bar">
      <div class="bar-face back percentage"></div>
      <div class="bar-face floor percentage"></div>
      <div class="bar-face roof percentage"></div>
      <div class="bar-face front percentage"></div>
    </section>
    <input class="bar-input" type="range" min="0" max="101" value="64" />
  </main>
  <p>Simple Range</p>


  <main class="perspective" id="second-bar">
    <section class="bar">
      <div class="bar-face back percentage"></div>
      <div class="bar-face floor percentage"></div>
      <div class="bar-face roof percentage"></div>
      <div class="bar-face front percentage"></div>
    </section>
    <input class="bar-input" type="range" min="0" max="101" value="37" />
  </main>
  <p>Patterned Range</p>


  <main class="perspective" id="third-bar">
    <section class="bar">
      <div class="bar-face back percentage"></div>
      <div class="bar-face floor percentage"></div>
      <div class="bar-face roof percentage"></div>
      <div class="bar-face front percentage"></div>
      <div class="indicator">89%</div>
    </section>
    <input class="bar-input" type="range" min="0" max="100" value="89" />
  </main>
  <p class="third-bar-p">Gradient Range with Indicator</p>

  <script>
    function initInputs() {
      var allInputs = document.body.querySelectorAll(".bar-input");

      for (var i = 0; i < allInputs.length; i++) {
        var input = allInputs[i];
        var barId = input.parentNode.id;
        var styleEl = document.head.appendChild(document.createElement("style"));

        if (i == allInputs.length - 1) {
          //set indicator
          var indicator = input.parentNode.querySelector('.bar .indicator');
          setBarIndicator(barId, input, styleEl, indicator);
          input.oninput = setBarIndicator.bind(this, barId, input, styleEl, indicator);
          input.onchange = setBarIndicator.bind(this, barId, input, styleEl, indicator);
        } else {
          setBar(barId, input, styleEl);
          input.oninput = setBar.bind(this, barId, input, styleEl);
          input.onchange = setBar.bind(this, barId, input, styleEl);
        }
      }
    }

    function setBar(barId, input, styleEl) {
      styleEl.innerHTML =
        "#" + barId + " .bar-face.percentage:before {width:" + input.value + "%;}";
    }

    function setBarIndicator(barId, input, styleEl, indicatorEl) {
      styleEl.innerHTML =
        "#" + barId + " .bar-face.percentage:before {width:" + input.value + "%;}";
      indicatorEl.style.marginLeft = (input.value - 10) + '%';
      indicatorEl.textContent = input.value + '%';
    }

    initInputs();
  </script>

  </div>
</body>

</html>

🥰 唯美登录背景

前端:UI 交互式特效 —— Css、Js,前端,css

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>HTML5 Canvas透明丝带飘动背景动画特效</title>

    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            background-color: #000;
            overflow: hidden;
        }

        .login-container {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            overflow: hidden;
        }
    </style>

</head>

<body>

    <div class="login-container"></div>

    <script>
        (function () {

            let pi = Math.PI;
            let pi2 = 2 * Math.PI;

            this.Waves = function (holder, options) {
                let Waves = this;

                Waves.options = extend(options || {}, {
                    resize: false,
                    rotation: 45,
                    waves: 5,
                    width: 100,
                    hue: [11, 14],
                    amplitude: 0.5,
                    background: true,
                    preload: true,
                    speed: [0.004, 0.008],
                    debug: false,
                    fps: false,
                });

                Waves.waves = [];

                Waves.holder = document.querySelector('.login-container');
                Waves.canvas = document.createElement('canvas');
                Waves.ctx = Waves.canvas.getContext('2d');
                Waves.holder.appendChild(Waves.canvas);

                Waves.hue = Waves.options.hue[0];
                Waves.hueFw = true;
                Waves.stats = new Stats();

                Waves.resize();
                Waves.init(Waves.options.preload);

                if (Waves.options.resize)
                    window.addEventListener('resize', function () {
                        Waves.resize();
                    }, false);

            };

            Waves.prototype.init = function (preload) {
                let Waves = this;
                let options = Waves.options;

                for (let i = 0; i < options.waves; i++)
                    Waves.waves[i] = new Wave(Waves);

                if (preload) Waves.preload();
            };

            Waves.prototype.preload = function () {
                let Waves = this;
                let options = Waves.options;

                for (let i = 0; i < options.waves; i++) {
                    Waves.updateColor();
                    for (let j = 0; j < options.width; j++) {
                        Waves.waves[i].update();
                    }
                }
            };

            Waves.prototype.render = function () {
                let Waves = this;
                let ctx = Waves.ctx;
                let options = Waves.options;

                Waves.updateColor();
                Waves.clear();

                if (Waves.options.debug) {
                    ctx.beginPath();
                    ctx.strokeStyle = '#f00';
                    ctx.arc(Waves.centerX, Waves.centerY, Waves.radius, 0, pi2);
                    ctx.stroke();
                }

                if (Waves.options.background) {
                    Waves.background();
                }

                each(Waves.waves, function (wave, i) {
                    wave.update();
                    wave.draw();
                });
            };

            Waves.prototype.animate = function () {
                let Waves = this;

                Waves.render();

                // if (Waves.options.fps) {
                //   Waves.stats.log();
                //   Waves.ctx.font = '12px Arial';
                //   Waves.ctx.fillStyle = '#fff';
                //   Waves.ctx.fillText(Waves.stats.fps() + ' FPS', 10, 22);
                // }

                window.requestAnimationFrame(Waves.animate.bind(Waves));
            };

            Waves.prototype.clear = function () {
                let Waves = this;
                Waves.ctx.clearRect(0, 0, Waves.width, Waves.height);
            };

            Waves.prototype.background = function () {
                let Waves = this;
                let ctx = Waves.ctx;

                let gradient = Waves.ctx.createLinearGradient(0, 0, 0, Waves.height);
                gradient.addColorStop(0, '#000');
                gradient.addColorStop(1, Waves.color);

                ctx.fillStyle = gradient;
                ctx.fillRect(0, 0, Waves.width, Waves.height);
            };

            Waves.prototype.resize = function () {
                let Waves = this;
                let width = Waves.holder.offsetWidth;
                let height = Waves.holder.offsetHeight;
                Waves.scale = window.devicePixelRatio || 1;
                Waves.width = width * Waves.scale;
                Waves.height = height * Waves.scale;
                Waves.canvas.width = Waves.width;
                Waves.canvas.height = Waves.height;
                Waves.canvas.style.width = width + 'px';
                Waves.canvas.style.height = height + 'px';
                Waves.radius = Math.sqrt(Math.pow(Waves.width, 2) + Math.pow(Waves.height, 2)) / 2;
                Waves.centerX = Waves.width / 2;
                Waves.centerY = Waves.height / 2;
                //Waves.radius /= 2; // REMOVE FOR FULLSREEN
            };

            Waves.prototype.updateColor = function () {
                let Waves = this;

                Waves.hue += (Waves.hueFw) ? 0.01 : -0.01;

                if (Waves.hue > Waves.options.hue[1] && Waves.hueFw) {
                    Waves.hue = Waves.options.hue[1];
                    Waves.Waves = false;
                } else if (Waves.hue < Waves.options.hue[0] && !Waves.hueFw) {
                    Waves.hue = Waves.options.hue[0];
                    Waves.Waves = true;
                }

                let a = Math.floor(127 * Math.sin(0.3 * Waves.hue + 0) + 128);
                let b = Math.floor(127 * Math.sin(0.3 * Waves.hue + 2) + 128);
                let c = Math.floor(127 * Math.sin(0.3 * Waves.hue + 4) + 128);

                Waves.color = 'rgba(' + a + ',' + b + ',' + c + ', 0.1)';
            };

            function Wave(Waves) {
                let Wave = this;
                let speed = Waves.options.speed;

                Wave.Waves = Waves;
                Wave.Lines = [];

                Wave.angle = [
                    rnd(pi2),
                    rnd(pi2),
                    rnd(pi2),
                    rnd(pi2)
                ];

                Wave.speed = [
                    rnd(speed[0], speed[1]) * rnd_sign(),
                    rnd(speed[0], speed[1]) * rnd_sign(),
                    rnd(speed[0], speed[1]) * rnd_sign(),
                    rnd(speed[0], speed[1]) * rnd_sign(),
                ];

                return Wave;
            }

            Wave.prototype.update = function () {
                let Wave = this;
                let Lines = Wave.Lines;
                let color = Wave.Waves.color;

                Lines.push(new Line(Wave, color));

                if (Lines.length > Wave.Waves.options.width) {
                    Lines.shift();
                }
            };

            Wave.prototype.draw = function () {
                let Wave = this;
                let Waves = Wave.Waves;

                let ctx = Waves.ctx;
                let radius = Waves.radius;
                let radius3 = radius / 3;
                let x = Waves.centerX;
                let y = Waves.centerY;
                let rotation = dtr(Waves.options.rotation);
                let amplitude = Waves.options.amplitude;
                let debug = Waves.options.debug;

                let Lines = Wave.Lines;

                each(Lines, function (line, i) {
                    if (debug && i > 0) return;

                    let angle = line.angle;

                    let x1 = x - radius * Math.cos(angle[0] * amplitude + rotation);
                    let y1 = y - radius * Math.sin(angle[0] * amplitude + rotation);
                    let x2 = x + radius * Math.cos(angle[3] * amplitude + rotation);
                    let y2 = y + radius * Math.sin(angle[3] * amplitude + rotation);
                    let cpx1 = x - radius3 * Math.cos(angle[1] * amplitude * 2);
                    let cpy1 = y - radius3 * Math.sin(angle[1] * amplitude * 2);
                    let cpx2 = x + radius3 * Math.cos(angle[2] * amplitude * 2);
                    let cpy2 = y + radius3 * Math.sin(angle[2] * amplitude * 2);

                    ctx.strokeStyle = (debug) ? '#fff' : line.color;

                    ctx.beginPath();
                    ctx.moveTo(x1, y1);
                    ctx.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x2, y2);
                    ctx.stroke();

                    if (debug) {
                        ctx.strokeStyle = '#fff';
                        ctx.globalAlpha = 0.3;

                        ctx.beginPath();
                        ctx.moveTo(x1, y1);
                        ctx.lineTo(cpx1, cpy1);
                        ctx.stroke();
                        ctx.beginPath();
                        ctx.moveTo(x2, y2);
                        ctx.lineTo(cpx2, cpy2);
                        ctx.stroke();

                        ctx.globalAlpha = 1;
                    }
                });
            };

            function Line(Wave, color) {
                let Line = this;

                let angle = Wave.angle;
                let speed = Wave.speed;

                Line.angle = [
                    Math.sin(angle[0] += speed[0]),
                    Math.sin(angle[1] += speed[1]),
                    Math.sin(angle[2] += speed[2]),
                    Math.sin(angle[3] += speed[3])
                ];

                Line.color = color;
            }

            function Stats() {
                this.data = [];
            }

            Stats.prototype.time = function () {
                return (performance || Date)
                    .now();
            };

            Stats.prototype.log = function () {
                if (!this.last) {
                    this.last = this.time();
                    return 0;
                }

                this.new = this.time();
                this.delta = this.new - this.last;
                this.last = this.new;

                this.data.push(this.delta);
                if (this.data.length > 10)
                    this.data.shift();
            };

            Stats.prototype.fps = function () {
                let fps = 0;
                each(this.data, function (data, i) {
                    fps += data;
                });

                return Math.round(1000 / (fps / this.data.length));
            };

            function each(items, callback) {
                for (let i = 0; i < items.length; i++) {
                    callback(items[i], i);
                }
            }

            function extend(options, defaults) {
                for (let key in options)
                    if (defaults.hasOwnProperty(key))
                        defaults[key] = options[key];
                return defaults;
            }

            function dtr(deg) {
                return deg * pi / 180;
            }

            function rtd(rad) {
                return rad * 180 / pi;
            }

            function diagonal_angle(w, h) {
                let a = Math.atan2(h, w) * 1.27325;
                return a;
            }

            function rnd(a, b) {
                if (arguments.length == 1)
                    return Math.random() * a;
                return a + Math.random() * (b - a);
            }

            function rnd_sign() {
                return (Math.random() > 0.5) ? 1 : -1;
            }

        })();

        let waves = new Waves('.login-container ', {
            fps: true,
            waves: 3,
            width: 200,
        });

        waves.animate();
    </script>

</body>

</html>

 😎 蜡烛登录动画

前端:UI 交互式特效 —— Css、Js,前端,css

前端:UI 交互式特效 —— Css、Js,前端,css

<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <title>CSS3可爱卡通蜡烛交互式动画特效</title>

  <style>
    body {
      background: #13b280;
      /* 背景 */
      animation: change-background 5s infinite linear;
    }

    .wrapper {
      position: absolute;
      left: 80%;
      top: 70%;
      transform: scale(1.5, 1.5) translate(-50%, -50%);
    }

    .floor {
      position: absolute;
      left: 50%;
      top: 50%;
      width: 350px;
      height: 5px;
      background: #673C63;
      transform: translate(-50%, -50%);
      box-shadow: 0px 2px 5px #111;
      z-index: 2;
    }

    .candles {
      position: absolute;
      left: 50%;
      top: 50%;
      width: 250px;
      height: 150px;
      transform: translate(-50%, -100%);
      z-index: 1;
    }

    .candle1 {
      position: absolute;
      left: 50%;
      top: 50%;
      width: 35px;
      height: 100px;
      background: #fff;
      border: 3px solid #673C63;
      border-bottom: 0px;
      border-radius: 3px;
      transform-origin: center right;
      transform: translate(60%, -25%);
      box-shadow: -2px 0px 0px #95c6f2 inset;
      /* 高蜡烛向上伸展动画 */
      animation: expand-body 5s infinite linear;
    }

    .candle1__stick,
    .candle2__stick {
      position: absolute;
      left: 50%;
      top: 0%;
      width: 3px;
      height: 15px;
      background: #673C63;
      border-radius: 8px;
      transform: translate(-50%, -100%);
    }

    .candle2__stick {
      height: 12px;
      transform-origin: bottom center;
      /* 蜡烛芯 */
      animation: stick-animation 5s infinite linear;
    }

    .candle1__eyes,
    .candle2__eyes {
      position: absolute;
      left: 50%;
      top: 0%;
      width: 35px;
      height: 30px;
      transform: translate(-50%, 0%);
    }

    .candle1__eyes-one {
      position: absolute;
      left: 30%;
      top: 20%;
      width: 5px;
      height: 5px;
      border-radius: 100%;
      background: #673C63;
      transform: translate(-70%, 0%);
      /* 高蜡烛眼睛 */
      animation: blink-eyes 5s infinite linear;
    }

    .candle1__eyes-two {
      position: absolute;
      left: 70%;
      top: 20%;
      width: 5px;
      height: 5px;
      border-radius: 100%;
      background: #673C63;
      transform: translate(-70%, 0%);
      /* 高蜡烛眼睛 */
      animation: blink-eyes 5s infinite linear;
    }

    .candle1__mouth {
      position: absolute;
      left: 40%;
      top: 20%;
      width: 0px;
      height: 0px;
      border-radius: 20px;
      background: #673C63;
      transform: translate(-50%, -50%);
      /* 高蜡烛嘴吹气 */
      animation: uff 5s infinite linear;
    }

    .candle__smoke-one {
      position: absolute;
      left: 30%;
      top: 50%;
      width: 30px;
      height: 3px;
      background: grey;
      transform: translate(-50%, -50%);
      /* 气体动画 向左*/
      animation: move-left 5s infinite linear;
    }

    .candle__smoke-two {
      position: absolute;
      left: 30%;
      top: 40%;
      width: 10px;
      height: 10px;
      border-radius: 10px;
      background: grey;
      transform: translate(-50%, -50%);
      /* 气体动画 向上 */
      animation: move-top 5s infinite linear;
    }

    .candle2 {
      position: absolute;
      left: 20%;
      top: 65%;
      width: 42px;
      height: 60px;
      background: #fff;
      border: 3px solid #673C63;
      border-bottom: 0px;
      border-radius: 3px;
      transform: translate(60%, -15%);
      transform-origin: center right;
      box-shadow: -2px 0px 0px #95c6f2 inset;
      /* 矮蜡烛 涨红脸 */
      animation: shake-left 5s infinite linear;
    }

    .candle2__eyes-one {
      position: absolute;
      left: 30%;
      top: 50%;
      width: 5px;
      height: 5px;
      display: inline-block;
      border: 0px solid #673C63;
      border-radius: 100%;
      float: left;
      background: #673C63;
      transform: translate(-80%, 0%);
      /* 矮蜡烛 眼睛 */
      animation: changeto-lower 5s infinite linear;
    }

    .candle2__eyes-two {
      position: absolute;
      left: 70%;
      top: 50%;
      width: 5px;
      height: 5px;
      display: inline-block;
      border: 0px solid #673C63;
      border-radius: 100%;
      float: left;
      background: #673C63;
      transform: translate(-80%, 0%);
      /* 矮蜡烛眼睛 */
      animation: changeto-greater 5s infinite linear;
    }

    .light__wave {
      position: absolute;
      top: 35%;
      left: 35%;
      width: 75px;
      height: 75px;
      border-radius: 100%;
      z-index: 0;
      transform: translate(-25%, -50%) scale(2.5, 2.5);
      border: 2px solid rgba(255, 255, 255, 0.2);
      /* 高蜡烛 向上伸张 */
      animation: expand-light 5s infinite linear;
    }

    .candle2__fire {
      position: absolute;
      top: 50%;
      left: 40%;
      display: block;
      width: 16px;
      height: 20px;
      background-color: red;
      border-radius: 50% 50% 50% 50% / 60% 60% 40% 40%;
      background: #FF9800;
      transform: translate(-50%, -50%);
      /* 火焰 */
      animation: dance-fire 5s infinite linear;
    }

    @keyframes blink-eyes {

      0%,
      35% {
        opacity: 1;
        transform: translate(-70%, 0%);
      }

      36%,
      39% {
        opacity: 0;
        transform: translate(-70%, 0%);
      }

      40% {
        opacity: 1;
        transform: translate(-70%, 0%);
      }

      50%,
      65% {
        transform: translate(-140%, 0%);
      }

      66% {
        transform: translate(-70%, 0%);
      }
    }

    @keyframes expand-body {

      0%,
      40% {
        transform: scale(1, 1) translate(60%, -25%);
      }

      45%,
      55% {
        transform: scale(1.1, 1.1) translate(60%, -28%);
      }

      60% {
        transform: scale(0.89, 0.89) translate(60%, -25%);
      }

      65% {
        transform: scale(1, 1) translate(60%, -25%);
      }

      70% {
        transform: scale(0.95, 0.95) translate(60%, -25%);
      }

      75% {
        transform: scale(1, 1) translate(60%, -25%);
      }
    }

    @keyframes uff {

      0%,
      40% {
        width: 0px;
        height: 0px;
      }

      50%,
      54% {
        width: 15px;
        height: 15px;
        left: 30%;
      }

      59% {
        width: 5px;
        height: 5px;
        left: 20%;
      }

      62% {
        width: 2px;
        height: 2px;
        left: 20%;
      }

      67% {
        width: 0px;
        height: 0px;
        left: 30%;
      }
    }

    @keyframes change-background {

      0%,
      59%,
      98%,
      100% {
        background: #13b280;
      }

      61%,
      97% {
        background: #F8AE39;
      }
    }

    @keyframes move-left {

      0%,
      59%,
      100% {
        width: 0px;
        left: 40%;
      }

      60% {
        width: 30px;
        left: 30%;
      }

      68% {
        width: 0px;
        left: 20%;
      }
    }

    @keyframes move-top {

      0%,
      64%,
      100% {
        width: 0px;
        height: 0px;
        top: 0%;
      }

      65% {
        width: 10px;
        height: 10px;
        top: 40%;
        left: 40%;
      }

      80% {
        width: 0px;
        height: 0px;
        top: 20%;
      }
    }

    @keyframes shake-left {

      0%,
      40% {
        left: 20%;
        transform: translate(60%, -15%);
      }

      50%,
      54% {
        left: 20%;
        transform: translate(60%, -15%);
      }

      59% {
        left: 20%;
        transform: translate(60%, -15%);
      }

      62% {
        left: 18%;
        transform: translate(60%, -15%);
      }

      65% {
        left: 21%;
        transform: translate(60%, -15%);
      }

      67% {
        left: 20%;
        transform: translate(60%, -15%);
      }

      75% {
        left: 20%;
        transform: scale(1.15, 0.85) translate(60%, -15%);
        background: #fff;
        border-color: #673C63;
      }

      91% {
        left: 20%;
        transform: scale(1.18, 0.82) translate(60%, -10%);
        background: #F44336;
        border-color: #F44336;
        box-shadow: -2px 0px 0px #F44336 inset;
      }

      92% {
        left: 20%;
        transform: scale(0.85, 1.15) translate(60%, -15%);
      }

      95% {
        left: 20%;
        transform: scale(1.05, 0.95) translate(60%, -15%);
      }

      97% {
        left: 20%;
        transform: scale(1, 1) translate(60%, -15%);
      }
    }

    @keyframes stick-animation {

      0%,
      40% {
        left: 50%;
        top: 0%;
        transform: translate(-50%, -100%);
      }

      50%,
      54% {
        left: 50%;
        top: 0%;
        transform: translate(-50%, -100%);
      }

      59% {
        left: 50%;
        top: 0%;
        transform: translate(-50%, -100%);
      }

      62% {
        left: 50%;
        top: 0%;
        transform: rotateZ(-15deg) translate(-50%, -100%);
      }

      65% {
        left: 50%;
        top: 0%;
        transform: rotateZ(15deg) translate(-50%, -100%);
      }

      70% {
        left: 50%;
        top: 0%;
        transform: rotateZ(-5deg) translate(-50%, -100%);
      }

      72% {
        left: 50%;
        top: 0%;
        transform: rotateZ(5deg) translate(-50%, -100%);
      }

      74%,
      84% {
        left: 50%;
        top: 0%;
        transform: rotateZ(0deg) translate(-50%, -100%);
      }

      85% {
        transform: rotateZ(180deg) translate(0%, 120%);
      }

      92% {
        left: 50%;
        top: 0%;
        transform: translate(-50%, -100%);
      }
    }

    @keyframes expand-light {

      10%,
      29%,
      59%,
      89% {
        transform: translate(-25%, -50%) scale(0, 0);
        border: 2px solid rgba(255, 255, 255, 0);
      }

      90%,
      20%,
      50% {
        transform: translate(-25%, -50%) scale(1, 1);
      }

      95%,
      96%,
      26%,
      27%,
      56%,
      57% {
        transform: translate(-25%, -50%) scale(2, 2);
        border: 2px solid rgba(255, 255, 255, 0.5);
      }

      0%,
      28%,
      58%,
      100% {
        transform: translate(-25%, -50%) scale(2.5, 2.5);
        border: 2px solid rgba(255, 255, 255, 0.2);
      }
    }

    @keyframes dance-fire {

      59%,
      89% {
        left: 40%;
        width: 0px;
        height: 0px;
      }

      90%,
      0%,
      7%,
      15%,
      23%,
      31%,
      39%,
      47%,
      55% {
        left: 40.8%;
        width: 16px;
        height: 20px;
        background: #FFC107;
      }

      94%,
      3%,
      11%,
      19%,
      27%,
      35%,
      43%,
      51%,
      58% {
        left: 41.2%;
        width: 16px;
        height: 20px;
        background: #FF9800;
      }
    }

    @keyframes changeto-lower {

      0%,
      70%,
      90% {
        padding: 0px;
        display: inline-block;
        border-radius: 100%;
        background: #673C63;
        border-width: 0 0 0 0;
        border: 0px solid #673C63;
        transform: translate(-90%, 0%);
      }

      71%,
      89% {
        background: none;
        border: solid #673C63;
        border-radius: 0px;
        border-width: 0 2px 2px 0;
        display: inline-block;
        padding: 1px;
        float: left;
        transform-origin: bottom left;
        transform: rotate(-45deg) translate(-50%, -65%);
        -webkit-transform: rotate(-45deg) translate(-50%, -65%);
      }
    }

    @keyframes changeto-greater {

      0%,
      70%,
      90% {
        top: 50%;
        padding: 0px;
        display: inline-block;
        border-radius: 100%;
        background: #673C63;
        border-width: 0 0 0 0;
        border: 0px solid #673C63;
        transform: translate(-80%, 0%);
      }

      71%,
      89% {
        top: 30%;
        background: none;
        border: solid #673C63;
        border-radius: 0px;
        border-width: 0 2px 2px 0;
        display: inline-block;
        padding: 1px;
        float: left;
        transform-origin: bottom left;
        transform: rotate(135deg) translate(-80%, 20%);
        -webkit-transform: rotate(135deg) translate(-80%, 20%);
      }
    }
  </style>

</head>

<body>
  <div class="wrapper">
    <div class="candles">
      <div class="light__wave"></div>
      <div class="candle1">
        <div class="candle1__body">
          <div class="candle1__eyes">
            <span class="candle1__eyes-one"></span>
            <span class="candle1__eyes-two"></span>
          </div>
          <div class="candle1__mouth"></div>
        </div>
        <div class="candle1__stick"></div>
      </div>

      <div class="candle2">
        <div class="candle2__body">
          <div class="candle2__eyes">
            <div class="candle2__eyes-one"></div>
            <div class="candle2__eyes-two"></div>
          </div>
        </div>
        <div class="candle2__stick"></div>
      </div>
      <div class="candle2__fire"></div>
      <div class="sparkles-one"></div>
      <div class="sparkles-two"></div>
      <div class="candle__smoke-one">

      </div>
      <div class="candle__smoke-two">

      </div>

    </div>

    <div class="floor">
    </div>

  </div>


</body>

</html>

🥵 火箭 

前端:UI 交互式特效 —— Css、Js,前端,css

源码仓库在后面,文件比较多,会影响阅读,

😶‍🌫️ 时间翻盘

前端:UI 交互式特效 —— Css、Js,前端,css

 原生js、vue版本,请移步仓库里

🤺 复选框动画

前端:UI 交互式特效 —— Css、Js,前端,css

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>CSS3 SVG点击复选框勾选动画特效</title>

<style>
@import url("https://fonts.googleapis.com/css?family=Exo");
html {
  font-size: 100%;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  background-color: #00acc1;
  font-family: 'Exo', sans-serif;
}

input[type="checkbox"] {
  display: none;
}
input[type="checkbox"] + .label {
  position: relative;
  padding-left: 1.7em;
  color: #ffffff;
  font-size: 3.125rem;
  cursor: pointer;
}
input[type="checkbox"] + .label::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 1em;
  height: 1em;
  border: 3px solid #ffffff;
  border-radius: 0.1em;
}
input[type="checkbox"] + .label::after {
  content: '';
  position: absolute;
  top: 0.1em;
  left: 0.1em;
  width: 0.92em;
  height: 0.92em;
  transform: scale(0);
  background-color: #ffffff;
  border-radius: 0.02em;
  transition: all 0.2s linear;
  opacity: 0;
}
input[type="checkbox"] + .label svg {
  position: absolute;
  top: 0.2em;
  left: 0.12em;
  z-index: 1;
}
input[type="checkbox"] + .label #check-icon {
  stroke: #00acc1;
  stroke-dasharray: 36;
  stroke-dashoffset: 36;
}
input[type="checkbox"]:checked + .label::after {
  transform: scale(1);
  opacity: 1;
}
input[type="checkbox"]:checked + .label #check-icon {
  animation-name: check-animation;
  animation-duration: 0.2s;
  animation-delay: 0.4s;
  animation-fill-mode: forwards;
  animation-timing-function: cubic-bezier(1, 0.12, 0.96, 0.62);
}

@keyframes check-animation {
  0% {
    stroke-dashoffset: 36;
  }
  100% {
    stroke-dashoffset: 0;
  }
}
</style>

</head>
<body>

<input type="checkbox" id="check-me">

<label for="check-me" class="label">
	Check Me!
	<svg viewBox="-9 -9 43 35.191" width="43" height="35">
    	<path id="check-icon" d=" M 0 9 Q 8 17 8 17 Q 8 17 25 0" fill="none" stroke-width="6" stroke="rgb(0,0,0)" stroke-linecap="round" />
    </svg>
</label>

</body>
</html>

🤪 基础表单输入动画

前端:UI 交互式特效 —— Css、Js,前端,css

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>form input动画</title>
    <style>
        input[type='text'],
        input[type='password'] {
            height: 40px;
            width: 200px;
            background: transparent;
            border: none;
            border-bottom: 1px solid #999;
            text-indent: 20px;
            transition: 0.3;
            outline: none;
        }

        input[type='text']:hover,
        input[type='password']:hover {
            border-color: #42b983;
        }

        input[type='text']:focus,
        input[type='password']:focus {
            border-bottom-color: #f1190d;
        }

        input[type='password']::-webkit-input-placeholder,
        input[type='text']::-webkit-input-placeholder {
            transition: 0.5s;
            font-size: 14px;
            transform-origin: top left;
        }

        input[type='password']:focus::-webkit-input-placeholder,
        input[type='text']:focus::-webkit-input-placeholder {
            transform: scale(0.8) translateY(-10px);
        }
    </style>
</head>

<body>
    <input type="text" placeholder="请输入您的姓名" />
    <input type="password" placeholder="请输入您的密码" />
</body>

</html>

😃 卡包动画

前端:UI 交互式特效 —— Css、Js,前端,css

<template>
	<div>
		<div class="tariffCards">
			<div class="economy">
				<img
					src="https://creditcard.ecitic.com/2019_gw/images/g-logo.png"
					alt="中信银行"
					height="74"
				/>
				<h3>中信银行</h3>
				<span>zhongxin bank</span>
			</div>
			<div class="premiumeconomy">
				<img
					src="https://www.bankofchina.com/images/boc2013_logo.png"
					alt="中国银行"
					height="30"
				/>
				<h3>中国银行</h3>
				<span>chinease bank</span>
			</div>
			<div class="business">
				<img
					src="http://www.jsbchina.cn/data/tosend/resource/upload/20201127/f97a668d-3cce-435c-8cb5-ca4e69b86aec.jpg"
					alt="交通银行"
					height="74"
				/>
				<h3>交通银行</h3>
				<span>jiaotong bank</span>
			</div>
			<div class="first">
				<img
					src="http://www.jsbchina.cn/CN/index.html"
					alt="江苏银行"
					height="74"
				/>
				<h3>江苏银行</h3>
				<span>jiangsu bank</span>
			</div>
		</div>
	</div>
</template>

<style scoped>
.tariffCards {
	position: absolute;
	top: 50%;
	left: 50%;
	margin: -180px 0 0 -140px;
	user-select: none;
	transform: translate3d(0, 0, 0);
	transform-style: preserve-3d;
}
.tariffCards:after {
	position: absolute;
	bottom: -27px;
	left: 5%;
	content: '';
	width: 65%;
	height: 10px;
	border-radius: 100%;
	background-image: radial-gradient(
		rgba(34, 50, 84, 0.04),
		rgba(34, 50, 84, 0)
	);
}
.tariffCards > div {
	position: relative;
	width: 280px;
	height: 140px;
	border-radius: 12px;
	color: white;
	transform: rotateX(45deg) rotateY(-15deg) rotate(45deg);
	transition: all 0.4s ease;
	overflow: hidden;
	cursor: pointer;
}
.tariffCards > div:after {
	position: absolute;
	top: -70px;
	left: 0;
	content: '';
	width: 200%;
	height: 200%;
	background-image: linear-gradient(
		60deg,
		rgba(255, 255, 255, 0) 20%,
		rgba(255, 255, 255, 0.1),
		rgba(255, 255, 255, 0) 80%
	);
	transform: translateX(-100%);
}
.tariffCards > div img {
	margin-top: 15px;
	pointer-events: none;
}
.tariffCards > div h3 {
	position: absolute;
	bottom: 28px;
	left: 15px;
	font-size: 18px;
	font-weight: 800;
}
.tariffCards > div span {
	position: absolute;
	font-weight: 700;
	bottom: 15px;
	left: 15px;
	font-size: 12px;
	font-weight: 600;
	opacity: 0.8;
}
.tariffCards > div.economy {
	margin-top: 0;
	z-index: 3;
	background-color: #8063e1;
	background-image: linear-gradient(135deg, #bd7be8, #8063e1);
	box-shadow: 20px 20px 60px rgba(34, 50, 84, 0.5), 1px 1px 0px 1px #8063e1;
}
.tariffCards > div.premiumeconomy {
	margin-top: -70px;
	z-index: 2;
	background-color: #3f58e3;
	background-image: linear-gradient(135deg, #7f94fc, #3f58e3);
	box-shadow: 20px 20px 60px rgba(34, 50, 84, 0.5), 1px 1px 0px 1px #3f58e3;
}
.tariffCards > div.business {
	margin-top: -70px;
	z-index: 1;
	background-color: #2c6fd1;
	background-image: linear-gradient(135deg, #21bbfe, #2c6fd1);
	box-shadow: 20px 20px 60px rgba(34, 50, 84, 0.5), 1px 1px 0px 1px #2c6fd1;
}
.tariffCards > div.first {
	margin-top: -70px;
	background-color: #352f64;
	background-image: linear-gradient(135deg, #415197, #352f64);
	box-shadow: 5px 5px 60px rgba(34, 50, 84, 0.1), 1px 1px 0px 1px #352f64;
}
.tariffCards > div:hover {
	transform: rotateX(30deg) rotateY(-15deg) rotate(30deg) translate(-25px, 50px);
}
.tariffCards > div:hover:after {
	transform: translateX(100%);
	transition: all 1.2s ease-in-out;
}
</style>

😷 流光扫过动画

前端:UI 交互式特效 —— Css、Js,前端,css

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .flash-container {
            width: 148px;
            height: 148px;
            background: #333333;
            margin: 0 auto;
            position: relative;
            overflow: hidden;

            &::after {
                content: '';
                height: 150%;
                width: 25px;
                background: #fff;
                position: absolute;
                left: 0;
                right: 0;
                top: 0;
                bottom: 0;
                margin: auto;
                opacity: 0.6;
                filter: blur(6px);
                animation: move 2s infinite ease-out;
            }
        }

        @keyframes move {
            0% {
                transform: translate(-200px, -200px) rotate(45deg);
            }

            100% {
                transform: translate(200px, 200px) rotate(45deg);
            }
        }
    </style>
</head>

<body>
    <div class="flash-container">
        <img src="https://img-blog.csdnimg.cn/180fbfb5f0434211b3e8640891ecea33.gif" alt />
    </div>
</body>

</html>

🥶 酷炫标题

前端:UI 交互式特效 —— Css、Js,前端,css

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .wrap {
            position: relative;
            display: inline-block;
            left: 50%;
            top: 20px;
        }

        .wrap span {
            position: relative;
            z-index: 2;
            display: inline-block;
            padding: 0 15px;
            height: 32px;
            line-height: 32px;
            background-color: #42b983;
            color: #fff;
            font-size: 16px;
            box-shadow: 0 10px 6px -9px rgba(0, 0, 0, 0.6);
        }

        .wrap span::before,
        .wrap span::after {
            position: absolute;
            bottom: -6px;
            border-width: 3px 5px;
            border-style: solid;
            content: '';
        }

        .wrap span::before {
            left: 0;
            border-color: #42b983 #42b983 transparent transparent;
        }

        .wrap span::after {
            right: 0;
            border-color: #42b983 transparent transparent #42b983;
        }

        .wrap::before,
        .wrap::after {
            position: absolute;
            top: 6px;
            content: '';
            border-style: solid;
            border-color: #42b983;
        }

        .wrap::before {
            left: -32px;
            border-width: 16px 26px 16px 16px;
            border-left-color: transparent;
        }

        .wrap::after {
            right: -32px;
            border-width: 16px 16px 16px 26px;
            border-right-color: transparent;
        }
    </style>
</head>

<body>
    <div class="wrap">
        <span>距离高考还有10天</span>
    </div>
</body>

</html>

前端:UI 交互式特效 —— Css、Js,前端,css

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            padding: 20px;
        }

        .wrap {
            position: relative;
            background-color: pink;
            height: 200px;
            /* width: 500px;
            margin: 0 auto; */
        }

        .left {
            width: 200px;
            height: 140px;
            position: absolute;
            top: -8px;
            left: -8px;
            overflow: hidden;
        }

        .left::before {
            position: absolute;
            left: 124px;
            border-radius: 8px 8px 0 0;
            width: 16px;
            height: 8px;
            background-color: #42b983;
            content: '';
        }

        .left::after {
            position: absolute;
            left: 0;
            top: 124px;
            border-radius: 0 8px 8px 0;
            width: 8px;
            height: 16px;
            background-color: #42b983;
            content: '';
        }

        .left span {
            display: inline-block;
            text-align: center;
            width: 200px;
            height: 40px;
            line-height: 40px;
            position: absolute;
            top: 30px;
            left: -50px;
            z-index: 2;
            overflow: hidden;
            -ms-transform: rotate(-45deg);
            -moz-transform: rotate(-45deg);
            -webkit-transform: rotate(-45deg);
            -o-transform: rotate(-45deg);
            transform: rotate(-45deg);
            border: 1px dashed #fff;
            box-shadow: 0 0 0 3px #42b983, 0 14px 7px -9px rgba(0, 0, 0, 0.6);
            background-color: #42b983;
            color: #fff;
        }

        .right {
            width: 140px;
            height: 200px;
            position: absolute;
            top: -8px;
            right: -8px;
            overflow: hidden;
        }

        .right::before {
            position: absolute;
            right: 124px;
            border-radius: 8px 8px 0 0;
            width: 16px;
            height: 8px;
            background-color: #42b983;
            content: '';
        }

        .right::after {
            position: absolute;
            right: 0;
            top: 124px;
            border-radius: 0 8px 8px 0;
            width: 8px;
            height: 16px;
            background-color: #42b983;
            content: '';
        }

        .right span {
            display: inline-block;
            text-align: center;
            width: 200px;
            height: 40px;
            line-height: 40px;
            position: absolute;
            top: 30px;
            right: -50px;
            z-index: 2;
            overflow: hidden;
            -ms-transform: rotate(45deg);
            -moz-transform: rotate(45deg);
            -webkit-transform: rotate(45deg);
            -o-transform: rotate(45deg);
            transform: rotate(45deg);
            border: 1px dashed #fff;
            box-shadow: 0 0 0 3px #42b983, 0 14px 7px -9px rgba(0, 0, 0, 0.6);
            background-color: #42b983;
            color: #fff;
        }
    </style>
</head>

<body>
    <div class="wrap">
        <div class="left">
            <span>张</span>
        </div>
        <div class="right">
            <span>坤</span>
        </div>
    </div>


</body>

</html>

🤖 交互式评分

前端:UI 交互式特效 —— Css、Js,前端,css

 文件较多、参考仓库

🐔 动态向上箭头

前端:UI 交互式特效 —— Css、Js,前端,css

 🐽 卸载对话框表情交互动画

前端:UI 交互式特效 —— Css、Js,前端,css

 ✈️ 随机密码生成器代码

前端:UI 交互式特效 —— Css、Js,前端,css

 下面是功能篇章

🧨 跟随设备切换主题

index.html

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>切换主题 dark、light、system</title>


    <style>
        /* dark 主题  */
        [data-theme="dark"] {
            --text-color: white;
            --background-color: black;
        }

        /* light 主题  */
        [data-theme="light"] {
            --text-color: black;
            --background-color: white;
        }

        body {
            color: var(--text-color);
            background-color: var(--background-color);
        }
    </style>
</head>

<body>
    <h1>跟随设备切换主题</h1>
    <p>这是一段测试文本。</p>
    <img src="https://www4.bing.com//th?id=OHR.GoliathHeron_ZH-CN2413747227_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp&w=360&h=202"
        alt="">
    <!-- 下拉框 -->
    <select id="select-wrap" title="切换主题">
        <option value="light">light</option>
        <option value="dark">dark</option>
        <option value="system">system</option>
    </select>

    <script>
        const selectWrap = document.querySelector('#select-wrap');
        const bodyTheme = document.querySelector('body');

        window.onload = () => {
            // 获取用户的选择
            const theme = localStorage.getItem('theme');
            // 如果用户选择了主题,就设置主题同时改变下拉框的选中项
            if (theme) {
                // 设置下拉框的选中项
                selectWrap.value = theme;
                // 动态设置 system 主题
                setTheme()
            }
        }

        // 监听下拉框的变化
        selectWrap.onchange = () => {
            setTheme()
            localStorage.setItem('theme', selectWrap.value);
        }

        // 动态设置 system 主题 函数
        function setTheme() {
            /* 
            下拉框改变时,先移除 system 主题,因为dark、light主题不需要使用系统主题,
            系统主题只需要在下拉框选择 system 时才需要使用,动态添加,解决系统切换主题时,项目不需要刷新
            */
            removeSystemLink()
            if (selectWrap.value === 'system') {
                setTimeout(() => {
                    const link = document.createElement('link');
                    link.rel = 'stylesheet';
                    link.href = './system.css';
                    // 加上名称方便找到移除
                    link.id = 'system';
                    // 在head中插入link 添加到最后
                    document.head.appendChild(link);
                }, 0);
                // 在某个元素前面插入一个元素 语法:parentElement.insertBefore(newElement, targetElement)
                // parentElement是要插入新元素的父元素,newElement是要插入的新元素对象,targetElement是当前元素的前一个兄弟元素,也就是新元素要插入到这个元素之前。
                // 例子:在head中插入link 添加到最前面
                //       document.head.insertBefore(link, document.head.firstChild); 
                //       document.head.insertBefore(link, document.head.children[0]);  

                // 或者:document.head.insertBefore(link, document.head.lastChild); // 在head中插入link 添加到最后面
                // 或者:document.head.insertBefore(link, document.querySelector('title')); // 在head中插入link 添加到title前面
            } else {
                // 动态设置 light 和 dark 主题
                bodyTheme.setAttribute('data-theme', selectWrap.value);
            }
        }

        /* 
        移除 system 主题 函数:
        有时候切换系统主题了,项目还要刷新一下:
        因为系统主题的切换需要重新加载样式表才能生效,但有时候页面中的部分元素已经渲染出来,
        样式表被加载后并不会自动刷新渲染结果。在这种情况下,动态移除和添加样式表就能解决这个问题。
        */
        function removeSystemLink() {
            const link = document.querySelector('#system');
            if (link) link.remove();
        }
    </script>
</body>

</html>

 system.css

:root {
  --text-color: black;
  --background-color: white;
}

@media (prefers-color-scheme: dark) {
  :root {
    --text-color: white;
    --background-color: black;
  }
}

body {
  color: var(--text-color);
  background-color: var(--background-color);
}

🚒 昼夜切换主题

前端:UI 交互式特效 —— Css、Js,前端,css

 ❤️‍🩹 使用系统取色器

<!DOCTYPE html>
<html>
<head>
  <title>使用系统取色器</title>
  <style>
    .box {
      width: 200px;
      height: 200px;
      border: 1px solid black;
    }
  </style>
</head>
<body>
  <button>打开取色器</button>
  <div class="box"></div>
  <br>
  <label></label>

  <script>
    const btn = document.querySelector('button');
    const box = document.querySelector('.box');
    const label = document.querySelector('label');

    btn.onclick = async () => {
      const dropper = new EyeDropper();

      try {
        const result = await dropper.open();
        console.log(result);
        box.style.backgroundColor = result.sRGBHex;
        label.textContent = result.sRGBHex;
      } catch {
        console.log('用户取消了操作');
      }
    }
  </script>
</body>
</html>

😃 右键动态菜单(已做边缘动画及边界外判断)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>右键菜单</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #context-menu {
            position: fixed;
            width: 300px;
            height: 400px;
            background-image: linear-gradient(235deg, #f7f0ac, #acf7f0, #f0acf7);
            transition: all 0.3s ease-in-out;
            border-radius: 5px;
            /* 使用  display: none; 会造成边界判断失败 */
            visibility: hidden;
            opacity: 0;
            z-index: 9999;

        }

        .menu-item {
            padding: 10px;
            cursor: pointer;
        }

        .menu-item:hover {
            background-color: #d6d6d6;
        }

        .rebound {
            animation: rebound .5s;
        }

        @keyframes rebound {
            0% {
                transform: translate(-100%, 0);
                opacity: 0;
            }

            40% {
                transform: translate(10%, 0);
            }

            70% {
                transform: translate(-5%, 0);
            }

            100% {
                transform: translate(0);
                opacity: 1;
            }
        }
    </style>
</head>

<body>


    <div id="context-menu">
        <div class="menu-item">菜单项1</div>
        <div class="menu-item">菜单项2</div>
        <div class="menu-item">菜单项3</div>
    </div>

    <script>
        const contextMenu = document.getElementById('context-menu');

        function setPosition(event, menu) {
            // 获取窗口宽度和高度
            const screenWidth = window.innerWidth;
            const screenHeight = window.innerHeight;
            // 获取菜单宽度和高度
            const menuWidth = menu.offsetWidth;
            const menuHeight = menu.offsetHeight;
            // 获取鼠标在页面中的位置
            const x = event.clientX;
            const y = event.clientY;
            // 计算菜单的调整后的水平位置和垂直位置
            const adjustedX = (x + menuWidth) >= screenWidth ? (x - menuWidth) : x; // 检查是否超出右侧边界
            const adjustedY = (y + menuHeight) >= screenHeight ? (y - menuHeight) : y; // 检查是否超出底部边界
            // 如果超出右侧边界,让菜单反弹一下
            if (adjustedX !== x) {
                menu.classList.add('rebound');
                setTimeout(() => {
                    menu.classList.remove('rebound');
                }, 1000);
            }
            // 设置菜单的位置
            menu.style.left = adjustedX + 'px';
            menu.style.top = adjustedY + 'px';
        }

        document.addEventListener('contextmenu', function (event) {
            event.preventDefault(); // 阻止系统默认的右键菜单
            setPosition(event, contextMenu); // 计算并设置菜单的位置
            contextMenu.style.visibility = 'visible'; // 显示菜单
            contextMenu.style.opacity = '1';
        });

        // 如果点击的地方不在菜单内,隐藏菜单
        document.addEventListener('click', function (event) {
            console.log(event.target);
            console.log(contextMenu);
            if (contextMenu !== event.target) {
                contextMenu.style.visibility = 'hidden';
                contextMenu.style.opacity = '0';
            }
        });


        const menuItems = document.querySelectorAll('.menu-item');
        // 为每个菜单项添加事件监听 不优化
        // for (let i = 0; i < menuItems.length; i++) {
        //     menuItems[i].addEventListener('click', function (event) {
        //         console.log(`您点击了菜单项${i + 1}`);
        //                     contextMenu.style.visibility = 'visible';

        //     });
        //     menuItems[i].addEventListener('mousedown', function (event) {
        //         event.stopPropagation();
        //     });
        // }

        // 使用事件委托 优化
        contextMenu.addEventListener('click', function (event) {
            const target = event.target;
            if (target.classList.contains('menu-item')) {
                // indexOf() 返回指定元素在目标队列中首次出现的索引,找不到指定元素,则会返回 -1。
                // call 第一个参数是指定该方法执行时的上下文环境(写谁指向谁),第二个参数,它表示要传递给被调用的方法的参数。
                const index = Array.prototype.indexOf.call(menuItems, target);
                console.log(`您点击了菜单项${index + 1}`);
            }
        });
    </script>

</body>

</html>

🎋 酷炫打字特效

前端:UI 交互式特效 —— Css、Js,前端,css

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>删库跑路</title>
    <style>
      * {
        margin: 0;
        padding: 0;
        border: 0;
        font-size: 100%;
        font: inherit;
        vertical-align: baseline;
        box-sizing: border-box;
        color: inherit;
      }

      body {
        background-image: linear-gradient(120deg, #4f0088 0%, #000 100%);
        height: 100vh;
      }

      div {
        background: rgba(0, 0, 0, 0);
        width: 70vw;
        position: relative;
        top: 50%;
        -webkit-transform: translateY(-50%);
        transform: translateY(-50%);
        margin: 0 auto;
        padding: 30px 30px 10px;
        box-shadow: 0 0 150px -20px rgba(0, 0, 0, 0.5);
        z-index: 3;
      }

      P {
        font-family: "Share Tech Mono", monospace;
        color: #f5f5f5;
        margin: 0 0 20px;
        font-size: 17px;
        line-height: 1.2;
      }

      span {
        color: #f0c674;
      }

      i {
        color: #8abeb7;
      }

      div a {
        text-decoration: none;
      }

      b {
        color: #81a2be;
      }

      a.avatar {
        position: fixed;
        bottom: 15px;
        right: -100px;
        -webkit-animation: slide 0.5s 4.5s forwards;
        animation: slide 0.5s 4.5s forwards;
        display: block;
        z-index: 4;
      }

      a.avatar img {
        border-radius: 100%;
        width: 44px;
        border: 2px solid white;
      }

      @-webkit-keyframes slide {
        from {
          right: -100px;
          -webkit-transform: rotate(360deg);
          transform: rotate(360deg);
          opacity: 0;
        }

        to {
          right: 15px;
          -webkit-transform: rotate(0deg);
          transform: rotate(0deg);
          opacity: 1;
        }
      }

      @keyframes slide {
        from {
          right: -100px;
          -webkit-transform: rotate(360deg);
          transform: rotate(360deg);
          opacity: 0;
        }

        to {
          right: 15px;
          -webkit-transform: rotate(0deg);
          transform: rotate(0deg);
          opacity: 1;
        }
      }
    </style>
  </head>

  <body>
    <div id="container">
      <p>
        >
        <span> [root@VM-0-7-centos ~]# </span>
        : "
        <i> rm -rf /*正在删除本地的数据 </i>
        "
      </p>

      <p>
        >
        <span> [root@VM-0-7-centos ~]# </span>
        : "
        <i> 删除成功 </i>
        "
      </p>

      <p>
        >
        <span> [root@VM-0-7-centos ~]# </span>
        : "
        <i> 文件备份自动启用中... </i>
        "
      </p>

      <p>
        >
        <span> [root@VM-0-7-centos ~]# </span>
        : "
        <i> 备份失败! 仅备份文件碎片... </i>
        "
      </p>

      <p>
        >
        <span> [root@VM-0-7-centos ~]# </span>
        : "
        <i> 文件碎片正在加载... </i>
        "
      </p>

      <p>
        >
        <span> [root@VM-0-7-centos ~]# </span>
        : "
        <i> 加载失败 对不起我们跑路了... </i>
        "
      </p>

      <p>
        >
        <span> [root@VM-0-7-centos ~]# </span>
        : "
        <i> 不要伤心 不要难过... </i>
        "
      </p>

      <p>
        >
        <span> [root@VM-0-7-centos ~]# </span>
        : "
        <i> 或许我们还会再建个站继续骗你 ... </i>
        "
      </p>

    </div>

    <script>
      // 将元素内容转换为字符串
      let str = document.querySelector("#container").innerHTML.toString();
      let i = 0;
      let containerHtml = document.querySelector("#container");
      containerHtml.innerHTML = "";
      setTimeout(function () {
        let se = setInterval(function () {
          i++;
        //   str.slice(start, end) 表示从 str 字符串的 start 索引处开始,提取到 end 索引处之前(不包含 end)的子串。如果不指定 end 参数,则默认提取到字符串末尾。
          containerHtml.innerHTML = str.slice(0, i) + "|";
          if (i == str.length) {
            clearInterval(se);
            containerHtml.innerHTML = str;
          }
        }, 30);
      }, 0);
    </script>
  </body>
</html>

🚆 方形抽奖

前端:UI 交互式特效 —— Css、Js,前端,css

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>转盘</title>
    <style>
      .main {
        display: flex;
        width: 320px;
        flex-wrap: wrap;
      }
      .item {
        width: 100px;
        height: 100px;
        background-color: #ddd;
        display: flex;
        align-items: center;
        justify-content: center;
        border: 2px solid #fff;
      }
      .item.active {
        background-color: #999;
      }
      .item.btn {
        background-color: green;
        color: #fff;
      }
    </style>
  </head>
  <body>
    <div class="main"></div>

    <script>
      window.onload = () => {
        const data = {
          jp: [
            { name: "代金券1" },
            { name: "代金券2", is: true },
            { name: "代金券3" },
            { name: "代金券4" },
            { name: "代金券5" },
            { name: "代金券6" },
            { name: "代金券7" },
            { name: "代金券8" },
          ],
        };

        const main = document.querySelector(".main");
        main.innerHTML = data.jp
          .map(
            (v) =>
              `<div class="item" ${v.is ? "is='true'" : ""}>${v.name}</div>`
          )
          .join("");

        const btnEl = document.createElement("div");
        btnEl.className = "item btn";
        btnEl.innerHTML = "抽奖";

        main.insertBefore(btnEl, main.children[4]);

        let isRunning = false;
        let itemIndex = 0;

        const spinWheel = () => {
          const nodesList = [...main.childNodes].filter(
            (v) => !v.classList.contains("btn")
          );
          const spinOrder = [0, 1, 2, 4, 7, 6, 5, 3];
          const spinItems = spinOrder.map((v) => nodesList[v]);

          if (!spinItems[itemIndex]) {
            itemIndex = 0;
          }

          const active1 = main.querySelector(".active");
          active1 && active1.classList.remove("active");

          spinItems[itemIndex].classList.add("active");

          if (!isRunning && spinItems[itemIndex].getAttribute("is")) {
            clearInterval(intervalId);
          }

          itemIndex++;
        };

        let intervalId;
        btnEl.onclick = () => {
          if (isRunning) return;

          isRunning = true;
          intervalId = setInterval(spinWheel, 100);

          setTimeout(() => {
            isRunning = false;
          }, 3000);
        };
      };
    </script>
  </body>
</html>

🚼 圆形抽奖

前端:UI 交互式特效 —— Css、Js,前端,css


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>转盘</title>
<style>
    .zp {
        position: relative;
        border-radius: 100%;
        width: 300px;
        overflow: hidden;
        margin:0 auto;
    }
    .zp-panel {
        background: url(./images/zp.webp) no-repeat center center;
        background-size: 100%;
        width: 300px;
        height: 300px;
        position: relative;
        transition: transform 4s ease-out;
        
    }
    .item {
        font-size: 12px;
        position: absolute;
        top: 50%;
        left: 0;
        right: 0;
        text-align: center;
        margin-top: -7px;
        line-height: 1;
    }
    .btn {
        position: absolute;
        background-color: green;
        width: 80px;
        height: 80px;
        border-radius: 100%;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        z-index: 2;
        display: flex;
        align-items: center;
        justify-content: center;
        color: #fff;
    }
    .btn:after {
        content: '';
        position: absolute;
        height: 80px;
        width: 4px;
        background-color: green;
        left: 38px;
        bottom: 60px;
    }
</style>

</head>
<body>
    <div class="zp">
        <div class="zp-panel"></div>
        <div class="btn">开始</div>
    </div>
</body>
<script>
    const arr = [
        {name: '积分+1'},
        {name: '积分+2'},
        {name: '积分+3'},
        {name: '积分+4'},
        {name: '电动车一辆', is: true},
        {name: '积分+10'}
    ]
    const zp = document.querySelector('.zp-panel')
    const btn = document.querySelector('.btn')
    const d = 360 / arr.length
    zp.innerHTML = arr.map((v, i) => {
        return `<div class="item" 
            style="transform:rotate(${i*d - 90}deg) translate(75px)">${v.name}</div>`
    }).join('')
    btn.onclick = () => {
        const zpIndex = arr.findIndex(v => v.is)
        const deg = -(zpIndex * d + 720)
        // 清空上次抽奖,暂停动画效果
        zp.style.transition = 'inherit'
        zp.style.transform = ''
        setTimeout(() => {
            // 重置transition,恢复动画效果
            zp.style.transition = ''
            setTimeout(() => {
                // 触发动画
                zp.style.transform  = `rotate(${deg}deg)`
            })
        })
    }
</script>
</html>

🛹 吸顶楼层导航

前端:UI 交互式特效 —— Css、Js,前端,css

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>楼层滚动</title>
  </head>
  <style>
    * {
      padding: 0;
      margin: 0;
    }
    body,
    html {
      height: auto;
      width: 100%;
      background-image: linear-gradient(to right, #f7f0ac, #acf7f0, #f0acf7);
    }
    .nav-wrap {
      position: fixed;
      z-index: 99;
      top: 50%;
      left: 120px;
      transform: translateY(-50%);
      width: 100px;
      height: 300px;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: space-between;
    }
    .stick {
      position: sticky;
      top: 10px;
      height: 15px;
      padding: 5px;
      line-height: 15px;
      background-color: #5f9ea0;
      color: #ffff;
      font-weight: 900;
    }
    .nav {
      width: 100px;
      flex: 1;
      margin-bottom: 10px;
      background: url(https://img1.baidu.com/it/u=105002249,3897918256&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=281)
        no-repeat center center/cover;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 25px;
    }
    .main {
      text-align: center;
      line-height: 900px;
      font-size: 30px;
      color: #ffff;
      width: 800px;
      height: 900px;
      /* background-color: hsla(0, 0%, 100%, 0.2); */
      background: rgba(255, 255, 255, 0.4);
      position: relative;
      left: 50%;
      transform: translateX(-50%);
    }
    .nav-active {
      color: red;
      background: url("https://img1.baidu.com/it/u=833204098,2930185410&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=745")
        no-repeat center center/cover;
    }
  </style>

  <body>
    <div class="nav-wrap">
      <div class="nav">A</div>
      <div class="nav">B</div>
      <div class="nav">C</div>
      <div class="nav">D</div>
    </div>

    <div class="main">A</div>

    <div class="main">
      <div class="stick">B</div>
    </div>

    <div class="main">
      <div class="stick">C</div>
    </div>

    <div class="main">
      <div class="stick">D</div>
    </div>
  </body>
  <script>
    const navAll = document.querySelector(".nav-wrap");
    const mainAll = document.querySelectorAll(".main");

    function reset() {
      for (let i = 0; i < navAll.children.length; i++) {
        navAll.children[i].classList.remove("nav-active");
      }
    }
    // 进入页面时,第一个导航栏高亮
    navAll.children[0].classList.add("nav-active");

    navAll.addEventListener("click", (event) => {
      if (event.target.classList.contains("nav")) {
        const index = Array.from(navAll.children).indexOf(event.target);
        console.log(index);
        window.scrollTo({
          top: Math.floor(mainAll[index].offsetTop),
          behavior: "smooth",
        });
      }
    });

    window.addEventListener("scroll", () => {
      const scrollTop = document.scrollingElement.scrollTop;
      let left = 0;
      let right = navAll.children.length - 1;

      while (left <= right) {
        const mid = Math.floor((left + right) / 2);
        const currentMain = mainAll[mid];

        if (
          currentMain.offsetTop <= scrollTop &&
          currentMain.offsetTop + currentMain.offsetHeight > scrollTop
        ) {
          reset();
          navAll.children[mid].classList.add("nav-active");
          break;
        } else if (currentMain.offsetTop > scrollTop) {
          right = mid - 1;
        } else {
          left = mid + 1;
        }
      }
    });
  </script>
</html>

✈️ 困了盖坤

前端:UI 交互式特效 —— Css、Js,前端,css

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />

  <title>羊了个羊</title>
  <style>
    * {
      box-sizing: border-box;
    }

    body {
      margin: 0;
    }

    .main {
      position: relative;
    }

    .item {
      position: absolute;
      background: no-repeat center center #ffffff;
      border: 1px solid #ddd;
      background-size: 100%;
      color: transparent;
      display: flex;
      justify-content: center;
      align-items: center;
      z-index: 0;
      transition: left 0.3s, top 0.3s, transform 0.3s;
    }

    .item:after {
      content: "";
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      transition: background-color 0.2s;
    }

    .disabled:after {
      background-color: rgba(0, 0, 0, 0.7);
    }

    .move-list {
      border: 1px solid #ddd;
      background-color: #ddd;
      margin: 0 auto;
    }
  </style>
</head>

<body>
  <div class="main"></div>
  <div class="move-list"></div>
</body>
<script>
  // 基础数据
  const simpleData = [
    { name: "虎", color: "#ff1100", bg: "./xxl-img/1.png" },
    { name: "兔", color: "#ff8800", bg: "./xxl-img/2.png" },
    { name: "牛", color: "green", bg: "./xxl-img/3.png" },
    { name: "羊", color: "blue", bg: "./xxl-img/4.png" },
    { name: "蛇", color: "#779922", bg: "./xxl-img/5.png" },
    { name: "鼠", color: "#335577", bg: "./xxl-img/6.png" },
  ];
  // 卡片大小
  const size = 40;
  // 矩阵行
  const rows = 10;
  // 矩阵列
  const cols = 10;
  // 每组为3个
  const oneGoupCount = 3;
  // 每个卡片有x组
  const group = 6;
  // 总共6层,即6个表格
  const layerCount = 6;
  // 表格html
  const cellHtml = [];
  // 将生成所有的十二生肖
  const renderData = Array.from(new Array(oneGoupCount * group))
    .map((v) => {
      return simpleData.map((v) => ({ ...v }));
    })
    .flat()
    .sort((v) => Math.random() - 0.5);
  // 第一步:绘制出表格矩阵
  for (let ly = layerCount - 1; ly >= 0; ly--) {
    for (let i = 0; i < rows; i++) {
      for (let j = 0; j < cols; j++) {
        let pyStep = (ly + 1) % 2 === 0 ? size / 2 : 0;
        let item = Math.random() > 0.7 && renderData.pop();

        item &&
          cellHtml.push(`<div class="item" onclick="move(this)" id="m${ly}-${i}-${j}"
                    style="width:${size}px;height:${size}px;left:${size * j + pyStep}px;top:${size * i + pyStep
            }px;background-image:url(${item.bg || ""})">${item.name || ""}</div>`);
      }
    }
  }
  const main = document.querySelector(".main");
  const moveList = document.querySelector(".move-list");
  main.innerHTML = cellHtml.reverse().join("");
  main.style.height = `${size * rows + size * 2}px`;
  main.style.width = `${size * cols}px`;
  moveList.style.height = `${size}px`;
  moveList.style.width = `${size * 6}px`;
  // 第二步:计算被遮住的底牌需标暗色
  const checkDisabled = (items) => {
    (items || main.querySelectorAll(".item")).forEach((v, i) => {
      const arr = v.id
        .substring(1)
        .split("-")
        .map((v) => Number(v));
      const isPy = (arr[0] + 1) % 2 === 0;
      for (let i = arr[0] + 1; i <= layerCount - 1; i++) {
        const isPyB = (i + 1) % 2 === 0;
        if (isPy === isPyB) {
          const el = main.querySelector(`#m${i}-${arr[1]}-${arr[2]}`);
          if (el) {
            v.classList.add("disabled");
            break;
          }
        } else if (isPy && !isPyB) {
          if (
            ![
              `${i}-${arr[1]}-${arr[2]}`,
              `${i}-${arr[1]}-${arr[2] + 1}`,
              `${i}-${arr[1] + 1}-${arr[2]}`,
              `${i}-${arr[1] + 1}-${arr[2] + 1}`,
            ].every((k) => {
              return !main.querySelector("#m" + k);
            })
          ) {
            v.classList.add("disabled");
            break;
          } else {
            v.classList.remove("disabled");
          }
        } else if (!isPy && isPyB) {
          if (
            ![
              `${i}-${arr[1]}-${arr[2]}`,
              `${i}-${arr[1]}-${arr[2] - 1}`,
              `${i}-${arr[1] - 1}-${arr[2]}`,
              `${i}-${arr[1] - 1}-${arr[2] - 1}`,
            ].every((k) => {
              return !main.querySelector("#m" + k);
            })
          ) {
            v.classList.add("disabled");
            break;
          } else {
            v.classList.remove("disabled");
          }
        }
      }
    });
  };
  // 第三步:点击卡片进行消除计算
  let canMove = true;
  // 点击棋子,动画移动
  const move = (me) => {
    let left = moveList.offsetLeft;
    let top = moveList.offsetTop;
    if (!canMove || me.className.indexOf("disabled") >= 0) {
      return;
    }
    canMove = false;
    if (moveList.children.length > 0) {
      let el = moveList.children[moveList.children.length - 1];
      left = el.offsetLeft + size;
      top = el.offsetTop;
    }
    me.style.top = `${top}px`;
    me.style.left = `${left}px`;
    me.transitionNamesCount = 0;
    me.ontransitionend = (e) => {
      me.transitionNamesCount++;
      if (me.transitionNamesCount === 2) {
        moveEnd(me);
        canMove = true;
      }
    };
  };
  // 动画结束的相关计算
  const moveEnd = (me) => {
    me.ontransitionend = null;
    me.setAttribute("onclick", "");
    moveList.appendChild(me);

    const findResult = [...moveList.children].filter((v) => v.innerHTML === me.innerHTML);
    if (findResult.length === 3) {
      findResult.forEach((v) => {
        v.ontransitionend = (e) => {
          moveList.removeChild(v);
          [...moveList.children].forEach((v, i) => {
            v.style.left = `${i * size + moveList.offsetLeft}px`;
          });
        };
        setTimeout(() => (v.style.transform = "scale(0)"));
      });
    }
    if (moveList.children.length === 6) {
      return alert("池子已满,游戏结束");
    } else if (main.children.length === 0) {
      return alert("恭喜通关");
    }
    checkDisabled();
  };
  checkDisabled();
</script>

</html>

🛫 扣扣乐

前端:UI 交互式特效 —— Css、Js,前端,css

<canvas id="cvs" width="605" height="338"></canvas>
<style>
    canvas {
        background: url(./images/zj.png) no-repeat center center;
        background-size: 100%;
    }
</style>
<script>
    const cvs = document.getElementById('cvs')
    const ctx = cvs.getContext('2d')
    const url = './images/zj-bg.jpeg'
    const img = new Image()
    img.src = url
    img.onload = () => {
        ctx.drawImage(img, 0, 0, cvs.width, cvs.height)
    }
    let isClearing = false
    cvs.addEventListener('mousedown', e => {
        isClearing = true
    })
    cvs.addEventListener('mousemove', e => {
        if (isClearing) {
            const clearSize = 60
            ctx.clearRect(e.pageX - clearSize, e.pageY - clearSize,
                clearSize, clearSize)
        }
    })
    document.addEventListener('mouseup', e => {
        isClearing = false
    })
</script>

🍰 签名回溯

前端:UI 交互式特效 —— Css、Js,前端,css

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>HTML5 绘图</title>
    <style>
      .canvas {
        border: 1px solid #ccc;
        cursor: crosshair;
      }
    </style>
  </head>
  <body>
    <input type="button" value="重放" id="btn1" />
    <input type="button" value="清空" id="btn2" />
    <input type="button" value="保存" id="btn3" />

    <br />
    <canvas id="cvs" class="canvas"></canvas>
  </body>
</html>
<script>
  class Draw {
    constructor(selector, width, height) {
      this.element = document.querySelector(selector);
      this.canvas = this.element.getContext("2d");
      this.element.width = width;
      this.element.height = height;
      this.timeId = null;
      this.animateArr = [];
    }
    init() {
      const { canvas: c, element: el } = this;
      let isDrag = false;

      c.lineWidth = 2;
      c.lineJoin = "round";
      c.shadowColor = "#000";
      c.shadowBlur = 4;

      el.onmousedown = () => {
        isDrag = true;
        c.beginPath();
      };
      el.onmousemove = (e) => {
        if (isDrag) {
          const x = e.pageX - el.offsetLeft;
          const y = e.pageY - el.offsetTop;
          c.lineTo(x, y);
          c.stroke();
          this.animateArr.push([x, y]);
        }
      };
      el.onmouseup = () => {
        isDrag = false;
        this.animateArr.push(-1);
      };
      el.onmouseout = () => {
        el.onmouseup();
      };
    }
    animateGo() {
      const { canvas: c } = this;
      this.clear();
      c.beginPath();
      const loop = (animate, i) => {
        if (i < animate.length - 1) {
          const arr = animate[i];
          if (arr === -1) {
            c.beginPath();
          } else {
            c.lineTo(arr[0], arr[1]);
            c.stroke();
          }
          i++;
          this.timeId = setTimeout(() => {
            loop(animate, i);
          }, 10);
        }
      };
      loop(this.animateArr, 0);
    }
    clear() {
      const { canvas: c } = this;
      const { width, height } = this.element;
      c.clearRect(0, 0, width, height);
    }
  }
  const g = new Draw("#cvs", 600, 500);
  g.init();
  document.getElementById("btn1").onclick = () => {
    g.animateGo();
  };
  document.getElementById("btn2").onclick = () => {
    g.clear();
    g.animateArr = [];
  };
  document.getElementById("btn3").onclick = () => {
    const canvas = document.querySelector("#cvs");
    const dataURL = canvas.toDataURL();
    // 将dataURL发送到服务器进行保存操作
    console.log(dataURL);
  };
</script>

🌍 翻盘抽奖

前端:UI 交互式特效 —— Css、Js,前端,css

 前端:UI 交互式特效 —— Css、Js,前端,css画面 挺多、不一一展示了,快来一键三连抱走吧

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>9宫格翻牌抽奖</title>
    <style>
        .title {
            text-align: center;
        }
        .box {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
            width: 330px;
            margin:0 auto;
        }
        .item {
            position: relative;
            margin: 5px;
            width: 100px;
            height: 100px;
        }
        .style1, .style2 {
            position: absolute;
            left:0;
            top: 0;
            bottom: 0;
            right: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            border-radius: 5px;
            text-align: center;
            transition: transform .4s
        }
        .style1 {
            background-color: #ff8800;
            color: #fff;
        }
        .style2 {
            color: #ff8800;
            border:1px solid #ff8800;
            padding: 0 10px;
            transform: scaleX(0);
            background-color: #ffe6c9;
        }
        .hide {
            transform: scaleX(0);
        }
        .show {
            transform: scaleX(1);
        }
        .show-result {
            transform: scaleX(1);
            opacity: 0.5;
        }
    </style>
</head>
<style>
</style>
<body>
    <div class="title">可抽奖<label id="count">0</label>次</div>
    <div class="box"></div>
</body>
<script>
    // 奖品列表
    const list = [
        {id: 1, name: '1元优惠券', is: true},
        {id: 2, name: '10元优惠券', is: true},
        {id: 3, name: '谢谢惠顾', is: true},
        {id: 4, name: '豪华电动车'},
        {id: 5, name: '1w购物券'},
        {id: 6, name: '5w购物券'},
        {id: 7, name: '豪华轿车'},
        {id: 8, name: '房子一套'},
        {id: 9, name: '顶配笔记本'}
    ].sort(v => Math.random() - 0.5)
    // 中奖项
    const isArr = list.filter(v => v.is)
    // 非中奖项
    const noArr = list.filter(v => !v.is)
    // 抽奖次数
    let count = 3
    const box = document.querySelector('.box')
    const countEL = document.querySelector('#count')
    countEL.innerHTML = count
    box.innerHTML = list.map(v => {
        return `<div class="item" onclick="fp(this)">
            <div class="style1">抽奖</div>
            <div class="style2"></div>
        </div>`
    }).join('')
    // 翻牌抽奖
    const fp = (me) => {
        if (count === 0) {
            return
        }
        me.querySelector('.style1').classList.add('hide')
        // 抽奖动画
        setTimeout(() => {
            // 从非中奖项中取最后一个,并从数组中移除该项
            const item = isArr.pop()
            const style2 = me.querySelector('.style2')
            style2.innerHTML = item.name
            style2.classList.add('show')
        }, 400)
        count--
        countEL.innerHTML = count
        // 当抽奖次数为0的时候,就把剩余的奖项全部展示出来
        if (count === 0) {
            setTimeout(() => {
                box.querySelectorAll('.style1').forEach(v => {
                    v.classList.add('hide')
                    if (v.nextElementSibling.className.indexOf('show') === -1) {
                        const item = noArr.pop()
                        v.nextElementSibling.innerHTML = item.name
                    }
                })
                setTimeout(() => {
                    box.querySelectorAll('.style2').forEach(v => {
                        if (v.className.indexOf('show') === -1) {
                            v.classList.add('show-result')
                        }
                    })
                }, 400)
            }, 1000)
        }
    }
</script>
</html>

🪂 地址 🤺🤺🤺 

前端:UI 交互式特效 —— Css、Js,前端,css

前端:UI 交互式特效 —— Css、Js,前端,css

  

 🥰😉  谢谢观看

前端:UI 交互式特效 —— Css、Js,前端,css

 _______________________________  期待再见  _______________________________ 文章来源地址https://www.toymoban.com/news/detail-575861.html

到了这里,关于前端:UI 交互式特效 —— Css、Js的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Selenium4+Python3 - Iframe、Select控件、交互式弹出框、执行JS、Cookie操作

    iframe识别: 语法: driver.switch_to.frame(‘方式’) 1、常见处理方法三种 index:下标 name:id或name属性的值 webelement:元素 2、通过下标进入 进入第一个iframe: 3、通过id或name属性的值进入 通过id或name属性的值进入指定的iframe: 4、通过iframe元素进入iframe 通过iframe元素进入指定i

    2024年02月04日
    浏览(61)
  • 前端:运用html+css+js模仿京东上商品图片区域放大特效

    1. 前言 最近在网页端浏览京东上的商品时,觉得上面的那张gif图片上实现的特效不错,于是自己打算使用html+css+js技术来实现一下上述特效效果,我的实效果如下: 2. 前端界面 主要使用到浮动、绝对定位、相对定位等知识,不了解这部分知识点的读者可以先去了解了解,再

    2024年02月16日
    浏览(56)
  • 前端:运用html+css+js模仿百度热搜电影榜鼠标移入特效

    1. 实现原理 百度热搜上电影榜鼠标移入特效如上图所示。个人觉得上述特效实现原理为使用相对定位、绝对定位实现的(鼠标移入和没有移入时,元素布局有一些不同而已)。至于鼠标移入时,出现延迟效果,则是在css上设置transition(用于设置过渡效果的)实现的。我的实现效果

    2024年02月15日
    浏览(67)
  • 交互式shell与非交互式shell,反弹shell

    交互shell就是shell等待你的输入,并且立即执行你提交的命令。 这种模式被称作交互式是因为shell与用户进行交互。 这种模式也是大多数用户非常熟悉的:登录、执行一些命令、签退。当签退后,shell也终止了。 需要进行信息交互,例如输入某个信息 会返回信息 你需要对其输

    2024年02月02日
    浏览(56)
  • 人机交互学习-6 交互式系统的设计

    Allan Cooper建议不要过早地把重点放在小细节、小部件和精细的交互上会妨碍产品的设计,应先站在一个高层次上关注用户界面和相关行为的整体结构 Allan Cooper提出的交互框架不仅 定义了高层次的屏幕布局 ,同时定义了 产品的工作流、行为和组织 。它包括了6个主要步骤:

    2024年02月09日
    浏览(61)
  • 人机交互学习-5 交互式系统的需求

    关于目标产品的一种陈述,它指定了产品应做什么,或者应如何工作 应该是具体、明确和无歧义的 搜集数据 解释数据 提取需求 注:了解 功能不同 智能冰箱:应能够提示黄油已用完 字处理器:系统应支持多种格式 物理条件不同 移动设备运行的系统应尽可能小,屏幕显示限

    2024年02月09日
    浏览(58)
  • 交互式shell

    交互式模式就是shell等待用户的输入,并且执行用户提交的命令。这种模式被称作交互式是因为shell与用户进行交互。这种模式也是大多数用户非常熟悉的:登录、执行一些命令、签退。当用户签退后,shell也终止了。 shell也可以运行在另外一种模式:非交互式模式。在这种模

    2024年02月02日
    浏览(50)
  • Pyspark交互式编程

    Pyspark交互式编程 有该数据集Data01.txt 该数据集包含了某大学计算机系的成绩,数据格式如下所示: 根据给定的数据集,在pyspark中通过编程来完成以下内容: 该系总共有多少学生; (提前启动好pyspark) 该系共开设了多少门课程; Tom同学的总成绩平均分是多少; 求每名同学的

    2023年04月08日
    浏览(49)
  • web前端——页面动态交互(对注册页信息添加css及js)

    按照下述要求为register.html补充外部CSS样式和JavaScript脚本。 1.补充register.css样式,实现如下功能(效果见图2): 设置“注册信息”红、黄二重文本阴影,使用rgba设置阴影具有一定透明度; 姓名和密码输入框中显示背景图像; 单选按钮和复选按钮被选中时,其后的辅助文本动

    2024年02月03日
    浏览(48)
  • 构建一个动态交互式图表

    在Web开发中,JavaScript不仅是实现交互效果的关键,还可以用于构建复杂的可视化组件,如动态交互式图表。在本篇博客中,我将演示如何使用JavaScript和HTML5的Canvas元素来创建一个简单的动态条形图。 HTML结构  首先,我们需要一个HTML结构来容纳我们的图表。 JavaScript实现 接下

    2024年02月20日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包