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

圖形編輯器開發:自定義光標

開發 前端
光標(游標)在圖形界面交互中是非常基礎的一環。它是一個指針,懸浮在屏幕的最上層。除了可以標記出指針的當前位置,同時也會通過它獨特的樣式,提示用戶此時可以執行怎么的操作。

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

今天來講講如何在圖形編輯器中使用自定義光標,并對光標其進行管理。

編輯器 github 地址:

https://github.com/F-star/suika

線上體驗:

https://blog.fstars.wang/app/suika/

自定義光標的意義是什么?

光標(游標)在圖形界面交互中是非常基礎的一環。

它是一個指針,懸浮在屏幕的最上層。除了可以標記出指針的當前位置,同時也會通過它獨特的樣式,提示用戶此時可以執行怎么的操作。

比如抓手(grab)光標,是一個展開的手掌,表示可以對目標進行拖拽操作。

縮放(xx-resize)光標,是一個有方向的單(雙)箭頭,表示可以往特定方向移動以改變目標大小。

長得像英文字母 I 的文字(text)光標,則提示可以進行文字的操作,細瘦的垂直線是為了更好地點中字符之間的空白區域。

點擊(pointer)光標,一根手指(食指,不是中指)伸出來是要干嘛,是為了試探,看到按鈕就嘗試點一下,表示某個區域是可點擊的。

操作系統有豐富的光標樣式可以選擇,在 Web 網頁中可以通過  cursor 樣式屬性進行設置。

對于一般應用來說,通常是夠用的。但對于一個成熟的圖形編輯器來說,這還遠遠不夠。

我們還需要一些 更具體的光標樣式來向用戶傳遞信息,比如:

  • 旋轉光標:表示圖形可旋轉。cursor 屬性中沒有旋轉光標,勉強可用抓手工具做個平替;
  • 支持任意度數的縮放光標。cursor 屬性的縮放光標只有 45 度的正數倍數光標,這精度遠遠不夠。
  • 鋼筆工具相關光標:鋼筆光標、錨點光標、新增/刪除點光標;

等等。

此外,自定義光標還有一個很重要的作用,就是 實現不同平臺的視覺一致性。

不同操作系統的 UI 風格是不同的,它們的光標是相當不一致的,會給用戶帶來不同的體驗。

(我希望在 Windows 系統看到 MacOS 的光標)

如何支持自定義光標

沒有光標,我們自己造。

好在 cursor 是支持自定義光標的。

具體用法如下。

.suika-cursor-default {
  cursor: url(./cursor-icons/suika-cursor-default.png) 5 5, pointer;
}

值依次為:

  • url(<url>):自定義光標的圖片資源 url,因為不大且不希望額外作為單獨資源加載,通常會選擇轉換為 base64 格式內嵌;
  • x y:使用相對圖片左上角的像素位置作為光標位置;
  • <keyword>:如果沒有指定自定義光標圖片,或者加載光標資源失敗,就會使用瀏覽器支持的光標值,比如  pointer。

我們需要繪制好光標圖片,然后導出為 png(背景為透明度),然后定義好 x 和 y,再通過 css 類包裹一下,然后根據需要在 Canvas 上設置對應的 css 樣式即可。

多種旋轉角度的旋轉和縮放光標

有兩種光標比較特殊,它們有特殊的旋轉角度的參數。

它們就是旋轉和縮放光標。

因為 cursor 這個 css 屬性并不支持設置旋轉角度,所以我們只能繪制 0 到 359 之間度數共 360 個不同的旋轉光標圖片。

縮放光標因為其樣式中心對稱的原因,倒是不需要這么多,只要繪制 0 到 179 共 180 個圖片。

然后是 精細度的問題。

你這里可以整一些貓膩,比如偷懶,抽走一些度數,只給偶數的度數,比如 2、4,奇數的度數都丟掉,沒有 1、3 這些度數。設置光標的時候舍入一下,找最接近的度數。

