通过 js 给元素添加动画样式animation属性 ,以及 perspective 属性探究

news2024/11/25 14:20:03

学习关键语句:
js添加动画效果
js控制元素animation属性

写在前面

在制作组件的过程中呢 , 突然觉得这个动画啊应该由用户来决定到底是个啥样 , 但是怎么让用户操作这一步呢 ? 总不能让用户自己去写 css keyframe 吧 , 所以便有了这篇文章 , 同时 , 这篇文章的下半部分我们会一起来看看 perspective 这个属性的效果 , 这个属性比较冷门 , 我也是第一次听说和使用 , 但是使用效果非常惊人 , 所以你先看看目录再说吧.

出于适用性考虑 , 测试内容将使用新建的 html 文件来执行效果

开始

我们先写一个简单的页面 , 页面里面能看到的只有一个青色方块和一个按钮 , 我们将通过按钮赋予方块动画

test.html

<!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>test</title>
    <style>
        button {
            width: 120px;
            height: 40px;
            line-height: 40px;
            outline: none;
            position: absolute;
            left: 100px;
            top: 100px;
        }
        #dad {
            width: 300px;
            height: 500px;
            position: relative;
            top: 200px;
            left: 200px;
        }
        #son {
            width: 100%;
            height: 100%;
            background-color: cyan;
        }
    </style>
</head>
<body>
    <button onclick="addAnimate()"> 按我加动画 </button>
    <div id="dad">
        <div id="son"></div>
    </div>
</body>
<script>
    function addAnimate() {
 
    }
</script>
</html>

在这里插入图片描述

实现加动画的语句为 :
元素.animate( [{ 关键帧 }] , { 普通的animation属性 } )
注: 上面中此时的关键帧数组可直接改为关键帧对象

元素.animate( [{ 关键帧 } , { 关键帧 }] , { 普通的animation属性 } )

js 写法

dom.animate(
	// 关键帧数量大于1的时候必须要用数组包裹 , 只有一个关键帧时也可以使用数组包裹
	{
		width: '500px'
	},
	{
		duration: 1000, // 持续时间
		easing: 'linear', // 规定动画的速度曲线
		delay: 0,// 在动画开始之前的延迟
		iterations: Infinity,// 动画应该播放的次数
		direction: "alternate", // 是否应该轮流反向播放动画
		fill: 'forwards',// 动画是否停在最后一个关键帧
	}
)

现在我们将按钮的事件补充完善

addAnimate 方法

function addAnimate() {
    document.getElementById('son').animate(
        [{
            width: '500px'
        }],
        {
            duration: 1000,
            easing: 'linear',
            delay: 0,
            iterations: 'Infinity',
            direction: 'alternate'
            fill: 'forwards',
        }
    )
}

好的我们现在点击按钮就可以给元素添加动画效果了 , 我们一起来看一看截图
在这里插入图片描述

perspective 属性的学习使用

关于 perspective 属性的学习来自于我阅读这篇文章
https://www.cnblogs.com/yanggeng/p/11285856.html
仅在这里做对我自己有利的整理和总结

引入

我们知道在现实世界中 , 我们看到的物体 , 在无光线折射的情况下 , 普遍存在近大远小的现象 , 一个物体在你眼中的大小和物体与你的距离有关 , 同一个物体在长度趋于无限时在你的眼中末端会消失 .

但是 ,

凡是写过 rotateY 属性的朋友们都知道 , 我们在做水平翻转的时候 , 实际上并没有出现近大远小的情况 , 反而给我们带来的直接视觉效果是元素的宽度一直在改变

这个时候也许有的朋友就会说 , 因为浏览器默认的是使用2D效果 , 我们可以将它改为显示3D效果
emmm你可以试试看 , 不过我测试来看得到的效果也不是理想的 , 需要试验的话请在上述 test.html文件添加以下样式

* {
    transform-style: preserve-3d;
}

测试 perspective 属性

我们使用 perspective 属性来做到视觉上的近大远小 , 我们将上述文件中的 dad 元素样式添加

  • perspective :500px;

将动画修改成水平翻转

  • transform: ‘rotateY(360deg)’

test.html

<!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>test</title>
    <style>
        button {
            width: 120px;
            height: 40px;
            line-height: 40px;
            outline: none;
            position: absolute;
            left: 100px;
            top: 100px;
        }
        #dad {
            width: 300px;
            height: 500px;
            position: relative;
            top: 200px;
            left: 200px;
            perspective :500px;
        }
        #son {
            width: 100%;
            height: 100%;
            background-color: cyan;
        }
    </style>
