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>
相关推荐
小小小小宇2 小时前
TS泛型笔记
前端
小小小小宇2 小时前
前端canvas手动实现复杂动画示例
前端
codingandsleeping2 小时前
重读《你不知道的JavaScript》(上)- 作用域和闭包
前端·javascript
小小小小宇2 小时前
前端PerformanceObserver使用
前端
zhangxingchao3 小时前
Flutter中的页面跳转
前端
烛阴4 小时前
Puppeteer入门指南:掌控浏览器,开启自动化新时代
前端·javascript
全宝4 小时前
🖲️一行代码实现鼠标换肤
前端·css·html
小小小小宇5 小时前
前端模拟一个setTimeout
前端
萌萌哒草头将军5 小时前
🚀🚀🚀 不要只知道 Vite 了,可以看看 Farm ,Rust 编写的快速且一致的打包工具
前端·vue.js·react.js
芝士加6 小时前
Playwright vs MidScene:自动化工具“双雄”谁更适合你?
前端·javascript