或者你精益求精,你說間隔 1 度未免太大,我們要更精確一點,我們不僅支持整數,我們還要支持 1.5、6.5 這種中間值,我們要用 720 個圖片。

沒問題,都可以上。

批量生成方案

但是呢,我們發現,這些光標其實都來自一個源圖片,只是旋轉了不同的角度,我們手工一個個操作未免太低效了。

這時候我們就可以自己寫或找一些工具,批量對一張源圖形生成旋轉多種角度后的圖片,然后再寫個腳本去自動生成 css 代碼,把這些圖片引入進去。

這是一個方案,figma 是這么做的。

感覺還是有億點麻煩。沒事,我們有另一個方案。

上面做的是打包前生成大量圖片,那我們可不可以在運行時動態生成光標呢?

可以的。圖片有位圖的,也有矢量的啊,我們可以用一種叫做 SVG 的特殊圖片格式,它的內容是文本,一種的 xml 文本。

我們可以將光標 UI 導出為 SVG,然后在最頂層的元素加上 transform 的旋轉變換。

可以寫一個方法,傳入角度和位置信息,動態生成對應的 SVG 字符串,然后轉成 DataURL 給 cursor 應用上。

大概像這樣:

const getRotationIconDataUrl = (degree, x = 0, y = 0) => {
  return `url("data:image/svg+xml,
   ...
   <g fill='none' transform='rotate(${degree} ${x} ${y})'
   ...
  ") ${x} ${y}, pointer`
}

canvas.style.cursor = getRotationIconDataUrl(114.544);

開源白板工具 tldraw 選擇了這個方案。

你可以給一個精度很高的旋轉度數。

模塊設計

代碼設計上,我們會設計一個 CursorManager 類進行光標的管理。

這個類最重要的作用就是設置光標值。

setCursor 方法接收一個光標值,除了支持傳統的字符串,也支持 { type: 'rotation'; degree: 45 } 這種形式。

它主要做了如下操作:

  • 標準化光標值,比如把度數取余到 0~360 內。
  • 比較新舊光標值,相同就跳過。
  • 清空原來設置的光標樣式。
  • 根據光標不同,執行各自的邏輯。

下面是核心代碼實現。

// 支持的光標類型
export type ICursor =
  | 'default'
  | { type: 'resize'; degree: number }
  | { type: 'rotation'; degree: number }
  | 'grab'
 | ...
}

class CursorManager {
  private cursor: ICursor;

  setCursor(cursor: ICursor) {
    // 1. 標準化光標值,比如把度數取余到 0~360 內
    cursor = this.normalizeCursor(cursor);
    // 2. 比較新舊光標值,相同就跳過
    if (isEqual(cursor, this.cursor)) {
      return;
    }
    this.cursor = cursor;
    
    const clsPrefix = 'suika-cursor-';
    // 3. 清空原來設置的光標樣式
    canvasElement.classList.forEach((className) => {
      if (className.startsWith(clsPrefix) {
        canvasElement.classList.remove(className);
      }
    });
    this.editor.canvasElement.style.cursor = '';
    
    // 4. 根據光標不同,執行各自的邏輯
    if (this.customClassCursor.has(cursor)) {
      // 這個是注冊了 class 的光標
      const className = `${clsPrefix}${cursor}`;
      this.editor.canvasElement.classList.add(className);
    } else if (typeof cursor == 'string') {
      // 用瀏覽器自帶的
      this.editor.canvasElement.style.cursor = cursor;
    } else if (cursor.type === 'resize') {
      // 后面都是使用動態 svg 字符串
      this.setResizeCursorInCanvas(cursor.degree);
    } else if (cursor.type === 'rotation') {
      this.setRotationCursorInCanvas(cursor.degree);
    }
  }
}

繪制在畫布上的光標

光標還有一種比較少用的方案,也說說吧。

就是有些光標是繪制在畫布上的。

一個經典的例子就是 AutoCAD 的十字光標,這個十字的長度是可以設置的,可以相當長。

如果你修改操作系統的光標,那這個十字便會突破天際地顯示到非繪制區域上。

此外,AutoCAD 的光標并不忠實跟隨操作系統光標,比如有時候會吸附于某點不動,并基于它的位置顯示下拉菜單,此時可以用真正的光標去點選。

考慮到性能,建議把光標放到另一個 canvas 上,和圖形放一個 canvas 會讓畫布中沒做任何操作的圖形頻繁重繪。

結尾

總結一下。

關于圖形編輯器的光標,我們有以下方案:

  • 使用瀏覽器本身就提供的一些光標值。優點是成本低,缺點是樣式有限,且不同操作系統風格差異大;
  • cursor 支持自定義光標,所以我們可以自己設置自己的一套光標去應用。但其中有一些比較特殊的有各種旋轉方向的光標,需要做特別的處理。一種是用工具批量生產光標圖片,一種是利用 svg 在運行時動態生成;
  • 最后是在畫布上渲染光標的方案,適合一些有特殊需求的圖形編輯器。這類圖形編輯器的光標往往可以自定義,且可以非常大,或是它們在某些場景下會脫離鼠標的控制,喜歡特立獨行,比如突然吸附到某個吸附點上。缺點是實現比較復雜,你可能需要像管理圖形一樣去管理它。
責任編輯:姜華 來源: 前端西瓜哥
相關推薦

2023-10-20 08:02:25

圖形編輯器前端

2023-07-07 13:56:01

圖形編輯器畫布縮放

2011-03-17 09:45:01

Spring

2023-10-19 10:12:34

圖形編輯器開發縮放圖形

2010-11-16 13:21:08

Oracle命令行

2023-09-07 08:24:35

圖形編輯器開發繪制圖形工具

2023-08-31 11:32:57

圖形編輯器contain

2023-09-26 07:39:21

2023-09-11 09:02:31

圖形編輯器模塊間的通信

2023-10-08 08:11:40

圖形編輯器快捷鍵操作

2023-10-10 16:04:30

圖形編輯器格式轉換

2023-08-28 08:10:50

Hex圖形編輯器

2024-01-03 08:43:17

圖形編輯器旋轉控制點縮放控制點

2023-07-31 08:46:07

圖形編輯器圖形自動對齊

2023-02-06 16:59:57

Canvas編輯器

2023-04-07 08:02:30

圖形編輯器對齊功能

2023-01-18 08:30:40

圖形編輯器元素

2023-02-01 09:21:59

圖形編輯器標尺

2023-06-12 08:22:56

圖形編輯器工具

2023-05-09 08:15:32

圖形編輯器撤銷重做功能
點贊
收藏

51CTO技術棧公眾號

亚洲第一视频在线播放| 精品国产视频在线| 国产精品一区二区久久久| 自拍偷拍你懂的| 亚洲午夜免费| 国产欧美一区二区三区沐欲| 国产精品久久久久av免费| 性活交片大全免费看| 欧美电影免费看| 国产精品麻豆视频| 极品尤物一区二区三区| 在线免费观看av片| 国产视频一区在线观看一区免费| 自拍偷拍亚洲欧美| 久久久久成人精品无码中文字幕| 无遮挡爽大片在线观看视频 | 欧美色图一区二区三区| 在线免费观看成人网| 天堂在线视频网站| 狠狠色狠狠色合久久伊人| 热久久这里只有精品| 最新一区二区三区| 成人6969www免费视频| 精品国产成人系列| 超碰91在线播放| jizzjizz中国精品麻豆| 国产成人在线看| 国产精品毛片a∨一区二区三区|国 | 中文字幕日韩高清在线| 欧美日韩一卡二卡三卡 | 色网在线免费观看| 一区二区免费视频| 一区二区三区四区五区视频| 免费在线黄色网址| 国产原创一区二区三区| 欧美亚洲午夜视频在线观看| 精品在线视频观看| 91精品一区二区三区综合| 国产亚洲日本欧美韩国| 色呦呦一区二区| 国产精品视屏| 精品剧情v国产在线观看在线| 天天操狠狠操夜夜操| 亚洲天堂资源| 精品久久久久久久大神国产| 国产av熟女一区二区三区| 九七久久人人| 亚洲欧美偷拍卡通变态| 日本日本精品二区免费| 青青草免费在线视频| 91麻豆精品秘密| 精品午夜一区二区| 五月婷婷开心中文字幕| 99精品热视频| 狠狠色综合色区| 三级毛片在线免费看| a在线欧美一区| 精品欧美一区二区在线观看视频| 刘亦菲久久免费一区二区| 国产成人av一区二区| 国产精品10p综合二区| 亚洲国产精品视频在线| 国产一区二区精品在线观看| 亚洲一区二区中文字幕| www.色呦呦| 波多野结衣91| 欧美日韩国产不卡在线看| 天天操天天操天天操| 9久草视频在线视频精品| 国产一区免费| 国自产拍在线网站网址视频| 欧美激情综合五月色丁香小说| 亚洲成人18| a天堂中文在线官网在线| 一区二区三区毛片| 激情综合在线观看| 99久久精品无免国产免费 | 黄色免费网址大全| 国语自产精品视频在线看抢先版结局| 欧美日韩电影在线| 少妇熟女视频一区二区三区| 盗摄牛牛av影视一区二区| 亚洲精品美女视频| 免费视频91蜜桃| 888久久久| 69久久夜色精品国产69乱青草| 精品人妻一区二区色欲产成人| 亚洲精品久久久狠狠狠爱| 亚洲电影在线一区二区三区| 亚洲视频在线看| 在线观看免费av网址| 盗摄系列偷拍视频精品tp| 国产一区二区三区视频 | 日韩三级电影网| 国产精品久久久一本精品| 99国产精品白浆在线观看免费| 深夜成人在线| 91精品黄色片免费大全| 亚洲一区二区乱码| 先锋资源久久| 人妖精品videosex性欧美| 国产三级午夜理伦三级| 91蝌蚪porny成人天涯| 超碰免费在线公开| 自拍偷拍亚洲视频| 日韩视频在线观看一区二区| 国产又爽又黄无码无遮挡在线观看| 999国产精品999久久久久久| 97在线观看免费高清| 国产精品久久久久久久久毛片 | 国产乱码精品1区2区3区| 加勒比在线一区二区三区观看| 日本最新在线视频| 一本色道久久综合狠狠躁的推荐| 精品人妻一区二区三| 精品欧美久久| 97在线观看免费| 午夜精品久久久久久久96蜜桃| 久久久综合九色合综国产精品| 日韩精品免费一区| 四虎在线精品| 国产一区二区三区在线| 日本三级午夜理伦三级三| 狠狠色丁香久久婷婷综合丁香| 美女被啪啪一区二区| 欧美色图天堂| 欧美一区二区三区婷婷月色| 中文字幕在线观看免费高清| 国产精品久久久亚洲一区| 国产成人亚洲欧美| 97caopor国产在线视频| 欧美日韩成人激情| 公肉吊粗大爽色翁浪妇视频| 在线综合视频| 国产三区二区一区久久| 91蜜桃在线视频| 91.com在线观看| 免费一级suv好看的国产网站| 久久久久久久高潮| 欧美精品成人一区二区在线观看 | 成人国产精品av| 自拍视频在线播放| 欧美一a一片一级一片| b站大片免费直播| 久久视频一区| 日本不卡在线观看| 亚洲欧美在线成人| 一区二区三区四区在线观看视频| 中文字幕一区在线播放| 91在线免费播放| 日本黄色三级大片| 国产伦精品一区二区三区千人斩| 3d动漫精品啪啪一区二区竹菊| 屁屁影院国产第一页| 亚洲巨乳在线| 久久久久久久免费| 羞羞影院欧美| 色播久久人人爽人人爽人人片视av| 午夜一区二区三区四区| 久久亚洲二区三区| 女同一区二区| 天堂av最新在线| 精品动漫一区二区三区在线观看| 九九精品在线观看视频| 成人精品视频一区| 精品中文字幕av| 九色porny自拍视频在线观看 | 天堂中文视频在线| 欧美一区2区| 国产一区私人高清影院| 中文字幕第一页在线播放| 丝袜美腿高跟呻吟高潮一区| 天堂一区二区三区| 午夜免费福利在线| 久久porn| 人体精品一二三区| 成人日日夜夜| 亚洲国产精品va在线看黑人| 亚洲影院在线播放| 国产精品对白交换视频| 佐佐木明希电影| 久久国产精品久久久久久电车| 亚洲高清视频一区二区| 免费观看亚洲视频大全| 欧美一级大片在线免费观看| 97在线观看免费观看高清| 91精品国产全国免费观看| 欧美人妻一区二区| 国产午夜精品一区二区| 深夜福利网站在线观看| 久久激情久久| 麻豆映画在线观看| 久久成人高清| caoporen国产精品| 福利一区和二区| 欧美精品videos性欧美| 二人午夜免费观看在线视频| 91精品免费在线观看| 五月婷婷亚洲综合| 日韩久久一区二区| 91中文字幕永久在线| 国产精品一区二区在线观看不卡| 99999精品视频| 欧美一区二区三区久久精品茉莉花| 蜜桃91精品入口| 欧美第一在线视频| 国产精品久久久久久久久久| 成年人国产在线观看| 日韩中文字幕在线精品| 日本1级在线| 欧美成人精品1314www| 在线观看日本视频| 亚洲无线码一区二区三区| 黄色激情小视频| 久久免费的精品国产v∧| 亚洲乱妇老熟女爽到高潮的片| 秋霞午夜鲁丝一区二区老狼| 奇米影视亚洲色图| 欧美一区高清| 一区二区三区四区久久| 国产探花在线精品一区二区| 国产精品国产一区二区| 欧美经典一区| 成人精品久久av网站| 亚洲第一二三四区| 2020久久国产精品| 99re6在线精品视频免费播放| 久久久999精品免费| 91短视频版在线观看www免费| 日韩精品小视频| 日本人妻熟妇久久久久久| 日韩欧美在线123| 99久久久国产精品无码免费| 欧美日韩精品欧美日韩精品一 | 欧美喷水一区二区| 久久久999久久久| 色播五月激情综合网| 国产精品一区二区三区四| 亚洲国产日韩a在线播放| 久久久www成人免费毛片| 亚洲精选视频免费看| 在线看的片片片免费| 一色屋精品亚洲香蕉网站| 丁香六月激情综合| 国产精品久久网站| 黄色片子在线观看| 亚洲男人的天堂网| 欧美毛片在线观看| 性欧美大战久久久久久久久| 久久视频免费看| 亚洲成人免费视频| 日韩av一区二区在线播放| 亚洲超碰精品一区二区| 日本熟妇乱子伦xxxx| 婷婷开心激情综合| 国产黄色免费观看| 欧美影片第一页| 亚洲天堂狠狠干| 91精品免费在线观看| 精品人妻无码一区二区| 精品少妇一区二区三区在线播放| 亚洲免费一级片| 日韩第一页在线| 日本在线丨区| 国产亚洲欧美aaaa| 国产激情在线| 国内精品国产三级国产在线专| 激情aⅴ欧美一区二区欲海潮 | 久久av网站| 国产精品一区二区免费| 日韩美脚连裤袜丝袜在线| 欧美一区二区三区精美影视| 不卡av一区二区| 91精品国产吴梦梦| 在线亚洲成人| www.夜夜爽| 成人免费毛片app| 日韩精品无码一区二区三区久久久| 欧美国产欧美亚州国产日韩mv天天看完整 | 欧美影院在线| 久久久福利视频| 久久久综合色| 女人帮男人橹视频播放| 老司机一区二区三区| 亚洲va在线va天堂va偷拍| 懂色中文一区二区在线播放| 在线免费观看麻豆| 亚洲精品成人天堂一二三| www.日本精品| 欧美疯狂性受xxxxx喷水图片| 丰满肉嫩西川结衣av| 国产亚洲精品美女久久久| 色呦呦在线看| 国产精品激情av电影在线观看 | 国产高清视频色在线www| 国产精品高精视频免费| 999久久久精品一区二区| 日本在线一区| 国内精品久久久久久久97牛牛| 激情综合网婷婷| 国产成人一区二区精品非洲| 欧美亚一区二区三区| 亚洲激情五月婷婷| 国产成人av免费| 亚洲丁香婷深爱综合| 美女羞羞视频在线观看| 欧美福利视频在线观看| 成人精品国产| 久久偷看各类wc女厕嘘嘘偷窃 | 中文欧美字幕免费| 日本亚洲欧美在线| 欧美一区二区三区婷婷月色| 成年人在线视频免费观看| 7777精品久久久久久| 美国十次综合久久| 亚洲一区二区三区精品动漫| 欧美亚洲三区| 无码一区二区精品| 亚洲午夜久久久久久久久久久 | 亚洲成人第一| 久久福利一区| 午夜av免费看| 午夜视频一区二区| 免费av一级片| 久99久在线视频| 99精品美女视频在线观看热舞| 欧美日韩亚洲一区二区三区在线观看| 国内精品久久久久久久影视麻豆 | 国产美女永久无遮挡| 久久国产精品第一页| 亚洲午夜久久久久久久国产| 欧美日韩亚洲系列| 色婷婷中文字幕| 久久全球大尺度高清视频| 亚洲一级大片| 精品人妻人人做人人爽| 狠狠色丁香婷婷综合久久片| 中文字幕求饶的少妇| 欧美日本在线播放| av黄色在线观看| 国产精品永久在线| 成人免费在线观看av| 三级a在线观看| 亚洲国产成人私人影院tom| 国产一区二区视频免费| 亚洲欧美中文在线视频| 性欧美gay| 亚洲精品第一区二区三区| 日本不卡不码高清免费观看| 亚洲黄色小说视频| 在线观看视频一区二区欧美日韩| 欧美大片aaa| 国产精品精品一区二区三区午夜版| 久久成人av| 四季av一区二区三区| 中文字幕一区在线观看视频| 国产精品欧美激情在线| 久久综合伊人77777| 伊人久久影院| 激情伊人五月天| 久久久99精品久久| 伊人免费在线观看| 美女少妇精品视频| 国产精品久av福利在线观看| 欧美不卡在线播放| 久久久久久黄色| 91av久久久| 久久99精品视频一区97| 老司机成人在线| 妓院一钑片免看黄大片| 中文字幕在线观看一区二区| 国产免费福利视频| 97在线精品视频| 日本激情一区| 4438x全国最大成人| 黑人巨大精品欧美一区二区一视频| 国产黄在线观看| 91美女片黄在线观| 亚洲深夜激情| 国产黄色录像片| 亚洲电影av在线| 亚洲成人激情社区| 草草草视频在线观看| 99国产欧美另类久久久精品| 国产精品无码一区| 欧美精品videos另类日本| 精品精品久久| 69久久精品无码一区二区| 欧美性猛交xxxx| 亚洲羞羞网站| 日本一区二区久久精品| 国产麻豆午夜三级精品| 亚洲免费在线视频观看| 久久天天躁夜夜躁狠狠躁2022| 欧美a级网站| 天天操精品视频| 色综合色狠狠天天综合色| 中文字幕有码在线视频| 欧美一区二区三区电影在线观看| 国产传媒日韩欧美成人|