跟随鼠标3D倾斜

  1. 创建一个vanilla-tilt.js文件
  2. 将一下代码黏贴进去
  3. export var VanillaTilt = (function () {
      'use strict';
    
      /**
       * Created by Sergiu Șandor (micku7zu) on 1/27/2017.
       * Original idea: https://github.com/gijsroge/tilt.js
       * MIT License.
       * Version 1.7.2
       */
    
      class VanillaTilt {
        constructor(element, settings = {}) {
          if (!(element instanceof Node)) {
            throw ("Can't initialize VanillaTilt because " + element + " is not a Node.");
          }
    
          this.width = null;
          this.height = null;
          this.clientWidth = null;
          this.clientHeight = null;
          this.left = null;
          this.top = null;
    
          // for Gyroscope sampling
          this.gammazero = null;
          this.betazero = null;
          this.lastgammazero = null;
          this.lastbetazero = null;
    
          this.transitionTimeout = null;
          this.updateCall = null;
          this.event = null;
    
          this.updateBind = this.update.bind(this);
          this.resetBind = this.reset.bind(this);
    
          this.element = element;
          this.settings = this.extendSettings(settings);
    
          this.reverse = this.settings.reverse ? -1 : 1;
          this.glare = VanillaTilt.isSettingTrue(this.settings.glare);
          this.glarePrerender = VanillaTilt.isSettingTrue(this.settings["glare-prerender"]);
          this.fullPageListening = VanillaTilt.isSettingTrue(this.settings["full-page-listening"]);
          this.gyroscope = VanillaTilt.isSettingTrue(this.settings.gyroscope);
          this.gyroscopeSamples = this.settings.gyroscopeSamples;
    
          this.elementListener = this.getElementListener();
    
          if (this.glare) {
            this.prepareGlare();
          }
    
          if (this.fullPageListening) {
            this.updateClientSize();
          }
    
          this.addEventListeners();
          this.reset();
          this.updateInitialPosition();
        }
    
        static isSettingTrue (setting) {
          return setting === "" || setting === true || setting === 1;
        }
    
        /**
         * Method returns element what will be listen mouse events
         * @return {Node}
         */
        getElementListener () {
          if (this.fullPageListening) {
            return window.document;
          }
    
          if (typeof this.settings["mouse-event-element"] === "string") {
            const mouseEventElement = document.querySelector(this.settings["mouse-event-element"]);
    
            if (mouseEventElement) {
              return mouseEventElement;
            }
          }
    
          if (this.settings["mouse-event-element"] instanceof Node) {
            return this.settings["mouse-event-element"];
          }
    
          return this.element;
        }
    
        /**
         * Method set listen methods for this.elementListener
         * @return {Node}
         */
        addEventListeners () {
          this.onMouseEnterBind = this.onMouseEnter.bind(this);
          this.onMouseMoveBind = this.onMouseMove.bind(this);
          this.onMouseLeaveBind = this.onMouseLeave.bind(this);
          this.onWindowResizeBind = this.onWindowResize.bind(this);
          this.onDeviceOrientationBind = this.onDeviceOrientation.bind(this);
    
          this.elementListener.addEventListener("mouseenter", this.onMouseEnterBind);
          this.elementListener.addEventListener("mouseleave", this.onMouseLeaveBind);
          this.elementListener.addEventListener("mousemove", this.onMouseMoveBind);
    
          if (this.glare || this.fullPageListening) {
            window.addEventListener("resize", this.onWindowResizeBind);
          }
    
          if (this.gyroscope) {
            window.addEventListener("deviceorientation", this.onDeviceOrientationBind);
          }
        }
    
        /**
         * Method remove event listeners from current this.elementListener
         */
        removeEventListeners () {
          this.elementListener.removeEventListener("mouseenter", this.onMouseEnterBind);
          this.elementListener.removeEventListener("mouseleave", this.onMouseLeaveBind);
          this.elementListener.removeEventListener("mousemove", this.onMouseMoveBind);
    
          if (this.gyroscope) {
            window.removeEventListener("deviceorientation", this.onDeviceOrientationBind);
          }
    
          if (this.glare || this.fullPageListening) {
            window.removeEventListener("resize", this.onWindowResizeBind);
          }
        }
    
        destroy () {
          clearTimeout(this.transitionTimeout);
          if (this.updateCall !== null) {
            cancelAnimationFrame(this.updateCall);
          }
    
          this.reset();
    
          this.removeEventListeners();
          this.element.vanillaTilt = null;
          delete this.element.vanillaTilt;
    
          this.element = null;
        }
    
        onDeviceOrientation (event) {
          if (event.gamma === null || event.beta === null) {
            return;
          }
    
          this.updateElementPosition();
    
          if (this.gyroscopeSamples > 0) {
            this.lastgammazero = this.gammazero;
            this.lastbetazero = this.betazero;
    
            if (this.gammazero === null) {
              this.gammazero = event.gamma;
              this.betazero = event.beta;
            } else {
              this.gammazero = (event.gamma + this.lastgammazero) / 2;
              this.betazero = (event.beta + this.lastbetazero) / 2;
            }
    
            this.gyroscopeSamples -= 1;
          }
    
          const totalAngleX = this.settings.gyroscopeMaxAngleX - this.settings.gyroscopeMinAngleX;
          const totalAngleY = this.settings.gyroscopeMaxAngleY - this.settings.gyroscopeMinAngleY;
    
          const degreesPerPixelX = totalAngleX / this.width;
          const degreesPerPixelY = totalAngleY / this.height;
    
          const angleX = event.gamma - (this.settings.gyroscopeMinAngleX + this.gammazero);
          const angleY = event.beta - (this.settings.gyroscopeMinAngleY + this.betazero);
    
          const posX = angleX / degreesPerPixelX;
          const posY = angleY / degreesPerPixelY;
    
          if (this.updateCall !== null) {
            cancelAnimationFrame(this.updateCall);
          }
    
          this.event = {
            clientX: posX + this.left,
            clientY: posY + this.top,
          };
    
          this.updateCall = requestAnimationFrame(this.updateBind);
        }
    
        onMouseEnter () {
          this.updateElementPosition();
          this.element.style.willChange = "transform";
          this.setTransition();
        }
    
        onMouseMove (event) {
          if (this.updateCall !== null) {
            cancelAnimationFrame(this.updateCall);
          }
    
          this.event = event;
          this.updateCall = requestAnimationFrame(this.updateBind);
        }
    
        onMouseLeave () {
          this.setTransition();
    
          if (this.settings.reset) {
            requestAnimationFrame(this.resetBind);
          }
        }
    
        reset () {
          this.event = {
            clientX: this.left + this.width / 2,
            clientY: this.top + this.height / 2
          };
    
          if (this.element && this.element.style) {
            this.element.style.transform = `perspective(${this.settings.perspective}px) ` +
              `rotateX(0deg) ` +
              `rotateY(0deg) ` +
              `scale3d(1, 1, 1)`;
          }
    
          this.resetGlare();
        }
    
        resetGlare () {
          if (this.glare) {
            this.glareElement.style.transform = "rotate(180deg) translate(-50%, -50%)";
            this.glareElement.style.opacity = "0";
          }
        }
    
        updateInitialPosition () {
          if (this.settings.startX === 0 && this.settings.startY === 0) {
            return;
          }
    
          this.onMouseEnter();
    
          if (this.fullPageListening) {
            this.event = {
              clientX: (this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.clientWidth,
              clientY: (this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.clientHeight
            };
          } else {
            this.event = {
              clientX: this.left + ((this.settings.startX + this.settings.max) / (2 * this.settings.max) * this.width),
              clientY: this.top + ((this.settings.startY + this.settings.max) / (2 * this.settings.max) * this.height)
            };
          }
    
    
          let backupScale = this.settings.scale;
          this.settings.scale = 1;
          this.update();
          this.settings.scale = backupScale;
          this.resetGlare();
        }
    
        getValues () {
          let x, y;
    
          if (this.fullPageListening) {
            x = this.event.clientX / this.clientWidth;
            y = this.event.clientY / this.clientHeight;
          } else {
            x = (this.event.clientX - this.left) / this.width;
            y = (this.event.clientY - this.top) / this.height;
          }
    
          x = Math.min(Math.max(x, 0), 1);
          y = Math.min(Math.max(y, 0), 1);
    
          let tiltX = (this.reverse * (this.settings.max - x * this.settings.max * 2)).toFixed(2);
          let tiltY = (this.reverse * (y * this.settings.max * 2 - this.settings.max)).toFixed(2);
          let angle = Math.atan2(this.event.clientX - (this.left + this.width / 2), -(this.event.clientY - (this.top + this.height / 2))) * (180 / Math.PI);
    
          return {
            tiltX: tiltX,
            tiltY: tiltY,
            percentageX: x * 100,
            percentageY: y * 100,
            angle: angle
          };
        }
    
        updateElementPosition () {
          let rect = this.element.getBoundingClientRect();
    
          this.width = this.element.offsetWidth;
          this.height = this.element.offsetHeight;
          this.left = rect.left;
          this.top = rect.top;
        }
    
        update () {
          let values = this.getValues();
    
          this.element.style.transform = "perspective(" + this.settings.perspective + "px) " +
            "rotateX(" + (this.settings.axis === "x" ? 0 : values.tiltY) + "deg) " +
            "rotateY(" + (this.settings.axis === "y" ? 0 : values.tiltX) + "deg) " +
            "scale3d(" + this.settings.scale + ", " + this.settings.scale + ", " + this.settings.scale + ")";
    
          if (this.glare) {
            this.glareElement.style.transform = `rotate(${values.angle}deg) translate(-50%, -50%)`;
            this.glareElement.style.opacity = `${values.percentageY * this.settings["max-glare"] / 100}`;
          }
    
          this.element.dispatchEvent(new CustomEvent("tiltChange", {
            "detail": values
          }));
    
          this.updateCall = null;
        }
    
        /**
         * Appends the glare element (if glarePrerender equals false)
         * and sets the default style
         */
        prepareGlare () {
          // If option pre-render is enabled we assume all html/css is present for an optimal glare effect.
          if (!this.glarePrerender) {
            // Create glare element
            const jsTiltGlare = document.createElement("div");
            jsTiltGlare.classList.add("js-tilt-glare");
    
            const jsTiltGlareInner = document.createElement("div");
            jsTiltGlareInner.classList.add("js-tilt-glare-inner");
    
            jsTiltGlare.appendChild(jsTiltGlareInner);
            this.element.appendChild(jsTiltGlare);
          }
    
          this.glareElementWrapper = this.element.querySelector(".js-tilt-glare");
          this.glareElement = this.element.querySelector(".js-tilt-glare-inner");
    
          if (this.glarePrerender) {
            return;
          }
    
          Object.assign(this.glareElementWrapper.style, {
            "position": "absolute",
            "top": "0",
            "left": "0",
            "width": "100%",
            "height": "100%",
            "overflow": "hidden",
            "pointer-events": "none"
          });
    
          Object.assign(this.glareElement.style, {
            "position": "absolute",
            "top": "50%",
            "left": "50%",
            "pointer-events": "none",
            "background-image": `linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%)`,
            "transform": "rotate(180deg) translate(-50%, -50%)",
            "transform-origin": "0% 0%",
            "opacity": "0",
          });
    
          this.updateGlareSize();
        }
    
        updateGlareSize () {
          if (this.glare) {
            const glareSize = (this.element.offsetWidth > this.element.offsetHeight ? this.element.offsetWidth : this.element.offsetHeight) * 2;
    
            Object.assign(this.glareElement.style, {
              "width": `${glareSize}px`,
              "height": `${glareSize}px`,
            });
          }
        }
    
        updateClientSize () {
          this.clientWidth = window.innerWidth
            || document.documentElement.clientWidth
            || document.body.clientWidth;
    
          this.clientHeight = window.innerHeight
            || document.documentElement.clientHeight
            || document.body.clientHeight;
        }
    
        onWindowResize () {
          this.updateGlareSize();
          this.updateClientSize();
        }
    
        setTransition () {
          clearTimeout(this.transitionTimeout);
          this.element.style.transition = this.settings.speed + "ms " + this.settings.easing;
          if (this.glare) this.glareElement.style.transition = `opacity ${this.settings.speed}ms ${this.settings.easing}`;
    
          this.transitionTimeout = setTimeout(() => {
            this.element.style.transition = "";
            if (this.glare) {
              this.glareElement.style.transition = "";
            }
          }, this.settings.speed);
    
        }
    
        /**
         * Method return patched settings of instance
         * @param {boolean} settings.reverse - reverse the tilt direction
         * @param {number} settings.max - max tilt rotation (degrees)
         * @param {startX} settings.startX - the starting tilt on the X axis, in degrees. Default: 0
         * @param {startY} settings.startY - the starting tilt on the Y axis, in degrees. Default: 0
         * @param {number} settings.perspective - Transform perspective, the lower the more extreme the tilt gets
         * @param {string} settings.easing - Easing on enter/exit
         * @param {number} settings.scale - 2 = 200%, 1.5 = 150%, etc..
         * @param {number} settings.speed - Speed of the enter/exit transition
         * @param {boolean} settings.transition - Set a transition on enter/exit
         * @param {string|null} settings.axis - What axis should be disabled. Can be X or Y
         * @param {boolean} settings.glare - What axis should be disabled. Can be X or Y
         * @param {number} settings.max-glare - the maximum "glare" opacity (1 = 100%, 0.5 = 50%)
         * @param {boolean} settings.glare-prerender - false = VanillaTilt creates the glare elements for you, otherwise
         * @param {boolean} settings.full-page-listening - If true, parallax effect will listen to mouse move events on the whole document, not only the selected element
         * @param {string|object} settings.mouse-event-element - String selector or link to HTML-element what will be listen mouse events
         * @param {boolean} settings.reset - false = If the tilt effect has to be reset on exit
         * @param {gyroscope} settings.gyroscope - Enable tilting by deviceorientation events
         * @param {gyroscopeSensitivity} settings.gyroscopeSensitivity - Between 0 and 1 - The angle at which max tilt position is reached. 1 = 90deg, 0.5 = 45deg, etc..
         * @param {gyroscopeSamples} settings.gyroscopeSamples - How many gyroscope moves to decide the starting position.
         */
        extendSettings (settings) {
          let defaultSettings = {
            reverse: false,
            max: 15,
            startX: 0,
            startY: 0,
            perspective: 1000,
            easing: "cubic-bezier(.03,.98,.52,.99)",
            scale: 1,
            speed: 300,
            transition: true,
            axis: null,
            glare: false,
            "max-glare": 1,
            "glare-prerender": false,
            "full-page-listening": false,
            "mouse-event-element": null,
            reset: true,
            gyroscope: true,
            gyroscopeMinAngleX: -45,
            gyroscopeMaxAngleX: 45,
            gyroscopeMinAngleY: -45,
            gyroscopeMaxAngleY: 45,
            gyroscopeSamples: 10
          };
    
          let newSettings = {};
          for (var property in defaultSettings) {
            if (property in settings) {
              newSettings[property] = settings[property];
            } else if (this.element.hasAttribute("data-tilt-" + property)) {
              let attribute = this.element.getAttribute("data-tilt-" + property);
              try {
                newSettings[property] = JSON.parse(attribute);
              } catch (e) {
                newSettings[property] = attribute;
              }
    
            } else {
              newSettings[property] = defaultSettings[property];
            }
          }
    
          return newSettings;
        }
    
        static init (elements, settings) {
          if (elements instanceof Node) {
            elements = [elements];
          }
    
          if (elements instanceof NodeList) {
            elements = [].slice.call(elements);
          }
    
          if (!(elements instanceof Array)) {
            return;
          }
    
          elements.forEach((element) => {
            if (!("vanillaTilt" in element)) {
              element.vanillaTilt = new VanillaTilt(element, settings);
            }
          });
        }
      }
    
      if (typeof document !== "undefined") {
        /* expose the class to window */
        window.VanillaTilt = VanillaTilt;
    
        /**
         * Auto load
         */
        VanillaTilt.init(document.querySelectorAll("[data-tilt]"));
      }
    
      return VanillaTilt;
    
    }());
    

    使用:

    VanillaTilt.init(document.querySelectorAll('.publicize-item'), {
          max: 15, //最大倾斜度数
          speed: 400, //倾斜转换的速度
          glare: true, //是否开启眩光效果
          'max-glare': 1, //最大眩光的不透明度
          scale: 1.05 //指定2D旋转的缩放
        });

    配置项:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/308417.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一道新能:周期底部,TOPCon“红利牛”IPO来了

2023年无疑是TOPCon技术路线正式登台的一年,而风口之下必有“黑马”的诞生,去年最后一个工作日递交招股书申请创业板上市的一道新能正是如此。 复盘发现,短短成立五年,一道新能在双碳红利期中,实现资产规模、营收规模…

OpenAI ChatGPT-4开发笔记2024-04:Chat之Tool之2:multiple functions

从程序员到ai Expert 1 定义参数和函数2 第一轮chatgpt3 第一轮结果和function定义全部加入prompt再喂给chatgpt4 大结局7 参考资料 上一篇解决了调用一个函数的问题。这一篇扩展为调用3个。n个自行脑补。 1 定义参数和函数 #1.设定目标 import json import openai#1.定义para…

CSS 弹幕按钮动画

<template><view class="content"><button class="btn-23"><text class="text">弹幕按钮</text><text class="marquee">弹幕按钮</text></button></view></template><…

IP地址定位技术筑牢网络安全防线

随着互联网技术的飞速发展&#xff0c;网络安全问题日益凸显&#xff0c;成为人们关注的焦点。如何有效防范和打击网络犯罪&#xff0c;维护国家安全和社会稳定&#xff0c;是摆在我们面前的一项紧迫任务。IP地址定位技术作为网络安全领域的一项重要技术&#xff0c;在防范和打…

阿里云 云数据库 Redis 版测评

1. 试用 地址&#xff1a;https://developer.aliyun.com/topic/freetier/database 点击试用 选择相应信息后点击立即试用&#xff0c;此处务必注意ECS和Redis需要在一个地域(可用区)&#xff0c;否则后续连接不方便。 2. 创建实例 购买后&#xff0c;进入控制台&#xff0c…

Pytorch从零开始实战16

Pytorch从零开始实战——ResNeXt-50算法的思考 本系列来源于365天深度学习训练营 原作者K同学 对于上次ResNeXt-50算法&#xff0c;我们同样有基于TensorFlow的实现。具体代码如下。 引入头文件 import numpy as np from tensorflow.keras.preprocessing.image import Ima…

字体图标操作步骤

网站 直接点击 进去后长这样&#xff0c;点免费的添加 保存下载 保存后解压 把fonts文件夹复制粘贴到我们自己项目 可以放在同images的路径下 引入 来源于 再style中粘贴 font-face {font-family: icomoon;src: url(fonts/icomoon.eot?jyg4cp);src: url(fonts/icomoo…

Java微服务系列之 ShardingSphere - ShardingSphere-JDBC

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 系列专栏目录 [Java项…

使用Go语言通过API获取代理IP并使用获取到的代理IP

目录 前言 【步骤一&#xff1a;获取代理IP列表】 【步骤二&#xff1a;使用代理IP发送请求】 【完整代码】 【总结】 前言 在网络爬虫、数据抓取等场景中&#xff0c;经常需要使用代理IP来隐藏真实的IP地址&#xff0c;以及增加请求的稳定性和安全性。本文将介绍如何使用…

数据结构实验4:链表的基本操作

目录 一、实验目的 二、实验原理 1. 节点 2. 指针 3.链表的类型 3.1 单向链表 3.2 双向链表 3.3 单向循环链表 3.4 双向循环链表 4. 单链表的插入 4.1 头插法 4.2 尾插法 4.3 在指定位置插入元素 5. 单链表的删除 5.1 删除指定数值的节点 5.2 删除指定位置的节点 …

软件测试|Python Selenium 库安装使用指南

简介 Selenium 是一个用于自动化浏览器操作的强大工具&#xff0c;它可以模拟用户在浏览器中的行为&#xff0c;例如点击、填写表单、导航等。在本指南中&#xff0c;我们将详细介绍如何安装和使用 Python 的 Selenium 库。 安装 Selenium 库 使用以下命令可以通过 pip 安装…

Matlab 分段函数(piecewise)

语法 pw piecewise(cond1,val1,cond2,val2,...) pw piecewise(cond1,val1,cond2,val2,...,otherwiseVal)描述 pw piecewise(cond1,val1,cond2,val2,...) 返回分段表达式或函数pw&#xff0c;当cond1为True时&#xff0c;其值为val1&#xff0c;当cond2为True时&#xff0…

优化CentOS 7.6的HTTP隧道代理网络性能

在CentOS 7.6上&#xff0c;通过HTTP隧道代理优化网络性能是一项复杂且细致的任务。首先&#xff0c;我们要了解HTTP隧道代理的工作原理&#xff1a;通过建立一个安全的隧道&#xff0c;HTTP隧道代理允许用户绕过某些网络限制&#xff0c;提高数据传输的速度和安全性。然而&…

PyCharm 设置新建Python文件时自动在文章开头添加固定注释的方法

在实际项目开发时&#xff0c;为了让编写的每个代码文件易读、易于维护或方便协同开发时&#xff0c;我们都会在每一个代码文件的开头做一些注释&#xff0c;如作者&#xff0c;文档编写时间&#xff0c;文档的功能说明等。 利用PyCharm 编辑器&#xff0c;我们只需设置相关设…

MS-DETR论文解读

文章目录 前言一、摘要二、引言三、贡献四、MS-DETR模型方法1、模型整体结构解读2、模型改善结构解读3、一对多监督原理 五、实验结果1、实验比较2、论文链接 总结 前言 今天&#xff0c;偶然看到MS-DETR论文&#xff0c;以为又有什么高逼格论文诞生了。于是&#xff0c;我想查…

12.1SPI驱动框架

SPI硬件基础 总线拓扑结构 引脚含义 DO(MOSI)&#xff1a;Master Output, Slave Input&#xff0c; SPI主控用来发出数据&#xff0c;SPI从设备用来接收数据 DI(MISO) &#xff1a;Master Input, Slave Output&#xff0c; SPI主控用来发出数据&#xff0c;SPI从设备用来接收…

IPv6路由协议---IPv6动态路由(OSPFv3-4)

OSPFv3的链路状态通告LSA类型 链路状态通告是OSPFv3进行路由计算的关键依据,链路状态通告包含链路状态类型、链路状态ID、通告路由器三元组唯一地标识了一个LSA。 OSPFv3的LSA头仍然保持20字节,但是内容变化了。在LSA头中,OSPFv2的LS age、Advertising Router、LS Sequence…

Java中输入和输出处理(三)二进制篇

叮咚&#xff01;加油&#xff01;马上学完 读写二进制文件Data DataInputStream类 FilFeInputStream的子类 与FileInputStream类结合使用读取二进制文件 DataOutputStream类 FileOutputStream的子类 与FileOutputStream类结合使用写二进制文件 读写二进制代码 package 面…

DAPP和APP的区别在哪?

随着科技的飞速发展&#xff0c;我们每天都在与各种应用程序打交道。然而&#xff0c;你是否真正了解DAPP和APP之间的区别呢&#xff1f;本文将为你揭示这两者的核心差异&#xff0c;让你在自媒体平台上脱颖而出。 一、定义与起源 APP&#xff0c;即应用程序&#xff0c;通常指…

使用KubeSphere轻松部署Bookinfo应用

Bookinfo 应用 这个示例部署了一个用于演示多种 Istio 特性的应用&#xff0c;该应用由四个单独的微服务构成。 如安装了 Istio&#xff0c;说明已安装 Bookinfo。 这个应用模仿在线书店的一个分类&#xff0c;显示一本书的信息。 页面上会显示一本书的描述&#xff0c;书籍…