</head>
<body>
    <button onclick="addAnimate()"> 按我加动画 </button>
    <div id="dad">
        <div id="son"></div>
    </div>
</body>
<script>
    function addAnimate() {
        document.getElementById('son').animate(
            [{
                transform: 'rotateY(360deg)'
            }],
            {
                duration: 4000,
                easing: 'linear',
                iterations: 'Infinity',
                // fill: 'forwards',
                delay: 0,
                // direction: 'alternate'
            }
        )
    }
</script>
</html>

perspective 属性值的选取

通过学习上面提到的那篇文章我们可以得知两个关于 perspective 属性的信息

  1. perspective 属性必须写在父元素中 , 对子元素生效
  2. 属性值的本质是 从 你的眼睛 到 显示屏幕 的距离(单位 : px)

我们知道近大远小 , 所以你离 显示 屏幕的距离越大 , 那么这个物体在你眼中的大小变化就会越小 , 我目前测试是使用 500px 可以获得一个比较好的显示效果

perspective 属性值在 translateZ 存在情况下的异常 的 讨论

注意:这是一个提示和警告
在没有阅读学习文章(https://www.cnblogs.com/yanggeng/p/11285856.html)之前 , 你可能会对我这一小节说的内容存在疑惑 , 但是经过我的验证 , 原文中提到的现象是确实存在的 , 不过这里 , 我会提出和原文作者不同的猜想 , 希望大家如果有自己的想法可以疯狂 cue 我

说的异常是什么?

此处异常体现在 当子元素设定Z轴移动为 0px 时 , 即设定样式 transform: translateZ(0px);
此时 , 无论设置 perspective 属性值为多少 , 元素的大小都不会再变化 ,
同时 , 我发现还存在另一个异常 , 那就是
此时无论是否开启 perspective 属性值 , 对于设定动画 X轴,Y轴,Z轴翻转都将不再生效

你可以通过运行以下代码并在浏览器中检查元素直接修改 perspective 属性值来获得此处提到的异常

<!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>test</title>
    <style>
        button {
            width: 120px;
            height: 40px;
            line-height: 40px;
            outline: none;
            position: absolute;
            left: 100px;
            top: 100px;
        }
        #dad {
            width: 300px;
            height: 500px;
            position: relative;
            top: 200px;
            left: 200px;
            perspective :500px;
        }
        #son {
            width: 100%;
            height: 100%;
            background-color: cyan;
            // 以下为新添加行
            transform: translateZ(0px);
        }
    </style>
</head>
<body>
    <button onclick="addAnimate()"> 按我加动画 </button>
    <div id="dad">
        <div id="son"></div>
    </div>
</body>
<script>
    function addAnimate() {
        document.getElementById('son').animate(null)
        document.getElementById('son').animate(
            [{
                transform: 'rotateY(360deg)'
            }],
            {
                duration: 4000,
                easing: 'linear',
                iterations: 'Infinity',
                // fill: 'forwards',
                delay: 0,
                // direction: 'alternate'
            }
        )
    }
</script>
</html>

原文作者的解释

原文作者解释道所谓元素 , 我们看到的实际上是真正元素在二维平面上的投影 , 所以当 Z轴移动样式为 0px 时 , 真正元素和他的投影重合在了 显示 屏幕上

以上关于投影的说法我觉得有一定道理 , 因为可以使用投影的方式来修改任意元素显示在页面上的颜色和位置

此时无论怎么改变我们的眼睛 到 显示屏幕 的距离(单位 : px)都无法影响到我们看到的元素大小 , 这也对原作者发现的异常算是有个合理的解释

我的疑惑

为什么我会有疑惑 , 因为我在使用 translate 属性时 , 如果设置的属性值为 0px , 那么元素的最终位置和初始位置在我眼中是相同的 , 以上意思是仅在我眼中是相同位置
那么 , 如果说我们看到的元素是真正元素的投影 , 而且真正元素和看到的元素不在同一平面 , 那我们进行水平或者垂直移动并且设置好 perspective 属性值后应该会出现近大远小的现象 , 但是事实是并没有
所以我大胆猜测 , 虽然我们看到的元素是真正元素的投影 , 但实际上他们在同一位置(空间上)

我的猜想

很明显 , 设置了样式 translateZ(0px) 和不设置给我们的效果是不一样的 , 是什么原因导致的呢 ?
我给一个大胆的猜测 , 浏览器虽然默认以2D运行 , 但是在进行空间移动之前 , 可能 , 我是说可能 , 真正元素的位置并不存在 , 只是浏览器解析 html 文件后将元素的投影显示在了他应该在的位置 , 而进行移动之后 , 真正元素才会出现在画面之中(虽然感觉也很扯淡 , 但是反正只是不负责任的猜想 , 欢迎反驳)

