精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

學到了!Figma 原來是這樣表示矩形的

開發 前端
Figma 只用寬高和變換矩陣來表達矩形,在數據層可以用精簡的數據表達豐富的變形,此外在渲染的時候也能將矩陣運算交給 GPU 進行并行運算,是不錯的做法。

大家好,我是前端西瓜哥。

今天我們來研究一下 Figma 是如何表示圖形的,這里以矩形為切入點進行研究。

明白最簡單的矩形的表示后,研究其他的圖形就可以舉一反三。

矩形的一般表達

如果讓我設計一個矩形圖形的物理屬性,我會怎么設計?

我張口就來:x、y、width、height、rotation。

對一些簡單的圖形編輯操作,這些屬性基本上是夠用的,比如白板工具,如果你不考慮或者不希望圖形可以翻轉(flip) 的話。

Figma 需要考慮翻轉的情況的,此外還有斜切的情況。

翻轉的場景:

還有斜切的場景,在選中多個圖形然后縮放時有發生。

這些表達光靠上面的幾個屬性是不夠的,我們看看 Figma為了表達這些效果,是怎么去設計矩形的。

Figma 矩形物理屬性

與物理信息相關的屬性如下:

{
  "size": {
    "x": 100,
    "y": 100
  },
  "transform": {
    "m00": 1,
    "m01": 3,
    "m02": 5,
    "m10": 2,
    "m11": 4,
    "m12": 6
  },
  // 省略其他無關屬性
}

沒有位置屬性,這個屬性默認是 (0, 0),實際它轉移到 transform 的矩陣的位移子矩陣上了。

size 表示寬高,但屬性名用的是 x(寬) 和 y(高),理論上 width 和 height 語義更好,這樣應該是用了矢量類型。

size 表示寬高,理論上 width 和 height 語義更好,這樣應該是用了平面矢量類型的結構體,所以是 x 和 y。

transform 表示一個 3x3 的變換矩陣。

m00 | m01 | m02
m10 | m11 | m12
 0  |  0  |  1

上面的 transform 屬性的值所對應的矩陣為:

1 | 3 | 5
2 | 4 | 6
0 | 0 | 1

屬性面板

再看看這些屬性對應的右側屬性面板。

x、y 分別是 5 和 6,它是 (0, 0) 進行 transform 后的結果,這個直接對應 transform.m02 和 tansfrom.m12。

import { Matrix } from "pixi.js";

const matrix = new Matrix(1, 2, 3, 4, 5, 6);
const topLeft = matrix.apply({ x: 0, y: 0 }); // { x: 5, y: 6 }

// 或直接點
const topLeft = { x: 5, y: 6 }

這里引入了 pixi.js 的 matrix 類,該類使用列向量方式進行表達。

文末有 demo 源碼以及線上 demo,可打開控制臺查看結果驗證正確性。

然后這里的 width 和 height,是 223.61 和 500, 怎么來的?

它們對應的是矩形的兩條邊變形后的長度,如下:

uiWidth 為 (0, 0) 和 (width, 0)  進行矩陣變換后坐標點之間的距離。

const distance = (p1, p2) => {
  const a = p1.x - p2.x;
  const b = p1.y - p2.y;
  return Math.sqrt(a * a + b * b);
};

const matrix = new Matrix(1, 2, 3, 4, 5, 6);
const topLeft = { x: 5, y: 6 }

const topRight = matrix.apply({ x: 100, y: 0 });
distance(topRight, topLeft); // 223.60679774997897

最后計算出 223.60679774997897,四舍五入得到 223.61。

高度計算同理。

uiHeight 為 (0, 0) 和 (0, height)  進行矩陣變換后坐標點之間的距離。

const matrix = new Matrix(1, 2, 3, 4, 5, 6);
const topLeft = { x: 5, y: 6 }

const bottomLeft = matrix.apply({ x: 0, y: 100 });
distance(bottomLeft, topLeft); // 500

旋轉角度

最后是旋轉角度,它是寬度對應的矩形邊向量,逆時針旋轉 90 度的向量所對應的角度。

先計算寬邊向量,然后逆時針旋轉 90 度得到旋轉向量,最后計算旋轉向量對應的角度。

const wSideVec = { x: topRight.x - topLeft.x, y: topRight.y - topLeft.y };
// 逆時針旋轉 90 度,得到旋轉向量
const rotationMatrix = new Matrix(0, -1, 1, 0, 0, 0);
const rotationVec = rotationMatrix.apply(wSideVec);
const rad = calcVectorRadian(rotationVec);
const deg = rad2Deg(rad); //

