精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

国产伦精品一区二区三区照片| 尤物yw午夜国产精品视频明星| 成人国产一区二区三区| 国产av精国产传媒| 欧美体内she精视频在线观看| 欧美成人aa大片| av黄色在线网站| 一级日本在线| 成人av午夜电影| 国产精品久久999| 欧美激情一区二区视频| 中文字幕中文字幕精品| 欧美美女一区二区| 日本手机在线视频| 啊v在线视频| 国产河南妇女毛片精品久久久| 欧美亚洲国产日韩2020| 多男操一女视频| 天海翼精品一区二区三区| 欧美日韩大陆在线| 国产精品一区二区免费在线观看| www 日韩| 91香蕉视频污在线| 91精品视频在线| 色屁屁影院www国产高清麻豆| 亚洲先锋影音| 亚洲欧美日韩中文在线| 乳色吐息在线观看| 国产成人精品一区二区三区视频| 亚洲综合免费观看高清完整版| 青青草久久网络| 开心激情综合网| 精品一区二区在线看| 欧美在线性爱视频| 久久精品波多野结衣| 欧美韩国日本在线观看| 日韩精品视频免费专区在线播放| 91丝袜超薄交口足| 日韩高清在线| 欧美午夜www高清视频| 毛片av在线播放| 成人黄色在线电影| 国产精品久久久久婷婷| 欧美一二三四五区| 艳母动漫在线看| 成人深夜视频在线观看| 成人有码视频在线播放| 超碰在线免费97| 日韩精品一二三区| 国产精品99久久久久久久久| 国产精品久久久久久久久久久久久久久久久 | a级大片免费看| 国产精品蜜月aⅴ在线| 欧美性猛交xxxx乱大交蜜桃| 欧美午夜性视频| 欧洲一区二区三区| 亚洲免费av高清| av电影一区二区三区| 蜜桃视频网站在线| 《视频一区视频二区| 亚洲在线欧美| 米奇777四色精品人人爽| 中文字幕av免费专区久久| 欧美一区1区三区3区公司| 飘雪影院手机免费高清版在线观看| 成人免费高清视频在线观看| 国产精品久久久久久免费观看| 国产 欧美 自拍| 成人精品免费看| 精品免费日产一区一区三区免费| 婷婷久久久久久| 99re热这里只有精品免费视频| 国产精选一区二区| 神马久久精品| 久久精品一区二区| 亚洲7777| 国产爆初菊在线观看免费视频网站| 国产亚洲精品中文字幕| 一区二区精品视频| 伊人在我在线看导航| 亚洲国产欧美另类丝袜| 国产精品无码一区二区在线| 456亚洲精品成人影院| 欧美日韩成人综合天天影院 | 国产成人精品1024| 北条麻妃高清一区| 亚洲日本香蕉视频| 中文字幕成人在线观看| 国产免费内射又粗又爽密桃视频| 成人爽a毛片免费啪啪动漫| 五月婷婷色综合| 热久久精品免费视频| 亚洲伊人精品酒店| 欧美精品一区二区三区很污很色的| 国产xxxx视频| 日韩成人激情| 国产+人+亚洲| 男人天堂视频在线| 国产很黄免费观看久久| 欧美另类一区| 嫩草在线视频| 精品久久久久久中文字幕一区奶水 | 不卡一区二区在线观看| 久久视频精品| …久久精品99久久香蕉国产| 中文字幕人妻色偷偷久久| 国产老妇另类xxxxx| 久久精品第九区免费观看 | 99精品视频在线看| 欧美一级做a| 亚洲国产精品推荐| 中文字幕观看av| 亚洲每日更新| 91精品中文在线| 日韩三级电影网| 亚洲人吸女人奶水| 无码人妻丰满熟妇区毛片| 欧美日韩黄网站| 一区二区三区动漫| 日韩三级视频在线| 狠狠色丁香婷婷综合| 另类视频在线观看+1080p| av片哪里在线观看| 欧美三级日韩在线| 三级男人添奶爽爽爽视频| 香蕉久久网站| 国产精品一区二区三| 欧美巨乳在线| 精品久久在线播放| 激情av中文字幕| 亚洲91视频| 国产精品综合网站| 国产尤物视频在线| 欧美日韩亚洲高清| 黄色国产在线视频| 午夜精品亚洲| 91久久偷偷做嫩草影院| 1pondo在线播放免费| 色婷婷亚洲综合| 亚洲观看黄色网| 亚洲电影av| 91在线短视频| av香蕉成人| 69堂国产成人免费视频| 精品人体无码一区二区三区| 久久看片网站| 免费av在线一区二区| 牛牛精品一区二区| 欧美精品一区二区三区久久久| 久久精品99久久久久久| 国产69精品久久777的优势| 免费观看中文字幕| 欧美1区2区3| 欧美日韩福利电影| 国产三级三级在线观看| 亚洲视频一区二区在线观看| 亚洲综合婷婷久久| 久久在线视频免费观看| 91精品久久久久久久久久| 成人p站proumb入口| 欧美三日本三级三级在线播放| 99久久久无码国产精品性 | 日韩av免费看| 国产区视频在线| 欧美日韩一区二区在线视频| 18啪啪污污免费网站| 国内精品伊人久久久久av影院| 精品久久免费观看| 国产精品亚洲欧美日韩一区在线| 久久精品视频免费播放| 成人激情四射网| 亚洲国产精品一区二区久久| 亚洲中文字幕一区| 日韩激情一区二区| 综合网五月天| 视频精品二区| 国产91精品久久久久| 韩日在线视频| 日韩一区二区三区在线| 日韩aaaaaa| 日本一区二区三区dvd视频在线| 无限资源日本好片| 综合天堂av久久久久久久| 国产精品一区二区三区四区五区 | 少妇人妻精品一区二区三区| 欧美性猛交xxxx乱大交极品| 女教师淫辱の教室蜜臀av软件| 国产精品影音先锋| 国产h视频在线播放| 成人av资源电影网站| 91视频国产一区| yellow字幕网在线| 中文字幕一区二区三区电影| 亚洲国产www| 日本韩国一区二区三区| 欧美爱爱小视频| 久久久99精品久久| 中文字幕55页| 日日摸夜夜添夜夜添精品视频| 老汉色影院首页| 欧美亚洲国产日韩| 国产免费亚洲高清| h片在线观看下载| 色婷婷av一区二区三区久久| 秋霞av鲁丝片一区二区| 在线观看亚洲成人| 国产稀缺真实呦乱在线| 国产精品国产三级国产aⅴ原创| 日本少妇一级片| 日韩av一区二区三区四区| www.激情网| av一区二区高清| 国产中文一区二区| www一区二区三区| 国产成人亚洲综合91精品| 欧美色图天堂| 色婷婷成人综合| 国产精品ⅴa有声小说| 欧美精品一区二区久久婷婷| 91欧美日韩麻豆精品| 欧美性猛交xxxx偷拍洗澡| 我家有个日本女人| 国产精品萝li| 国产一二三四五区| av电影在线观看一区| 亚洲制服在线观看| 美国欧美日韩国产在线播放| 国产淫片免费看| 亚洲国产国产亚洲一二三| 亚洲一区精彩视频| 成人av国产| 欧美一级爱爱| 香蕉久久精品日日躁夜夜躁| 国产美女99p| 秋霞影院一区| 91系列在线播放| 亚洲香蕉久久| 91精品国产综合久久香蕉922| 亚洲日本网址| 日本成熟性欧美| a日韩av网址| 欧美亚洲另类在线| 小草在线视频免费播放| 97国产在线观看| a在线视频v视频| 97精品在线观看| 国产乱码精品一区二三赶尸艳谈| 欧美国产日本高清在线| 日韩123区| 欧美激情国产日韩精品一区18| aaa大片在线观看| 久久国产视频网站| 在线看一级片| 色综合久久88色综合天天看泰| av在线播放国产| 欧美激情精品久久久久久黑人| 里番在线播放| 久久久久久久999| 成人高潮aa毛片免费| 欧美精品videos性欧美| a天堂资源在线| 日本亚洲欧美成人| 久久精品女人天堂av免费观看| 国产成人综合一区二区三区| 日韩精品第一| 成人欧美一区二区三区在线| 国产激情精品一区二区三区| 91沈先生在线观看| 国产福利一区二区精品秒拍| 精品不卡一区二区三区| 亚洲最好看的视频| 亚洲精品国产精品国自产观看| 久久国产成人午夜av影院宅| 中文字幕中文字幕在线中一区高清| 综合久久精品| 欧美久久久久久久久久久久久| 久久久青草婷婷精品综合日韩| 九九热在线免费| 国产最新精品免费| 亚洲精品第二页| 国产亚洲欧美中文| 黑鬼狂亚洲人videos| 亚洲综合色成人| 欧美日韩一级黄色片| 欧美群妇大交群的观看方式| 狠狠综合久久av一区二区| 亚洲国内精品视频| jzzjzzjzz亚洲成熟少妇| 欧美成人免费全部| 免费成人在线电影| 国产欧美日韩视频| 国产精品流白浆在线观看| 青青影院一区二区三区四区| 66久久国产| 国产肥臀一区二区福利视频| 美女国产一区二区| 精品无码人妻少妇久久久久久| 亚洲国产高清aⅴ视频| 久久精品www| 欧美三级视频在线观看| 亚洲国产剧情在线观看| 一本大道久久加勒比香蕉| 伊人春色在线观看| 国产精品你懂得| 超碰97久久| 亚洲日本japanese丝袜| 亚洲激情成人| 超碰91在线播放| 国产亚洲美州欧州综合国| 麻豆成人在线视频| 欧美视频一区在线观看| 日本免费不卡视频| 欧美精品免费看| 视频精品导航| 久久这里精品国产99丫e6| 午夜日韩福利| 欧美特级aaa| 久久久久久久综合色一本| 青青草原国产视频| 欧美色综合影院| 精品乱码一区二区三四区视频| 欧美韩日一区二区| 伊人久久大香线蕉综合影院首页| 精品国产一区二区三| 黄色日韩在线| 小早川怜子一区二区三区| 国产亚洲短视频| 国产婷婷色一区二区在线观看| 日韩女同互慰一区二区| 免费网站看v片在线a| 国产精品嫩草视频| 欧美偷拍自拍| 欧美xxxxx在线视频| 91在线看国产| 日韩久久精品视频| 精品国产乱码久久久久久老虎 | 又污又黄的网站| 亚洲人成电影在线| 亚洲一区站长工具| 精品国产一区二区三| 一本综合久久| 精品人妻在线视频| 亚洲午夜av在线| 日本高清视频网站| 性日韩欧美在线视频| 伊人精品久久| 欧美大黑帍在线播放| 成人性生交大合| 国产无遮挡裸体免费视频| 精品久久一区二区三区| 白浆在线视频| 久久精品日产第一区二区三区精品版| 悠悠资源网久久精品| 精品少妇人妻av一区二区三区| 亚洲午夜羞羞片| 天堂在线观看视频| 91精品国产九九九久久久亚洲| 精品欠久久久中文字幕加勒比| 成人毛片一区二区| 久久久无码精品亚洲日韩按摩| 国产伦精品一区二区三区视频我| 伊人av综合网| 国产高清日韩| 欧美图片激情小说| 91久色porny| 超碰在线97观看| 日韩亚洲欧美中文在线| 精品一区二区三区亚洲| 国产精品三级一区二区| 成人av在线资源| 亚洲天堂一区在线观看| 亚洲色图av在线| 97精品资源在线观看| 黄色一级片黄色| xfplay精品久久| 亚洲视频一区在线播放| 欧美精品在线极品| 欧美aaaaaaaa牛牛影院| 欧美黄色一级片视频| 中文字幕一区二区三区乱码在线| 亚洲第九十九页| 日韩免费av一区二区| 999国产精品视频| 在线xxxxx| 欧美唯美清纯偷拍| 欧美人与牲禽动交com| 久久国产精品高清| 久国产精品韩国三级视频| 国产精品成人aaaa在线| 亚洲精品自在久久| 国产一区 二区| 日本精品一区在线观看| 国产精品久久久久久久蜜臀| 蜜臀久久精品久久久久| 国产精品成人一区二区| 中国成人一区| 国产一区二区三区四区五区六区| 日韩精品中文字幕一区| 亚洲日本网址| 国产爆乳无码一区二区麻豆|