perspective-origin 属性的使用

perspective-origin 这个属性是指你是从何视角进行观察的 , 默认是以中心视角 , 所以你运行的时候会发现 , 元素旋转的时候靠近你的上下两个角都会变大 , 是因为你的视角在中心 , 修改你的视角 , 你就会获得不一样的视觉效果
这个属性值 包括两个值 一个是 X 轴的一个是 Y 轴的
可选属性包括 百分比 , 距离(单位:px) , 位置(top , bottom , left , right)
其中自己设定的位置以左上角为原点

你可以在以下文件进行试验
test.html

<!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>test</title>
    <style>
        button {
            width: 120px;
            height: 40px;
            line-height: 40px;
            outline: none;
            position: absolute;
            left: 100px;
            top: 100px;
        }
        #dad {
            width: 300px;
            height: 500px;
            position: relative;
            top: 200px;
            left: 200px;
            perspective :500px;
            // 以下为新增属性
            perspective-origin:0px 0px;
        }
        #son {
            width: 100%;
            height: 100%;
            background-color: cyan;
        }
    </style>
</head>
<body>
    <button onclick="addAnimate()"> 按我加动画 </button>
    <div id="dad">
        <div id="son"></div>
    </div>
</body>
<script>
    function addAnimate() {
        document.getElementById('son').animate(
            [{
                transform: 'rotateY(360deg)'
            }],
            {
                duration: 4000,
                easing: 'linear',
                iterations: 'Infinity',
                // fill: 'forwards',
                delay: 0,
                // direction: 'alternate'
            }
        )
    }
</script>
</html>

写在最后

这个属性的探究确实让我感觉很多冷门的 CSS 样式其实非常有意思 , 而且很少见 , 写这篇花了不少心思 , 原文作者写的非常详细 , 希望了解这个属性的朋友一定要去看看原文 , 包括他的其他文章也很好理解
感谢你的阅读 !

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python+Selenium:Google patent数据爬取

准备工作,已搭建Python环境,安装Selenium pip install selenium -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com 步骤1: 根据Chrome版本下载ChromeDriver 下载链接地址: ChromeDriver - WebDriver for Chrome - Downloads 如在帮助——>关于Ch…

车道线检测-lanedet

源码&#xff1a;https://github.com/Turoad/lanedet 这是一个常见的检测网络整合版本&#xff0c;目前包括的检测网络有&#xff1a; 模型论文介绍 SCNN&#xff0c;RESA论文介绍&#xff0c;UFLD介绍&#xff0c;laneNet|其它相关模型&#xff0c;LaneATT介绍 数据集介绍…

机器学习之归一化

机器学习之归一化1.目的1.1损失函数求解问题1.2 归一化目的2. 归一化2.1 最大值最小值归一化2.2 标准化1.目的 1.1损失函数求解问题 线性回归Loss函数梯度公式 参数含义θ\thetaθ函数参数α\alphaα学习率xjix^i_{j}xji​x:数据集&#xff0c;i:样本&#xff0c;j:特征 【数…

OPengl学习(二)——opengl环境搭建

文章目录0、 概念/准备1、VSOpengl快速添加手动编译2、QT中使用opengl1.pro配置文件2.引入头文件 继承QGLWidget3.实现三个主要函数3、引用0、 概念/准备 opengl官网地址 1、OpenGL 函数库相关的 API 有核心库&#xff08;gl&#xff09;&#xff0c;实用库&#xff08;glu&a…

自动化状态监测和工业4.0解决方案-Softing uaGate SI

某公司为其注塑和反应/挤出系统采用了uaGate SI网关技术并实行了开放且独立于平台的OPC UA标准&#xff0c;以用于设备状态自动化监控&#xff0c;这有助于提高产量并避免机器停机。 自动化状态监测提高了产量并且可避免机器停机。为了将其设备控制系统与IT系统相连接起来&…

最小生成树(Prim算法与Kruskal算法)

一、什么是最小生成树 一个连通图的生成树是一个极小的连通子图&#xff0c;它含有图中全部的n个顶点&#xff0c;但只有足以构成一棵树的n&#xff0d;1条边。我们把构造连通网的最小代价生成树称为最小生成树。 例如下图中①、②、③都是左侧图的生成树&#xff0c;但③是构…

k8s的亲和调度