這里用了幾個工具函數。

// 計算和 (0, -1) 的夾角
const calcVectorRadian = (vec) => {
  const a = [vec.x, vec.y];
  const b = [0, -1]; // 這個是基準角度

  // 使用點積公式計算夾腳
  const dotProduct = a[0] * b[0] + a[1] * b[1];
  const d =
    Math.sqrt(a[0] * a[0] + a[1] * a[1]) * Math.sqrt(b[0] * b[0] + b[1] * b[1]);
  let rad = Math.acos(dotProduct / d);

  if (vec.x > 0) {
    // 如果 x > 0, 則 rad 轉為 (-PI, 0) 之間的值
    rad = -rad;
  }
  return rad;
}

// 弧度轉角度
const rad2Deg = (rad) => (rad * 180) / Math.PI;

Figma 的角度表示比較別扭。

特征為:基準角度朝上,對應向量為 (0, -1),角度方向為逆時針,角度范圍限定為 (-180, 180],計算向量角度時要注意這個特征進行調整。

完整代碼實現

線上 demo:

https://codepen.io/F-star/pen/WNPVWwQ?editors=0012

代碼實現:

import { Matrix } from "pixi.js";

// 計算和 (0, -1) 的夾角
const calcVectorRadian = (vec) => {
  const a = [vec.x, vec.y];
  const b = [0, -1];

  const dotProduct = a[0] * b[0] + a[1] * b[1];
  const d =
    Math.sqrt(a[0] * a[0] + a[1] * a[1]) * Math.sqrt(b[0] * b[0] + b[1] * b[1]);
  let rad = Math.acos(dotProduct / d);

  if (vec.x > 0) {
    // 如果 x > 0, 則 rad 為 (-PI, 0) 之間的值
    rad = -rad;
  }
  return rad;
}

// 弧度轉角度
const rad2Deg = (rad) => (rad * 180) / Math.PI;

const distance = (p1, p2) => {
  const a = p1.x - p2.x;
  const b = p1.y - p2.y;
  return Math.sqrt(a * a + b * b);
};

const getAttrs = (size, transform) => {
  const width = size.x;
  const height = size.y;
  const matrix = new Matrix(
    transform.m00, // 1
    transform.m10, // 2
    transform.m01, // 3
    transform.m11, // 4
    transform.m02, // 5
    transform.m12 // 6
  );

  const topLeft = { x: transform.m02, y: transform.m12 };
  console.log("x:", topLeft.x)
  console.log("y:", topLeft.y)

  const topRight = matrix.apply({ x: width, y: 0 });
  console.log("width:", distance(topRight, topLeft)); // 223.60679774997897

  const bottomLeft = matrix.apply({ x: 0, y: height });
  console.log("height:", distance(bottomLeft, topLeft)); // 500

  const wSideVec = { x: topRight.x - topLeft.x, y: topRight.y - topLeft.y };
  // 逆時針旋轉 90 度,得到旋轉向量
  const rotationMatrix = new Matrix(0, -1, 1, 0, 0, 0);
  const rotationVec = rotationMatrix.apply(wSideVec);

  const rad = calcVectorRadian(rotationVec);
  const deg = rad2Deg(rad);
  console.log("rotation:", deg); // -63.43494882292201
};

getAttrs(
  // 寬高
  { x: 100, y: 100 },
  // 變換矩陣
  {
    m00: 1,
    m01: 3,
    m02: 5,
    m10: 2,
    m11: 4,
    m12: 6,
  }
);

運行一下,結果和屬性面板一致。

結尾

Figma 只用寬高和變換矩陣來表達矩形,在數據層可以用精簡的數據表達豐富的變形,此外在渲染的時候也能將矩陣運算交給 GPU 進行并行運算,是不錯的做法。

責任編輯:姜華 來源: 前端西瓜哥
相關推薦

2024-02-06 09:30:25

Figma矩形矩形物理屬性

2022-12-14 07:32:40

InnoDBMySQL引擎

2023-05-22 15:58:11

2022-05-05 08:55:12

工業物聯網IIoT

2018-04-02 15:13:21

網絡

2023-02-15 08:17:38

2025-02-17 09:22:16

MySQLSQL語句

2020-05-26 08:52:36

