HTML视口动画

animista.js

复制代码
const getParamet = {
  getAnimistaClass(element) {
    return element.getAttribute("animista-class");
  },
  getIntervalTime(element) {
    return element.getAttribute("interval-time")
      ? Number(element.getAttribute("interval-time"))
      : null;
  },
  getBeforeTime(element) {
    return element.getAttribute("before-time")
      ? Number(element.getAttribute("before-time"))
      : null;
  },
  getTime(element) {
    return element.getAttribute("time")
      ? Number(element.getAttribute("time"))
      : null;
  },
};
class AnimistaParamet {
  animistaClass = null;
  intervalTime = null;
  beforeTime = null;
  time = null;
  constructor(parentElement, resetAnimistaParamet) {
    if (!resetAnimistaParamet) resetAnimistaParamet = {};
    if (!(parentElement instanceof Element))
      throw new Error("parentElement not is Element");
    this.animistaClass =
      getParamet.getAnimistaClass(parentElement) ||
      resetAnimistaParamet.animistaClass ||
      "";
    this.intervalTime =
      getParamet.getIntervalTime(parentElement) ||
      resetAnimistaParamet.intervalTime;
    this.beforeTime =
      getParamet.getBeforeTime(parentElement) ||
      resetAnimistaParamet.beforeTime;
    this.time = getParamet.getTime(parentElement);
  }
}

const getParentAnimistaParamet = (parentElement) => {
  const parentParamet = new AnimistaParamet(parentElement);
  return parentParamet;
};

const getParentAnimista = (parentElement, parentParamet) => {
  let time = parentParamet.beforeTime || 0;
  const childElements = parentElement.children;
  const childrenElementParamet = [];
  for (let i = 0; i < childElements.length; i++) {
    const itemElement = childElements[i];
    const itemParamet = new AnimistaParamet(itemElement, parentParamet);
    itemParamet.time =
      itemParamet.time === null
        ? time + i * itemParamet.intervalTime + (itemParamet.beforeTime || 0)
        : itemParamet.time;
    childrenElementParamet.push({
      itemElement,
      itemParamet,
    });
  }
  return childrenElementParamet;
};

const setParentAnimista = (childrenElementParamet) => {
  childrenElementParamet.forEach((item) => {
    setTimeout(() => {
      item.itemParamet.animistaClass &&
        item.itemElement.classList.add(item.itemParamet.animistaClass);
      item.itemElement.classList.remove("hide");
    }, item.itemParamet.time);
  });
};
const targets = document.querySelectorAll(".animista_box");
const parentAnimistaParametMap = new Map();
targets.forEach((item) => {
  parentAnimistaParametMap.set(item.id, getParentAnimistaParamet(item));
  item.classList.add("hide");
});
if ("IntersectionObserver" in window) {
  const observer = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          const parentAnimistaParamet = parentAnimistaParametMap.get(
            entry.target.id
          );
          if (!parentAnimistaParamet) return;

          const parentAnimista = getParentAnimista(
            entry.target,
            parentAnimistaParamet
          );
          setParentAnimista(parentAnimista);
        } else {
        }
      });
    },
    {
      root: null,
      rootMargin: "0px",
      threshold: 0.1,
    }
  );
  targets.forEach((target) => {
    observer.observe(target);
  });
} else {
  console.log("浏览器不支持 Intersection Observer");
}

animista.css

复制代码
/* ----------------------------------------------
 * Generated by Animista on 2025-2-19 18:25:51
 * Licensed under FreeBSD License.
 * See http://animista.net/license for more info. 
 * w: http://animista.net, t: @cssanimista
 * ---------------------------------------------- */

/**
 * ----------------------------------------
 * animation slide-in-blurred-left
 * ----------------------------------------
 */