k8s的亲和调度 出于高效通信等需求&#xff0c;偶尔需要把一些Pod对象组织在相近的位置(同一节点、机架、区域或地区等)&#xff0c;例如应用程序的Pod及其后端提供数据服务的Pod等&#xff0c;我们可以认为这是一类具有亲和关系的Pod对象。 理想的实现方式是允许调度器把第一个…

[附源码]计算机毕业设计springboot高校流浪动物领养网站

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

2022.11.28总结

今天写了条件查询 虽然思路上还说是比较顺&#xff0c;但是还是写了一晚上&#xff0c;因为老是在细节上出现bug&#xff0c;改了好久&#xff0c;踩了好几个坑。 首先大概是因为组件不是确定的&#xff0c;我把ref属性绑定在router-view上&#xff0c;导致我获取不到条件选择…

c++类型转换

目录 1.隐式类型转换和强制类型转换 2.隐式类型转换带来的危险 3.c提供的标准类型转换关键字 4.总结 1.隐式类型转换和强制类型转换 c语言的类型转换可以分为隐式类型转换和强制类型转换。 #include<iostream>using namespace std;int main() {double a 3.14;int …

医疗保健行业的福音是对话式AI吗?

导读对话式AI可以对医疗保健行业产生重大影响&#xff0c;且在许多领域已经产生了影响。如果使用得当&#xff0c;对话式AI可以提高操作效率和临床结果&#xff0c;并减轻医护人员的工作量。 对话式AI技术开启了数字患者护理的新时代。 患者可以随时访问其需要的数据&#xff…

Ubuntu 18.04 + CUDA 11.3.0 + CUDNN 8.2.1 + Anaconda + Pytorch 1.10

Xshell远程连接进行Ubuntu的Pytorch配置写在最前面参考Xshell常用命令Ubantu检查系统的各项配置查看ubuntu系统的版本信息和gcc版本查看Linux的内核版本和系统是多少位的验证机器是否具有n卡各种配置&#xff08;建议不要省略&#xff09;安装vim增加pip镜像源禁用nouveau开启S…

[附源码]计算机毕业设计springboot高校学生摄影作品展示平台

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

app与小程序的区别【开发小程序】

app与小程序&#xff0c;两者有什么区别呢&#xff1f;很多公司在开发app或是开发小程序上比较纠结&#xff0c;二选一不止究竟选哪个好&#xff0c;当然有财力的公司可能会两者都开发。那么下面说说app与小程序的区别是什么&#xff0c;好让大家更好地二选一。 app与小程序的…

单商户商城系统功能拆解39—分销应用—分销等级

单商户商城系统&#xff0c;也称为B2C自营电商模式单店商城系统。可以快速帮助个人、机构和企业搭建自己的私域交易线上商城。 单商户商城系统完美契合私域流量变现闭环交易使用。通常拥有丰富的营销玩法&#xff0c;例如拼团&#xff0c;秒杀&#xff0c;砍价&#xff0c;包邮…

2022小美赛数学建模ABCD赛题思路分析 - 认证杯

一、竞赛信息 考虑到美国大学生数学建模竞赛即将举行&#xff0c;近几年国内院校参加美赛的热情一直比较高涨&#xff0c;去年参赛规模已经突破了30000支队&#xff0c;但是由于美赛需要用英文书写论文&#xff0c;中文和英文的语法和思维差异比较明显&#xff0c;另外美赛参赛…

解决 Android WebView 多进程导致App崩溃

应用场景 应用内有两个位置用到WebView加载页面&#xff0c;具体处理逻辑不能通用。分别扩展了WebView了。应用内独立页面使用Fragment来展示,(采用单Activity架构&#xff09;。应用提供切换语言功能。 问题猜想 一、WebView内核bug 具体路径&#xff1a; 进入app–>设…

[附源码]SSM计算机毕业设计校园征兵及退役复原管理系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

ABAQUS学习之路

ABAQUS入门 首先看模块 1、部件——类似建模 2、属性——给零件添加材料属性 3、装配 4、分析步—— 5、相互作用——创建接触&#xff08;摩擦力&#xff09; 6、载荷——预定义场&#xff08;温度场、力场&#xff09;、边界条件 7、网络——划分网格 8、优化&#…

Libvirt Java API操作QEMU虚拟机(重启,强制关机,挂起,恢复,详情,关机,注销,快照备份等 )(CentOS)

需求背景 有个产品需求&#xff0c;需要在一台linux上装多个虚拟机&#xff0c;然后每个虚拟机单独部署一个产品&#xff0c;然后需要虚拟机的一个产品去控制宿主机中安装虚拟机的状态 注意&#xff1a; 如果虚拟机中装的产品去连宿主机的Libvirt服务&#xff0c;那么虚拟机一…