Java JVM多態

2020-11-24 06:20:02

Linux日志文件系統

2016-10-12 08:54:24

2025-11-24 09:01:03

Flink內存模型

2021-08-17 07:00:00

雙重檢查鎖Nacos

2017-11-02 13:05:12

PC3D NAND內存

2014-07-21 10:32:52

蘋果公司實習

2020-03-23 08:30:12

程序員男友感受

2015-03-25 09:55:34

程序員程序員修補BUG真正原因

2018-10-26 10:41:19

2017-05-09 15:39:33

ensorFlow機器人機器學習

2022-07-13 10:37:59

服務器故障優化

2017-06-06 15:13:07

點贊
收藏

51CTO技術棧公眾號

九九热爱视频精品视频| 超鹏97在线| 日韩成人伦理电影在线观看| 自拍偷拍亚洲在线| 欧美精品 - 色网| 欧美人与牲禽动交com| 91亚洲国产成人精品一区二三| 日韩av色综合| 青青青在线视频| 一区二区导航| 日韩精品一区二区三区在线| 国产熟人av一二三区| 成人在线观看免费网站| 久久久精品免费免费| 99免费在线视频观看| 欧美日韩在线视频播放| 欧美三区不卡| 中文字幕精品网| 黄色国产在线观看| 欧美午夜网站| 欧美亚洲国产一区二区三区va| www.69av| 欧美黑人激情| 久久精品免视看| 高清日韩一区| 97人妻一区二区精品免费视频| 香蕉成人久久| 韩国三级电影久久久久久| 国产精久久一区二区三区| 风间由美一区二区av101| 欧美视频在线观看一区| 精品欧美一区免费观看α√| 污污网站在线看| 国产精品超碰97尤物18| 久久精品国产第一区二区三区最新章节 | 欧美一区二区三区激情| 国内精品久久久久影院色| 日韩免费不卡av| 久久中文字幕免费| 在线一区电影| 久久久av亚洲男天堂| 久久久精品成人| 啪啪亚洲精品| 亚洲色图第三页| 国产三级视频网站| 国产毛片久久久| 精品国产凹凸成av人导航| 中文 日韩 欧美| 精品视频国内| 日韩欧美一二三区| 在线观看你懂的视频| 精品一区二区三区四区五区| 9191成人精品久久| 国产传媒免费观看| 精品国产一区二区三区性色av| 欧美日韩免费观看一区三区| 色免费在线视频| 伊人亚洲精品| 91精品国产一区二区| 欧美一级免费在线| 日韩精品免费视频一区二区三区 | 国产不卡一区二区在线播放| 中文字幕一区二区人妻视频| 日韩av一区二区在线影视| 国产精品久久久久久超碰| 性色av一区二区三区四区| 免费欧美日韩国产三级电影| 91精品国产综合久久香蕉| 99久久久国产精品无码网爆| 国产精品一区一区三区| 成人综合电影| 日韩欧美电影在线观看| 久久精品一区八戒影视| 亚洲一区二三| 性欧美1819sex性高清大胸| 亚洲午夜av在线| 欧美日韩国产精品激情在线播放| 国产精品久久久久av电视剧| 欧美军同video69gay| 国模大尺度视频| 亚洲大片精品免费| 日韩在线免费观看视频| 国产性猛交普通话对白| 亚洲综合二区| 国产日本欧美在线观看| 空姐吹箫视频大全| 国产色综合一区| 亚洲精品天堂成人片av在线播放| 碰碰在线视频| 欧美日韩精品一区视频| jjzz黄色片| 精品久久91| 欧美国产极速在线| 亚洲毛片一区二区三区| 韩国av一区二区三区四区| 国产欧美丝袜| av资源在线观看免费高清| 一区二区在线观看视频| 中文字幕乱码人妻综合二区三区 | 丁香花视频在线观看| 色综合天天做天天爱| 亚洲午夜精品一区| 日韩黄色网络| 久久亚洲成人精品| 欧美日韩综合一区二区三区| 国产精品456露脸| 日韩欧美精品一区二区| 成人福利电影| 91精品在线一区二区| 精品人妻一区二区三区视频| 午夜视频精品| 成人国产精品色哟哟| 免费在线稳定资源站| 一区二区三区欧美激情| 91n.com在线观看| 神马久久av| 欧美激情网站在线观看| 97视频免费在线| 国产欧美日本一区二区三区| 六月婷婷在线视频| 欧美久久亚洲| 久久精品久久久久电影| 国产精品欧美综合| 91香蕉视频mp4| 国产美女永久无遮挡| 中文字幕日本一区| 在线观看欧美日韩| 久久久精品毛片| 91麻豆精品秘密| 男女日批视频在线观看| 欧美成年网站| 麻豆国产精品va在线观看不卡| 91porny九色| 久久久亚洲精品石原莉奈| 97在线国产视频| 日韩成人视屏| 欧美老女人性视频| 国产农村妇女毛片精品| 国产精品成人网| 亚洲色图偷拍视频| 婷婷综合网站| 成人国产精品一区二区| 欧美18hd| 日韩一级高清毛片| 色欲人妻综合网| 国产一区二区导航在线播放| 丰满女人性猛交| 日本成人一区二区| 综合久久五月天| 一二三四区在线| 国产精品久久久久久久久动漫| 伊人国产在线视频| 97视频热人人精品免费| 91在线|亚洲| 日韩影视在线| 亚洲第一男人天堂| av黄色在线播放| 久久亚洲影视婷婷| 亚洲色图久久久| 欧美国产一区二区三区激情无套| 成人羞羞国产免费| a毛片在线观看| 欧美成人性战久久| wwwxxx亚洲| 久久久91精品国产一区二区三区| 91香蕉视频污版| 国产精品久久久久9999赢消| 91麻豆蜜桃| 国产在线天堂www网在线观看| 日韩国产高清视频在线| 在线观看国产区| 亚洲免费在线看| 少妇激情一区二区三区视频| 爽好久久久欧美精品| 在线天堂一区av电影| 一区二区中文字幕在线观看| 欧美亚洲另类制服自拍| 永久免费av在线| 日韩精品中文字幕在线不卡尤物| 亚欧视频在线观看| 亚洲国产精品精华液ab| 精产国品一二三区| 亚洲尤物影院| 99精品一级欧美片免费播放| 噜噜噜天天躁狠狠躁夜夜精品| 国产99久久精品一区二区 夜夜躁日日躁| aaa在线免费观看| 日韩一区二区三区av| 天天操天天干视频| 中文字幕一区二区三区蜜月| 91丨porny丨对白| 蜜桃视频在线一区| 人妻少妇精品无码专区二区| 日韩精品欧美| 久久精品国产精品青草色艺| 四虎视频在线精品免费网址| 91国产高清在线| 顶级网黄在线播放| 亚洲无亚洲人成网站77777| 国产999久久久| 91久久精品一区二区三| 黄色一级视频免费| 欧美激情综合在线| 男人的天堂影院| 精品在线视频一区| 久久久免费视频网站| 欧美日韩午夜| 中文字幕一区二区三区乱码| 综合综合综合综合综合网| 7777精品伊久久久大香线蕉语言| 经典三级一区二区| 久久青草精品视频免费观看| 黄网站在线免费| 一个人www欧美| 香港三日本三级少妇66| 日韩欧美国产精品| 亚洲一区二区色| 色综合天天综合在线视频| 久久久久97国产| 亚洲四区在线观看| 久久视频一区二区三区| 久久青草欧美一区二区三区| 制服丝袜av在线| 国产经典欧美精品| 免费成年人高清视频| 日韩成人精品在线观看| 精品免费国产一区二区| 国产精品毛片一区二区三区| 免费超爽大片黄| 国产精品mm| 狠狠精品干练久久久无码中文字幕 | 久久电影tv| 78色国产精品| 成人bbav| 国内免费久久久久久久久久久| 在线不卡日本v二区707| 超碰91人人草人人干| 黄视频网站在线看| 久久久精品中文字幕| 欧美成人高清在线| 色系列之999| 日韩伦理在线观看| 日韩中文字在线| 麻豆传媒视频在线| 久久久www成人免费精品张筱雨| 69久久夜色| 日韩中文在线中文网三级| 成人福利在线| 自拍偷拍亚洲区| 免费在线观看av| www.亚洲免费视频| 26uuu亚洲电影在线观看| 久久99亚洲热视| 黑人极品ⅴideos精品欧美棵| 久久久久久综合网天天| 草草在线观看| 国产成人av在线| av在线播放一区| 91亚洲精品久久久| 2021年精品国产福利在线| 国产精品高清一区二区三区| 九九热hot精品视频在线播放| 久久99精品久久久久久青青日本 | 亚洲大片免费观看| 欧美天堂亚洲电影院在线播放| 中文字幕乱码视频| 欧美一区二区三区婷婷月色| 亚洲精品免费在线观看视频| 日韩精品在线视频美女| jzzjzzjzz亚洲成熟少妇| 丝袜亚洲另类欧美重口| 中文字幕中文字幕在线十八区 | 国产h视频在线播放| 久久久久国产精品一区二区| 日本美女视频一区| 国产99久久久国产精品| 加勒比一区二区| 亚洲欧洲成人精品av97| 国产精品7777| 欧美午夜免费电影| 精品久久人妻av中文字幕| 精品亚洲一区二区三区四区五区| av在线天堂播放| 久久久欧美一区二区| 外国成人直播| 97人人澡人人爽| 国产欧美亚洲精品a| 四虎免费在线观看视频| 亚洲精品人人| 污污网站在线观看视频| 成人福利在线看| 操她视频在线观看| 精品久久久久久久大神国产| 一级全黄裸体免费视频| 亚洲精品国精品久久99热| 欧美三级黄网| 18一19gay欧美视频网站| 亚洲二区av| 欧美主播一区二区三区美女 久久精品人 | 制服丝袜综合日韩欧美| 国产日本精品| 性鲍视频在线观看| 欧美国产成人在线| 青青操免费在线视频| 69久久夜色精品国产69蝌蚪网| 色鬼7777久久| 欧美激情视频一区| 色综合久久久| 日韩av不卡播放| 日韩午夜高潮| 成人一区二区三区仙踪林| 亚洲国产精品成人久久综合一区| 亚洲男人第一av| 精品欧美乱码久久久久久| 日本三级在线视频| 欧美在线视频a| 美女av一区| 97超碰国产精品| 国内精品久久久久影院一蜜桃| 国产精品无码无卡无需播放器| 午夜精品久久久久久久99水蜜桃| 国产精品一级视频| 色午夜这里只有精品| 国产一区二区三区影视| 蜜桃久久精品乱码一区二区| 亚洲国产婷婷| 日批视频免费看| 亚洲免费在线视频| 国产精品久久婷婷| 色偷偷91综合久久噜噜| 97欧美成人| 水蜜桃一区二区三区| 久久国产日韩| av网站免费在线播放| 午夜精品久久久| 色综合久久久久久| 韩国三级日本三级少妇99| 成人中文字幕视频| 少妇人妻无码专区视频| 成人av综合在线| 日韩黄色一级大片| 亚洲国产精品yw在线观看 | 国产高清在线| 国产成人一区三区| 精品国产一区二区三区| 国产日韩成人内射视频| 国产日本亚洲高清| 丰满人妻一区二区三区四区| 国产一区二区三区直播精品电影| 制服诱惑亚洲| 亚洲午夜在线观看| 国精产品一区一区三区mba视频| 日韩欧美综合视频| 日韩一级黄色片| 超级白嫩亚洲国产第一| 精品无人区一区二区三区竹菊| 亚洲综合国产| 女人黄色一级片| 91精品国产综合久久福利| 亚洲夜夜综合| 久久精品午夜一区二区福利| 久久亚洲不卡| 国产又色又爽又高潮免费| 欧美一级夜夜爽| 成人国产电影在线观看| 欧美另类一区| 久久激情五月激情| 欧美爱爱小视频| 日韩电影大全免费观看2023年上| 黄色亚洲网站| 在线观看成人av| 成人看片黄a免费看在线| 久久久久99精品成人片我成大片| 在线日韩日本国产亚洲| 国内不卡的一区二区三区中文字幕| 999久久欧美人妻一区二区| 99精品黄色片免费大全| 一级一级黄色片| 欧美肥婆姓交大片| 综合亚洲自拍| 国产黄色一区二区三区| 精品国产成人在线| 免费在线看黄网站| 精品国产乱码久久久久久蜜柚| 免费在线观看一区二区三区| 男人操女人的视频网站| 日韩电影免费观看在线观看| 日韩一级视频| 高清在线观看免费| 国产精品久久毛片a| 日本美女一级视频| 97精品久久久| 日韩在线高清| yy6080午夜| 欧美一级在线观看| 蜜桃精品在线| 国产freexxxx性播放麻豆| 国产精品色一区二区三区| 天天躁日日躁狠狠躁喷水| 成人欧美一区二区三区在线湿哒哒|