@-webkit-keyframes slide-in-blurred-left {
  0% {
    -webkit-transform: translateX(-1000px) scaleX(2.5) scaleY(0.2);
    transform: translateX(-1000px) scaleX(2.5) scaleY(0.2);
    -webkit-transform-origin: 100% 50%;
    transform-origin: 100% 50%;
    -webkit-filter: blur(40px);
    filter: blur(40px);
    opacity: 0;
  }
  100% {
    -webkit-transform: translateX(0) scaleY(1) scaleX(1);
    transform: translateX(0) scaleY(1) scaleX(1);
    -webkit-transform-origin: 50% 50%;
    transform-origin: 50% 50%;
    -webkit-filter: blur(0);
    filter: blur(0);
    opacity: 1;
  }
}
@keyframes slide-in-blurred-left {
  0% {
    -webkit-transform: translateX(-1000px) scaleX(2.5) scaleY(0.2);
    transform: translateX(-1000px) scaleX(2.5) scaleY(0.2);
    -webkit-transform-origin: 100% 50%;
    transform-origin: 100% 50%;
    -webkit-filter: blur(40px);
    filter: blur(40px);
    opacity: 0;
  }
  100% {
    -webkit-transform: translateX(0) scaleY(1) scaleX(1);
    transform: translateX(0) scaleY(1) scaleX(1);
    -webkit-transform-origin: 50% 50%;
    transform-origin: 50% 50%;
    -webkit-filter: blur(0);
    filter: blur(0);
    opacity: 1;
  }
}
.slide-in-blurred-left {
  -webkit-animation: slide-in-blurred-left 0.6s
    cubic-bezier(0.165, 0.84, 0.44, 1) both;
  animation: slide-in-blurred-left 0.6s cubic-bezier(0.165, 0.84, 0.44, 1) both;
}
/* ----------------------------------------------
 * Generated by Animista on 2025-2-19 18:28:1
 * Licensed under FreeBSD License.
 * See http://animista.net/license for more info. 
 * w: http://animista.net, t: @cssanimista
 * ---------------------------------------------- */

/**
 * ----------------------------------------
 * animation slide-in-blurred-bottom
 * ----------------------------------------
 */
@-webkit-keyframes slide-in-blurred-bottom {
  0% {
    -webkit-transform: translateY(1000px) scaleY(2.5) scaleX(0.2);
    transform: translateY(1000px) scaleY(2.5) scaleX(0.2);
    -webkit-transform-origin: 50% 100%;
    transform-origin: 50% 100%;
    -webkit-filter: blur(40px);
    filter: blur(40px);
    opacity: 0;
  }
  100% {
    -webkit-transform: translateY(0) scaleY(1) scaleX(1);
    transform: translateY(0) scaleY(1) scaleX(1);
    -webkit-transform-origin: 50% 50%;
    transform-origin: 50% 50%;
    -webkit-filter: blur(0);
    filter: blur(0);
    opacity: 1;
  }
}
@keyframes slide-in-blurred-bottom {
  0% {
    -webkit-transform: translateY(1000px) scaleY(2.5) scaleX(0.2);
    transform: translateY(1000px) scaleY(2.5) scaleX(0.2);
    -webkit-transform-origin: 50% 100%;
    transform-origin: 50% 100%;
    -webkit-filter: blur(40px);
    filter: blur(40px);
    opacity: 0;
  }
  100% {
    -webkit-transform: translateY(0) scaleY(1) scaleX(1);
    transform: translateY(0) scaleY(1) scaleX(1);
    -webkit-transform-origin: 50% 50%;
    transform-origin: 50% 50%;
    -webkit-filter: blur(0);
    filter: blur(0);
    opacity: 1;
  }
}
.slide-in-blurred-bottom {
  -webkit-animation: slide-in-blurred-bottom 0.6s cubic-bezier(0.23, 1, 0.32, 1)
    both;
  animation: slide-in-blurred-bottom 0.6s cubic-bezier(0.23, 1, 0.32, 1) both;
}

html

bash 复制代码
 <div animista-class="slide-in-blurred-left" interval-time="100" class="animista_box">
 </div>
相关推荐
前端 贾公子5 小时前
pnpm 的 resolution-mode 配置 ( pnpm 的版本解析)
前端
伍哥的传说6 小时前
React 自定义Hook——页面或元素滚动到底部监听 Hook
前端·react.js·前端框架
麦兜*8 小时前
Spring Boot 集成Reactive Web 性能优化全栈技术方案,包含底层原理、压测方法论、参数调优
java·前端·spring boot·spring·spring cloud·性能优化·maven
知了一笑8 小时前
独立开发第二周:构建、执行、规划
java·前端·后端
UI前端开发工作室9 小时前
数字孪生技术为UI前端提供新视角:产品性能的实时模拟与预测
大数据·前端
Sapphire~9 小时前
重学前端004 --- html 表单
前端·html
遇到困难睡大觉哈哈9 小时前
CSS中的Element语法
前端·css
Real_man9 小时前
新物种与新法则:AI重塑开发与产品未来
前端·后端·面试
小彭努力中9 小时前
147.在 Vue3 中使用 OpenLayers 地图上 ECharts 模拟飞机循环飞行
前端·javascript·vue.js·ecmascript·echarts
老马聊技术9 小时前
日历插件-FullCalendar的详细使用
前端·javascript