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

將你的 Virtual dom 渲染成 Canvas

開發 后端
一個基于 vue 的 virtual dom 插件庫,按照Vue render 函數的寫法,直接將 Vue 生成的 Vnode 渲染到 canvas 中。支持常規的滾動操作和一些基礎的元素事件綁定。

項目概述
一個基于 vue 的 virtual dom 插件庫,按照Vue render 函數的寫法,直接將 Vue 生成的 Vnode 渲染到 canvas 中。支持常規的滾動操作和一些基礎的元素事件綁定。

demo 地址:https://muwoo.github.io/vnode2canvas/

背景
從一個小的需求說起:某一天,產品提了一個這樣的需求,需要制作一個微信活動頁,活動頁可以分享包含用戶相關信息的圖片。這些信息是需要從接口取的,而且每個人都不一樣。第一次碰到這種需求的時候,基本上都會去手擼 canvasAPI 去做渲染功能,這種情況的步驟大致如下:

  1. 寫一大串 dom template 標簽
  2. 渲染 template 成 dom 標簽
  3. 開始捕捉 dom 元素,繪制 canvas
  4. canvas 渲染圖片

面臨的主要問題是復用性太差,其次是性能上也有問題,用戶看到的界面不一定和正式渲染出的界面一致,可能存在渲染差異。作為一個有追求的前端,當然得想想看有沒有更好的法子。于是乎了解到了一個 html2canvas 這樣一個庫。但是總是感覺還是要轉成 dom 再去繪制,而且感覺性能和穩定性也不是很好。

我們知道 vue 通過 vnode 實現了對不同端的渲染工作,那有沒有可能通過 vnode 實現對 canvas 的渲染呢?也就是說,沒有 vnode -> html -> canvas 而是直接vnode -> canvas。同時利用 vue 的數據驅動,來達到繪制的數據驅動。想法有了,下面開始實施。

調研
這篇文章對此有詳細的介紹:60 FPS on the mobile web 這里簡單的概括一下:

canvas 是一種立即模式的渲染方式,不會存儲額外的渲染信息。Canvas 受益于立即模式,允許直接發送繪圖命令到 GPU。但若用它來構建用戶界面,需要進行一個更高層次的抽象。例如一些簡單的處理,比如當繪制一個異步加載的資源到一個元素上時會出現問題,如在圖片上繪制文本。

在 HTML 中,由于元素存在順序,以及 CSS 中存在 z-index,因此是很容易實現的。dom 渲染是一種保留模式,保留模式是一種聲明性 API,用于維護繪制到其中的對象的層次結構。保留模式 API 的優點是,對于你的應用程序,他們通常更容易構建復雜的場景,例如 DOM。通常這都會帶來性能成本,需要額外的內存來保存場景和更新場景,這可能會很慢。

看來 canvas 繪制頁面的研究,很久之前就已經有人付出過研究了。而且性能還是很不錯的。那我們更要試試看,到底我們的想法能不能實現了!越來越期待....

開始
canvas 的渲染其實也是一種嘗試,既然前人以及做了充分的實踐,那么我們便站在巨人的肩膀上去基于 vue 來實現一個數據驅動的canvas渲染。說做就做!(我們這里只提供思路,不做具體實現細節的討論,因為實現起來有點復雜,如果有興趣可以參考我的項目實現,或者一起交流探討 )

