精品欧美一区二区三区在线观看 _久久久久国色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-04-30 08:22:51

Figma圖形編輯變換矩陣

2022-12-14 07:32:40

InnoDBMySQL引擎

2022-05-05 08:55:12

工業物聯網IIoT

2023-05-22 15:58:11

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

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

2011-05-25 09:58:46

C#
點贊
收藏

51CTO技術棧公眾號

欧美日韩在线精品| 午夜精品在线视频| 日本少妇一区二区三区| 久久www人成免费看片中文| 国产成a人亚洲| 性欧美在线看片a免费观看| 久久久久无码精品国产sm果冻 | 狠狠干狠狠久久| 亚洲va韩国va欧美va精四季| 成人av免费播放| 视频在线观看一区| 九九精品在线视频| 欧美做受高潮6| 51精品国产| 欧美在线啊v一区| 国产一二三在线视频| 二区在线视频| av电影天堂一区二区在线观看| 国产va免费精品高清在线| 国产黄色小视频网站| 香蕉视频一区| 欧美成人精品3d动漫h| 国产精彩免费视频| 黄网av在线| 国产精品丝袜久久久久久app| 国产精品一区二区三区精品| www.五月婷婷.com| 亚洲精品极品| 九色精品免费永久在线| 国产成人在线网址| 你懂的视频欧美| 亚洲成人av片| 欧美国产日韩另类| 欧美日韩不卡| 欧美性极品xxxx做受| 欧洲精品在线播放| 成人在线影视| 综合精品久久久| 五月天丁香综合久久国产| 色中色在线视频| 成人精品国产免费网站| 亚洲综合av影视| 91亚洲欧美激情| 日韩va亚洲va欧美va久久| 欧美亚洲第一区| 日本免费观看视| 狠狠色丁香久久综合频道| 搡老女人一区二区三区视频tv| 欧美多人猛交狂配| 先锋影音国产精品| 日韩不卡在线观看| yy6080午夜| 国内精品国产成人国产三级粉色| 日韩女优毛片在线| 在线观看欧美一区二区| 日韩影片在线观看| 欧美不卡激情三级在线观看| 国产男女无遮挡猛进猛出| 色综合视频一区二区三区日韩 | 91av在线免费观看视频| 日本少妇激情舌吻| 日韩视频一区| 2020久久国产精品| 99精品在线播放| 先锋影音久久| 国产精品中文字幕久久久| 亚洲视频久久久| 精品一区二区三区视频| 91中文字幕在线| 精品人妻少妇AV无码专区| 国产高清亚洲一区| 极品尤物一区二区三区| 五月天福利视频| 国产三级一区二区三区| 亚洲午夜精品久久久久久浪潮| 男人和女人做事情在线视频网站免费观看| 国产精品欧美久久久久无广告| 宅男av一区二区三区| av免费在线观看网址| 亚洲一级二级在线| 欧美极品欧美精品欧美图片| 日本在线中文字幕一区二区三区| 欧美日韩亚洲综合在线 | 亚洲五码在线| 亚洲精品久久久久久久久久久久久 | 风流少妇一区二区| 精品视频一区二区三区四区| 国产三区四区在线观看| 亚洲欧美另类图片小说| 国产一级爱c视频| 草民电影神马电影一区二区| 日韩欧美中文字幕公布| 91精品人妻一区二区三区蜜桃欧美| 成人精品亚洲| 欧美激情久久久久久| 无码人妻av一区二区三区波多野 | 91成人观看| 久久久久久高潮国产精品视| 国内精品福利视频| 精品制服美女久久| 久久riav二区三区| 色开心亚洲综合| 午夜久久久久久电影| 天天干天天干天天干天天干天天干| 精品视频在线观看网站| 精品亚洲一区二区三区在线播放| 性色国产成人久久久精品| 亚洲激情视频| 成人春色激情网| 日本一区二区三区在线观看视频| 亚洲欧美一区二区三区久本道91| 国产91美女视频| 蜜桃在线一区| 中文字幕日韩精品有码视频| 在线看成人av| 国产一区二区不卡| 日韩一本精品| 国产夫妻在线播放| 日韩欧美国产高清| 精品少妇一区二区三区密爱| 亚洲伊人网站| 成人h在线播放| 国产在线高清视频| 欧美性猛片aaaaaaa做受| 亚洲天堂美女视频| 午夜欧美精品| 91精品网站| 麻豆tv免费在线观看| 色94色欧美sute亚洲线路一ni| 中国xxxx性xxxx产国| 亚洲成av人片一区二区密柚| 国产精品美女呻吟| 日本天堂在线| 福利一区福利二区微拍刺激| 国产吃瓜黑料一区二区| 中文字幕免费一区二区| 亚洲一区二区三区在线视频 | 久久久久久久久国产精品| 国产精品嫩草影院精东| 中文字幕欧美激情一区| 黄色高清无遮挡| 美日韩中文字幕| 欧美一级淫片aaaaaaa视频| 日韩在线观看视频网站| 亚洲线精品一区二区三区八戒| 天天av天天操| 欧美午夜一区二区福利视频| 亚洲自拍偷拍在线| www在线免费观看视频| 欧美高清性hdvideosex| 97在线观看视频免费| 国产在线播放一区三区四| 日本黄色播放器| 日韩毛片免费看| 久久久国产影院| 99精品视频免费看| 亚洲午夜久久久久久久久久久| 三级网站免费看| 激情久久久久| 久久综合中文色婷婷| 校园春色亚洲色图| 一区二区三区国产在线观看| 在线免费一区二区| 中文字幕一区二区三区精华液 | 国产性天天综合网| 91精品无人成人www| 欧美疯狂party性派对| 91九色单男在线观看| caoporm免费视频在线| 欧美不卡视频一区| 久久久久久少妇| 欧美国产在线观看| 日本一二三区在线| 亚洲大胆在线| 日韩欧美在线电影| 国产日韩中文在线中文字幕| 色综合视频一区中文字幕| 天天操天天干天天舔| 欧洲视频一区二区| 国产av 一区二区三区| 成人性色生活片| 国内外成人激情视频| 日韩在线观看一区| 粉嫩av免费一区二区三区| 天堂网在线最新版www中文网| 亚洲图片在线综合| 国产乱码精品一区二区三区精东| 亚洲国产日韩a在线播放| 少妇按摩一区二区三区| 老色鬼精品视频在线观看播放| 成年丰满熟妇午夜免费视频| 天堂一区二区三区四区| 国产欧美精品日韩精品| jizz一区二区三区| 自拍偷拍亚洲欧美| 国模人体一区二区| 欧美综合亚洲图片综合区| 欧美又粗又大又长| 久久精品这里都是精品| 中文字幕在线观看视频www| 久久精品30| 日韩一级免费看| 日韩理论片av| 久久久com| 亚洲一二三区视频| 国产精品无av码在线观看| 51精品在线| 久久精品视频亚洲| 久久久久久青草| 精品国产乱码久久久久久牛牛| 国产乱码在线观看| 欧美日韩国产精品一区二区三区四区 | 欧美日韩一区二区免费在线观看| 亚洲少妇xxx| 久久久久九九视频| 亚洲中文字幕无码一区| 国内精品久久久久影院薰衣草 | 国产一区二区三区精品久久久 | 国产丝袜在线视频| 欧洲视频一区二区| 免费的毛片视频| 午夜精品一区二区三区三上悠亚| 久久高清内射无套| 国产精品乱人伦| av网在线播放| 久久亚洲精品国产精品紫薇| 图片区偷拍区小说区| 国产麻豆视频精品| 亚洲欧美自拍另类日韩| 日韩激情一区二区| 99热成人精品热久久66| 在线综合视频| 欧美不卡在线播放| 狠狠入ady亚洲精品| 国产精品无码电影在线观看| 在线中文一区| 99精品一级欧美片免费播放| 久久国产影院| 亚洲一区不卡在线| 日韩精品久久| 亚洲一区二区免费视频软件合集| 欧美裸体在线版观看完整版| 欧洲久久久久久| 亚洲最好看的视频| 日本10禁啪啪无遮挡免费一区二区| 欧美中文一区| 免费观看成人在线| 国产99久久| 日韩av在线电影观看| 欧美伦理影院| 欧美爱爱视频网站| 香蕉综合视频| 日韩中文在线字幕| 欧美三级特黄| 青青青免费在线| 国产精品久久久久久模特| 久久久亚洲国产精品| 亚洲国产免费看| 日韩在线一级片| 久久在线精品| 免费一区二区三区在线观看| 九色porny丨国产精品| 一级 黄 色 片一| 国产成人亚洲综合a∨婷婷| 特级特黄刘亦菲aaa级| 91偷拍与自偷拍精品| 波多野结衣a v在线| 国产精品色在线观看| 一区二区在线观看免费视频| 亚洲成人自拍网| www欧美在线| 欧美日韩1234| 亚洲欧美强伦一区二区| 亚洲男人7777| 精品孕妇一区二区三区| 欧美激情精品久久久久| 欧美成人影院| 91香蕉嫩草影院入口| 成人黄色av网址| 日本一区二区精品| 亚洲一级毛片| 免费黄色福利视频| 久久精品国产在热久久| 丰满少妇xbxb毛片日本| 久久精品亚洲麻豆av一区二区| 日本精品在线免费观看| 亚洲成人免费av| 国产99久久久久久免费看| 日韩三区在线观看| 精品福利视频导航大全| 久久综合亚洲社区| a一区二区三区| 91亚洲午夜在线| 伊人久久综合影院| 四虎精品欧美一区二区免费| 亚洲欧美视频| gogo亚洲国模私拍人体| 久久久五月婷婷| 久久久久亚洲av无码专区| 91福利在线免费观看| 亚洲AV无码成人片在线观看| 亚洲人线精品午夜| heyzo在线播放| 91丝袜美腿美女视频网站| 夜夜春成人影院| 国产av熟女一区二区三区 | 欧美午夜精品在线| 国产绳艺sm调教室论坛| 亚洲一二在线观看| 91豆花视频在线播放| 91精品视频免费| 精品免费一区二区| 成人免费aaa| 国产v综合v亚洲欧| 美女网站视频色| 日本韩国精品在线| 欧美一区二区公司| 美日韩精品免费视频| 国产成人a视频高清在线观看| 久久riav| 99热在线精品观看| www.com日本| 亚洲欧美日韩系列| 一本色道久久综合精品婷婷 | 欧美丰满美乳xxⅹ高潮www| 亚洲国产成人91porn| 国产日韩一级片| 精品国产拍在线观看| 成人久久网站| 五月天亚洲综合情| 丝袜a∨在线一区二区三区不卡| 亚洲av永久无码精品| 亚洲综合成人在线视频| 国产视频在线观看免费| 精品国产美女在线| 91精品麻豆| 永久久久久久| 久久成人免费网站| 男女男精品视频网站| 欧洲一区二区三区免费视频| 国产黄色在线播放| 国产精品对白刺激| 精品久久91| 国产又黄又猛又粗又爽的视频| 久久精品亚洲一区二区三区浴池| 91丝袜一区二区三区| 亚洲乱码国产乱码精品精| 日本蜜桃在线观看视频| 久久久一本精品99久久精品| 免费日韩视频| 精品人妻无码一区二区三区换脸 | 国产女人爽到高潮a毛片| 久久久www成人免费精品| 精品91福利视频| 91视频 - 88av| 99热在这里有精品免费| 久久精品国产成人av| 亚洲欧美中文字幕| ww久久综合久中文字幕| 中文字幕一区二区中文字幕| 国产一区不卡在线| 久久久久亚洲天堂| 国产丝袜视频一区| 一二区成人影院电影网| 亚洲日本理论电影| 国产精品自产自拍| 久久久久久久蜜桃| 亚洲乱码国产乱码精品精天堂 | 亚洲最大福利视频| 很黄很黄激情成人| 91网站免费视频| 欧美人xxxx| 波多野结衣在线播放| 欧美日韩在线播放一区二区| 美女网站一区二区| 看片网站在线观看| 亚洲欧洲日产国产网站| 国产精品久久久久久久久久辛辛 | 亚洲欧美偷拍卡通变态| 国产黄色一级大片| 77777少妇光屁股久久一区| 视频一区欧美| 日韩av影视大全| 午夜激情一区二区| 日日夜夜精品一区| 国产伦精品一区二区三区四区视频| 久久综合九色| 午夜少妇久久久久久久久| 亚洲男人天堂2024| 九九99久久精品在免费线bt| 九一国产精品视频| 中文字幕一区二区三区蜜月| 天堂国产一区二区三区| 国产中文欧美精品| 99精品国产在热久久| 潘金莲一级黄色片| 亚洲美女在线视频| 中文字幕av一区二区三区四区| 丁香啪啪综合成人亚洲| 一级精品视频在线观看宜春院|