使用css实现任意大小,任意方向, 任意角度的箭头
使用css实现任意大小,任意方向, 任意角度的箭头
网页开发中,经常会使用到 下拉箭头,右侧箭头
这样的箭头。 一般用css来实现:
{
display: inline-block;
margin: 72px;
border-top: 24px solid;
border-right: 24px solid;
width: 120px;
height: 120px;
transform: rotate(45deg);
}
因为这是利用div的border-top, border-right,然后通过旋转div来实现的。
任意角度的箭头
这里有个问题: 假如需要一个角度为120度的箭头怎么办呢? 由于border-top, border-right一直是90度, 所以仅仅通过旋转不行。
我们可以先把div 旋转45度, 让它成为一个 菱形 然后再伸缩,达到任意的角度, 这样就可以得到一个 任意角度的箭头。由于用到了旋转和伸缩两种变换,所以需要使用transform: matrix(a,b,c,d,e,f) 这个变换矩阵。 这里的6个变量组成了一个3介的变换矩阵
$$
\left[
\begin{matrix}
a & c & e \\
b & d & f \\
0 & 0 & 1
\end{matrix}
\right]
$$
任意点p(x,y)的平移, 旋转, 伸缩变换以及他们的各种组合都可以通过这个变换矩阵做到:
$$
\left[
\begin{matrix}
x \\
y \\
1
\end{matrix}
\right]
\left[
\begin{matrix}
a & c & e \\
b & d & f \\
0 & 0 & 1
\end{matrix}
\right]=
\left[
\begin{matrix}
x' \\
y' \\
1
\end{matrix}
\right]
$$
注:这里用齐次坐标 来表达一个点。 简单说就是p(x, y) 表示为p'(x', y', 1)
平移矩阵
v(x, y) 沿着x轴平移tx, 沿着y轴平移ty。 则有:
x' = x + tx
y' = y + ty
所以平移矩阵:
$$
\left[
\begin{matrix}
x' \\
y' \\
1
\end{matrix}
\right]=
\left[
\begin{matrix}
1 & 0 & tx \\
0 & 1 & ty \\
0 & 0 & 1
\end{matrix}
\right]
\left[
\begin{matrix}
x \\
y \\
1
\end{matrix}
\right]
$$
旋转矩阵
v(x, y) 点绕原点旋转θ到v'(x', y')
则有:
x = r * cos(ϕ )
y = r * sin(ϕ )
x' = r * cos(θ + ϕ) = r * cos(θ) * cos(ϕ) - r * sin(θ) * sin(ϕ ) // 余弦公式
y' = r * sin(θ + ϕ) = r * sin(θ) * cos(ϕ) + r * cos(θ) * sin(ϕ ) // 正弦公式
所以:
x' = x * cos(θ) - y * sin(θ)
y' = x * sin(θ) + y * cos(θ)
所以旋转矩阵:
$$
\left[
\begin{matrix}
x' \\
y' \\
1
\end{matrix}
\right]=
\left[
\begin{matrix}
cos(θ) & -sin(θ) & 0 \\
sin(θ) & cos(θ) & 0 \\
0 & 0 & 1
\end{matrix}
\right]
\left[
\begin{matrix}
x \\
y \\
1
\end{matrix}
\right]
$$
伸缩矩阵
假设x轴,y轴的伸缩率分别是kx, ky。 则有:
x' = x * kx
y' = y * ky
所以:
$$
\left[
\begin{matrix}
x' \\
y' \\
1
\end{matrix}
\right]=
\left[
\begin{matrix}
kx & 0 & 0 \\
0 & ky & 0 \\
0 & 0 & 1
\end{matrix}
\right]=
\left[
\begin{matrix}
x \\
y \\
1
\end{matrix}
\right]
$$
复合变换
如果是对p(x, y)先平移(变换矩阵A), 然后旋转(变换矩阵B), 然后伸缩(变换矩阵C)呢?
p' =C(B(Ap)) ==> p' = (CBA)p //矩阵乘法结合率
现在任意角度o的箭头就很简单了:
- 先把div旋转45度 成为 菱形, 变换为 M1
- 伸缩x轴, y轴 :
x' = size * cos(o/2) = x * √2 * cos(o/2)
y' = size * sin(o/2) = y * √2 * sin(o/2)
即: kx = √2 cos(o/2); ky = √2 sin(o/2)
这样就得到了任意角度的箭头。 变换为M2
如果箭头的方向不是指向右侧, 在进行一次旋转就可以得到任意方向的箭头。变换为M3
那么由于 p' =C(B(Ap)) ==> p' = (CBA)p, 我们就可以先计算出 M3M2M1,然后对div进行相应的变换,就可以得到任意角度, 任意方向的箭头了。
div的width和height就是箭头的边长, 通过调整可以获取任意边长的箭头。
React组件
为了方便使用, 这个箭头被封装为了一个 React组件。git地址
示例
| 简单箭头 | 模拟select | 发散箭头 |
|---|---|---|
props
| name | type | default | description |
|---|---|---|---|
| degree | number | 90 | 箭头的张角, 角度制 |
| offsetDegree | number | 0 | 箭头的方向,默认指向右边 |
| color | string | - | 箭头的颜色 |
| size | string | 10px | 箭头边长 |
安装使用
npm install rc-arrow --save
import Arrow from 'rc-arrow'
class Hw extends Component {
render() {
return (
<Arrow size="20px" color="red"/>
)
}
}
使用css实现任意大小,任意方向, 任意角度的箭头的更多相关文章
- PHP图像裁剪为任意大小的图像,图像不变形,不留下空白
<?php /** * 说明:函数功能是把一个图像裁剪为任意大小的图像,图像不变形 * 参数说明:输入 需要处理图片的 文件名,生成新图片的保存文件名,生成新图片的宽,生成新图片的高 */ fu ...
- linux c使用socket进行http 通信,并接收任意大小的http响应(三)
使用socket进行http通信的时候,浏览器返回的响应经常不是固定长度的,有时候很大,有些时候又非常小,十分讨厌.如果仅仅只是为了接收一小段信息,设置一个十分大的缓存,这样又会十分浪费.而且经常更改 ...
- linux shell 脚本攻略学习10--生成任意大小的文件和文本文件的交集与差集详解
一.生成任意大小的文件(dd命令): 举例: amosli@amosli-pc:~/learn/example$ ; + records in + records out bytes ( MB/s a ...
- oracle 产生一个任意大小的随机数
SELECT DBMS_RANDOM.RANDOM FROM DUAL; 产生一个任意大小的随机数 SELECT ABS(MOD(DBMS_RANDOM.RANDOM,100)) F ...
- 用python生成你想要的任意大小文件
在测试的日常工作中,我们经常会需要测试上传文件的边界值.今天分享一段30行的简单代码,可以生成任意大小的文件,方便测试. file_size=input("请输入想要生成文件的大小:(单位M ...
- 通过 NewLife.XCode 迁移任意现有数据库到任意数据库
通过 NewLife.XCode 迁移任意现有数据库到任意数据库(附分表分库方法) 本文背景是将其他系统的数据库迁移到另一个数据库(仅需 20 行代码),也可以作为项目迁移用,生成自己系统的专属实体代 ...
- js 获取任意一个元素的任意一个样式属性的值
//谷歌,火狐支持console.log(window.getComputedStyle(my$("dv"),null).left);//IE8支持console.log(my$( ...
- hdu5795 A Simple Nim 求nim求法,打表找sg值规律 给定n堆石子,每堆有若干石子,两个人轮流操作,每次操作可以选择任意一堆取走任意个石子(不可以为空) 或者选择一堆,把它分成三堆,每堆不为空。求先手必胜,还是后手必胜。
/** 题目:A Simple Nim 链接:http://acm.hdu.edu.cn/showproblem.php?pid=5795 题意:给定n堆石子,每堆有若干石子,两个人轮流操作,每次操作 ...
- Pop–实现任意iOS对象的任意属性的动态变化
简介 Pop 是一个可扩展的动画引擎,可用于实现任意iOS对象的任意属性的动态变化,支持一般动画,弹性动画和渐变动画三种类型. 项目主页: pop 最新示例: 点击下载 注意: 官方代码中,并不包含实 ...
随机推荐
- MySQL查看数据库中所有表占用的空间大小
select TABLE_NAME, concat(truncate(data_length/1024/1024,2),'MB') as data_size, concat(truncate(inde ...
- Qt:QVector
0.说明 template <typename T> class QVector QVector是存储同一个类型T数据的模板类,其功能是动态数组,数据在其中的存储是一系列连续的存储空间. ...
- Excel:获取等差时间
假设:从0:01:05开始,每隔1分30秒生成一个时间项 做法: 在A2处写 =TIME( 0,1,5 )构建一个TIME类型0:01:05,如果要构建别的时间,就按照TIME( 时 , 分 , 秒 ...
- Java:常用语句
学习时可参考: Java在线文档(中文版) Java官方文档(英文版) 0.基本 0.1.导入某个Module import java.util.List;import java.util.Array ...
- LeetCode-061-旋转链表
旋转链表 题目描述:给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置. 示例说明请见LeetCode官网. 来源:力扣(LeetCode) 链接:https://leet ...
- netty搭建rpc框架
介绍 netty想必大家都不陌生,我就不废话介绍了...(主要是懒,网上资料很多的) 本文主要使用netty搭建rpc远程调用框架,实现了个注册中心微服务,整合了springboot例子... 开发内 ...
- tp5.0使用JWT完成token认证技术
1.安装 composer require firebase/php-jwt 2.封装(在框架根目录extend下新建Token.php) 复制代码 <?php use Firebase\JWT ...
- 微信小程序获取当前的时间戳
js文件中进行计算var timestamp = Date.parse(new Date()); timestamp = timestamp / 1000; console.log(timestamp ...
- laravel 框架登录 实际操作
//登录中间件 Route::group(['middleware'=>'checkage'],function (){ Route::get('/mou/list','MouControlle ...
- nginx配置负载均衡分发服务器笔记
记录学习搭建nginx负载均衡分发服务器的过程笔记 1.服务器IP:192.168.31.202(当前需要搭建nginx负载均衡分发的服务器)安装好nginx 2.在服务器IP:192.168.31. ...