處理 vnode
熟悉 Vue 源碼的應該都知道,Vue 通過 render 函數,傳入 createElement 方法來構造出一個 vnode,通過發布--訂閱模式來實現對數據的監聽,重新生成 vnode。vnode 最后被轉成各平臺所需的視圖。而我們要做的就是在 vnode 這一層開始。所以,我們基于 Vue 源碼的方式,實現一個監聽函數,并混入 Vue 實例中:

  1. Vue.mixin({ 
  2.     // ... 
  3.     created() {      if (this.$options.renderCanvas) { 
  4.         // ... 
  5.         // 監聽vnode中引用的變化,重新渲染 
  6.         this.$watch(this.updateCanvas, this.noop) 
  7.         // ... 
  8.       }    },    methods: {      updateCanvas() {        // 模擬Vue render 函數 
  9.         // 尋找實例中定義的 renderCanvas 方法,并傳入createElement方法 
  10.         let vnode = this.$options.renderCanvas.call(this._renderProxy, this.$createElement) 
  11.       }}) 

這樣我們就可以愉快的在組件內部使用:

  1. renderCanvas (h) { 
  2.   return h(...) 

canvas 元素處理
render 的 vnode 我們需要做額外的一些約束,也就是說我們需要怎么樣的渲染標簽,來渲染對應的 canvas 元素(舉個 ):

  1. view/scrollView/scrollItem --> fillRect
  2. text --> fillText
  3. image --> drawImage

其中這些元素類分別都繼承于一個 Super 類,并且由于它們各有不同的展示方式,因此它們分別實現自己的 draw 方法,做定制化的展示。

繪制對象的布局機制實現
繪制 canvas 布局最基礎的寫法是為 canvas 元素傳入一系列坐標點和相關的基礎寬高,這樣寫到實際項目中可能是這樣的:

  1. renderCanvas(h) { 
  2.   return h('view', { 
  3.      style: { 
  4.        left: 10, 
  5.        top: 10, 
  6.        width: 100, 
  7.        height: 100 
  8.      }  })} 

這樣寫確實有點不方便維護,目前有好幾種解決方案,一種是使用 css-layout去做管理。css-layout 支持的轉換屬性如下:

這樣也只是做了一層轉換,幫我們更好的用 css 思維去寫 canvas,但是如果我們很不爽 css in js 的寫法,其實我們還可以寫一個webpack loader 來加載外部 css:

  1. const css = require('css'
  2. module.exports = function (source, other) { 
  3.   let cssAST = css.parse(source) 
  4.   let parseCss = new ParseCss(cssAST) 
  5.   parseCss.parse()  this.cacheable(); 
  6.   this.callback(null, parseCss.declareStyle(), other); 
  7. };class ParseCss { 
  8.   constructor(cssAST) { 
  9.     this.rules = cssAST.stylesheet.rules 
  10.     this.targetStyle = {} 
  11.   }  parse () {    this.rules.forEach((rule) => { 
  12.       let selector = rule.selectors[0] 
  13.       this.targetStyle[selector] = {} 
  14.       rule.declarations.forEach((dec) => { 
  15.         this.targetStyle[selector][dec.property] = this.formatValue(dec.value) 
  16.       })    })  }  formatValue (string) { 
  17.     string = string.replace(/"/g, '').replace(/'/g, '') 
  18.     return string.indexOf('px') !== -1 ? parseInt(string) : string 
  19.   }  declareStyle (property) {    return `window.${property || 'vStyle'} = ${JSON.stringify(this.targetStyle)}` 
  20.   }} 

簡單的來說:主要也就是將 css 文件轉成 AST 語法樹,之后再對語法樹做轉換,轉成 canvas 需要的定義形式,并以變量的形式注入到組件中。

實現列表滾動
如果我們的元素很多,需要滾動時,我們必須解決 canvas 內部元素滾動的問題。這里我選擇了使用Zynga Scroller 來模擬用戶滾動方法,通過他返回的滾動坐標點,來對 canvas 進行重繪。有興趣的可以參考這里我的實現:

https://github.com/muwoo/vnode2canvas/blob/master/src/core/shape/scrollView.js

事件模擬
對于 click,touch 等 dom 事件的模擬,我們采用的方案是根據點擊區域進行檢測,并找出最底層的元素,遞歸尋找父元素并觸發對應事件處理程序,從而模擬事件冒泡。詳細的實現可以參考這里:

https://github.com/muwoo/vnode2canvas/blob/master/src/core/event.js

最后
canvas 繪制頁面也是一種創新的嘗試,希望這里的研究對你有啟發,也歡迎你的 PR。這里也做了很多性能優化,限于篇幅不在贅述了,有興趣也可以一起探討。

最后:它并不意味著完全取代基于DOM的渲染,這仍然需要文本輸入,復制/粘貼,可訪問性和SEO。出于這些原因,我們可以使用canvas和基于DOM的渲染的組合。

 

責任編輯:姜華 來源: 今日頭條
相關推薦

2022-05-06 19:42:53

DOM

2023-02-28 11:43:35

2022-08-14 23:04:54

React前端框架

2022-12-12 09:01:13

2021-06-21 07:36:32

Virtual DOMDOMvue.js

2021-05-26 05:22:09

Virtual DOMSnabbdom虛擬DOM

2021-07-04 10:07:04

Virtual DO閱讀源碼虛擬DOM

2018-10-22 16:21:50

ChromeHTMLCSS

2025-10-23 09:02:51

2024-01-15 09:23:16

框架方式原生

2023-09-25 10:26:05

DOMCSS

2021-04-20 20:09:56

LinuxScrcpy桌面應用

2012-11-23 17:20:43

Linux服務器

2021-08-31 08:32:40

開源項目開發

2010-06-28 09:53:17

Linux操作系統U盤

2021-02-04 13:00:40

樹莓派Linux

2020-11-25 10:42:57

Python代碼工具

2017-05-10 16:09:12

MySQL數據庫查詢

2020-07-27 09:40:12

Spark SQL模型訓練場景

2021-12-12 18:31:35

VNode組件Vue3
點贊
收藏

51CTO技術棧公眾號

欧美精品一区二区三区在线看午夜| 欧美黑人性视频| 超碰在线97免费| 日本暖暖在线视频| 成人小视频免费观看| 5252色成人免费视频| 一本在线免费视频| ady日本映画久久精品一区二区| 日韩欧美成人免费视频| 亚洲欧洲日韩综合二区| 老牛影视av牛牛影视av| 日韩高清不卡在线| 久久久伊人日本| 亚洲色图 激情小说| 爱高潮www亚洲精品| 欧美午夜在线观看| 欧美亚洲日本一区二区三区| 137大胆人体在线观看| caoporm超碰国产精品| 国产情人节一区| 日本韩国欧美中文字幕| 欧美影院一区| 伊人精品在线观看| 蜜桃精品成人影片| 动漫av一区| 欧美日韩情趣电影| 欧美韩国日本在线| 国产三级伦理在线| 亚洲摸摸操操av| 亚洲国产日韩美| 九色在线观看视频| 99国产精品一区| 超碰97人人人人人蜜桃| 亚洲综合精品视频| 日本中文字幕一区二区视频| 久久人人爽人人爽人人片av高请| 亚洲二区在线播放| 日韩一区二区在线| 色哟哟入口国产精品| 精品少妇人妻一区二区黑料社区| 欧美交a欧美精品喷水| 欧美一二三区在线观看| 日韩av.com| 日韩护士脚交太爽了| 欧美性受xxxx| 青青青国产在线视频| 在线观看v片| 岛国av午夜精品| 欧美激情 国产精品| a级片在线免费| 亚洲6080在线| 婷婷五月综合缴情在线视频| 国产天堂在线播放视频| 亚洲综合999| 久久久久久久香蕉| 色www永久免费视频首页在线| 亚洲欧美一区二区三区极速播放 | 国产精品mv在线观看| 久热精品视频在线观看一区| 在线看的片片片免费| 91精品电影| 久久伊人免费视频| 免费中文字幕在线观看| 亚洲视频福利| 97精品国产97久久久久久免费 | 欧美精品一级二级| 热久久久久久久久| 精品一区二区三区中文字幕视频| 日韩一级欧美一级| 欧美激情 亚洲| 少妇精品久久久一区二区| 亚洲日韩第一页| 欧美巨胸大乳hitomi| 91精品高清| 欧美精品xxx| 在线视频一区二区三区四区| 日韩在线播放一区二区| 成人免费午夜电影| 国产香蕉在线观看| 久久久一区二区三区| 亚州欧美一区三区三区在线| 黄网站在线播放| 亚洲自拍偷拍欧美| 精品免费国产一区二区| 欧美在线se| 精品久久久久久亚洲综合网 | 欧美精品精品精品精品免费| 国产成人亚洲欧洲在线| 日韩成人一区二区三区在线观看| 成人黄色免费网站在线观看| 欧美一级做性受免费大片免费| 久久综合久久综合九色| 一区二区三区四区五区视频| 欧美一卡二卡| 欧美视频一区在线观看| 国产ts在线观看| 九色成人国产蝌蚪91| 日韩视频免费在线| 久久免费激情视频| 激情小说亚洲一区| 久久久久久精| 中文字幕在线观看播放| 色婷婷久久综合| 欧美69精品久久久久久不卡| 经典一区二区| 欧美激情一级精品国产| 亚洲精品一区二三区| 国产精品66部| 亚洲韩国在线| 免费观看欧美大片| 日韩欧美电影一区| 国产成人免费观看网站| 亚洲美女啪啪| 成人欧美一区二区三区黑人孕妇 | 97精品超碰一区二区三区| 亚洲综合网中心| 深夜成人福利| 亚洲黄一区二区| 在线免费日韩av| 免费黄网站欧美| 久久久水蜜桃| 污片视频在线免费观看| 欧美日本一区二区三区四区| 日韩人妻无码一区二区三区| 国内精品嫩模av私拍在线观看| 国产综合视频在线观看| 国模精品一区二区| 欧美日韩国产在线播放| 四虎精品一区二区| 综合久久亚洲| 国产欧亚日韩视频| 尤物网址在线观看| 欧美色大人视频| 蜜桃久久精品成人无码av| 亚洲影视在线| 久久99欧美| 国产精品13p| 日韩欧美一级片| 日本老熟俱乐部h0930| 青青国产91久久久久久| 日本公妇乱淫免费视频一区三区| a日韩av网址| 亚洲免费电影在线观看| 天天操中文字幕| 国产成人精品一区二区三区视频| 黄色www网站| 成人开心激情| 亚洲人成网站在线播| 日韩精品视频免费看| 成人夜色视频网站在线观看| 粉嫩av一区二区三区天美传媒| 亚洲一区av| 久久伊人91精品综合网站| 国产乱人乱偷精品视频a人人澡| 国产精品美女一区二区三区| 国产一区二区在线免费播放| 第一sis亚洲原创| 国产欧美日韩精品在线观看| 毛片av在线| 欧美一个色资源| 国产网站在线看| 99久久久久免费精品国产| 国产a级一级片| 欧洲专线二区三区| 国产精品丝袜视频| 快射av在线播放一区| 欧美一区二区三区影视| 日韩a级片在线观看| 国产成人av一区二区| 欧美日韩性生活片| 欧洲grand老妇人| 国产自摸综合网| 97人澡人人添人人爽欧美| 日韩成人av在线| 最近国语视频在线观看免费播放| 一区二区中文视频| 免费黄色a级片| 国产精品一二| 亚洲午夜久久久影院伊人| 美女日韩一区| 4444欧美成人kkkk| 最新97超碰在线| 日韩美女在线视频| 久久久久久不卡| 亚洲免费av高清| 在线免费观看a级片| 免费在线看一区| 波多野结衣 作品| 久久不见久久见国语| 91精品视频免费看| 精品三级久久| 久久精品成人欧美大片| 蜜臀av在线观看| 欧美日韩一区二区三区高清| 欧美另类视频在线观看| 久久久久99精品一区| 中文字幕第66页| 久久一本综合频道| 久久这里只有精品8| jiujiure精品视频播放| 国产91免费视频| 国产成+人+综合+亚洲欧美| 久久久久久久久久久成人| 福利片在线看| 亚洲高清在线观看| 国产情侣自拍小视频| 欧美性极品xxxx做受| 九九视频免费观看| 中文字幕中文字幕一区| 欧美一级电影免费在线观看| 美女搡bbb又爽又猛又黄www| 日韩中文字幕亚洲一区二区va在线| 欧美日韩一区二区三区电影| 国产欧美久久一区二区三区| 国产福利久久| 97色婷婷成人综合在线观看| 日本三级韩国三级久久| 丁香花在线电影小说观看| 在线观看亚洲区| 午夜成人免费影院| 日韩欧美成人激情| 一区二区三区免费观看视频| 疯狂蹂躏欧美一区二区精品| 免费人成在线观看| 亚洲欧洲日本在线| аⅴ天堂中文在线网| 91麻豆视频网站| 欧美大喷水吹潮合集在线观看| 国模一区二区三区白浆| www.激情网| 久久久久久久久99精品大| 日韩精品伦理第一区| 一本色道久久综合亚洲精品酒店 | 久久青草欧美一区二区三区| 少妇熟女视频一区二区三区| 久久电影网电视剧免费观看| 久久综合久久色| 欧美一级视频| 欧美国产亚洲一区| 亚洲黑丝一区二区| 国产精品久久国产| 亚洲字幕久久| 99久久99久久精品| 国产精品a久久久久| 在线视频一二三区| 国产精品久久久久久久| 中文字幕久久一区| 天天揉久久久久亚洲精品| 无码免费一区二区三区免费播放| 久操成人av| 日韩亚洲欧美精品| 国产欧美日韩精品一区二区三区| 欧美高清性xxxxhd| 亚洲人成精品久久久| 蜜桃在线一区二区三区精品| 亚洲高清极品| 日产精品一线二线三线芒果| 国产一区二区三区四区| 婷婷久久五月天| 91偷拍一区二区三区精品| 国产精品jizz在线观看老狼| 亚洲色图插插| 欧美一级视频在线播放| 香蕉久久国产| 99视频精品免费| 久久精品国产精品亚洲红杏| 深爱五月综合网| 成人午夜在线播放| 蜜桃精品一区二区| 亚洲国产精品成人久久综合一区| 国产精品视频看看| 亚洲综合在线观看视频| 国偷自拍第113页| 欧美视频一区二区三区在线观看| 国产又大又粗又硬| 欧美精品一区二区久久婷婷| 天堂中文字幕在线| 色偷偷亚洲男人天堂| 先锋影音在线资源站91| 2019日本中文字幕| 韩日精品一区| 99电影在线观看| 日本中文字幕在线一区| 亚洲成人第一| 亚洲视频一区| mm1313亚洲国产精品无码试看| 久久精品国产**网站演员| 亚洲美女高潮久久久| 久久久精品国产免大香伊 | 久青青在线观看视频国产| 色噜噜国产精品视频一区二区| 欧美人与牲禽动交com| 欧美亚洲成人精品| 国产aa精品| 欧美视频1区| 伊人久久亚洲热| 国产又粗又长又大的视频| 从欧美一区二区三区| 欧美人与性囗牲恔配| 亚洲一区成人在线| 中文字幕日日夜夜| 亚洲精品大尺度| 超碰porn在线| 国产精品国产三级国产aⅴ浪潮| 日韩中文一区二区| 水蜜桃亚洲精品| 一区二区黄色| 久久国产免费视频| 中文字幕一区二区三区四区不卡 | 欧美一区二区三区视频免费播放| 欧美色视频免费| 欧美激情小视频| 日韩国产91| 少妇精品久久久久久久久久| 99亚洲伊人久久精品影院红桃| 欧美又黄又嫩大片a级| 国产午夜亚洲精品羞羞网站| 日韩视频免费观看高清| 欧美一区二区私人影院日本| av影片在线看| 欧美主播福利视频| 国产乱人伦精品一区| 黄色网zhan| 久久99精品久久久久婷婷| 亚洲 小说 欧美 激情 另类| 亚洲一二三区不卡| 精品美女www爽爽爽视频| 久久久极品av| 欧美爱爱视频| 亚洲国产一区二区精品视频 | 午夜亚洲福利老司机| 国产青青草视频| 精品国产一区二区三区久久久狼 | 99热国产在线中文| 91精品久久久久久久久中文字幕| 国产乱码精品一区二区亚洲| 欧美黄网站在线观看| 久久综合久久99| 丰满少妇xoxoxo视频| 亚洲国产97在线精品一区| 97人澡人人添人人爽欧美| 国产精品免费一区二区| 亚洲视频免费| 精品一区二区视频在线观看| 亚洲va欧美va天堂v国产综合| 亚洲精品国产精品国| 欧美激情免费视频| 波多野结衣欧美| 999在线观看视频| 97精品国产97久久久久久久久久久久 | …久久精品99久久香蕉国产| 欧美日韩夜夜| 伊人成色综合网| 91蝌蚪porny九色| 中文字幕免费观看| 正在播放欧美视频| 成人国产精品| 国产福利片一区二区| 国产裸体歌舞团一区二区| 校园春色 亚洲| 精品国产一区二区三区不卡 | 国产精品日韩在线| 91麻豆国产自产在线观看亚洲| 毛片毛片毛片毛| 一区二区三区欧美亚洲| 人妻精品无码一区二区| 欧美一级大片视频| 精品欧美激情在线观看| 亚洲午夜精品一区| 一区二区三区精品| 亚洲av激情无码专区在线播放| 国产v综合ⅴ日韩v欧美大片| 色综合天天爱| 黑人性生活视频| 午夜精品123| aⅴ在线视频男人的天堂| 91麻豆桃色免费看| 亚洲经典三级| 超薄肉色丝袜一二三| 欧美一区二区三区四区久久| 免费h视频在线观看| 日韩免费三级| 国产91精品一区二区| 欧美h在线观看| 久久精品视频亚洲| 国产精品白丝一区二区三区| 黄色国产精品视频| 亚洲欧美经典视频| 天堂а√在线8种子蜜桃视频 | 成人性生交大片免费看96| 国语对白做受xxxxx在线中国| 国产精品久线在线观看| 国产成人三级在线观看视频| 国产精品一二三在线| 欧美精品麻豆| 国产成人一区二区在线观看| 日韩精品专区在线| 国产韩日精品| 国产视频一视频二| 成人欧美一区二区三区黑人麻豆 |