




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、夢中的婚禮于鵬飛技術解析主題圖形渲染引擎的設計與實現 華為分享與原子化服務 項目設計理念與技術解析JavaScript與Java相互通信Web前端從業者如何學習鴻蒙應用設計理念與核心功能應用背景2D版換裝秀!結合疫情當下的時代背景,彌補新人無法蜜月旅行的遺憾,軟件模擬夢中婚禮的盛況。這是一款傳統Web應用,在鴻蒙系統分布式能力的加持下,迸發出新的活力。核心功能 單機模式單機模式核心功能:切換場景:選擇舞臺場景,切換場景主題。創建精靈:創建精靈元素:人物、裝飾、寵物等。拖拽精靈:拖拽調整精靈擺放位置。縮放精靈:通過縮放改變精靈尺寸。刪除精靈:從場景中移除不需要的精靈。局部替換:新郎/新娘可替換發
2、型與服裝。旋轉精靈:精靈主體旋轉,局部精靈同步操作。核心功能 多端協同多端協同操作,便捷又高效!主設備將應用的部分能力遷移到另一臺設備中(控制面板)。主設備:場景鋪滿,最大化可視區域。從設備:作為控制面板,負責選擇精靈。核心功能 快捷分享華為分享,實現獨立設備之間的應用共享!通過華為的近場通訊技術,將原子化服務快捷的分享給其他設備,打破傳統束縛,分享更方便,服務更貼近。藍牙+WLAN技術解析技術解析Canvas畫布二次編輯選中畫布中的某個精靈平移、縮放、旋轉精靈替換精靈局部內容精靈與其組成部分同比例縮放系統分布式能力多設備協同(控制面板遷移)從設備控制主設備創建精靈技術解析鴻蒙系統分布式渲染引
3、擎業務功能多端協同跨端遷移為什么要自己做渲染引擎?1、目前無鴻蒙專用Canvas圖形引擎。2、Web端圖形引擎體積大,存在DOM api與平臺兼容性代碼,不易抽離邏輯(Pixi6.2.2 500KB)。3、極致壓縮應用體積,輕量化易于分享(應用3MB,引擎4KB)。4、2D圖形復雜度可控,理論與實踐相結合。5、易于擴展,與后期計劃開發的補間動畫、粒子效果、碰撞檢測庫無縫結合。技術選型背景:HarmonyOS2.0(api6)UI界面 :ArkUI(JSUI)系統能力 :java2D圖形渲染引擎渲染引擎最小系統實現保留模式記錄渲染狀態、幾何數據、變換信息。基于多叉樹的場景圖(Scence Gra
4、ph)層次渲染。支持精確點選,擁有完整的事件分發體系。自定義渲染系統坐標系變換(局部-世界坐標系)。基于時間的更新與重繪機制。一套小的算法庫,包含多叉樹尋址、矩陣運算、向量運算、單位化、遞歸更新等內容。Canvas繪制核心原理依賴于canvas標簽所提供的渲染上下文(CanvasRenderingContext2D)對象,該對象包含了所有渲染所需要的屬性和繪制命令。使用translate、rotate和scale這些方法時,變換的是依附在物體本體上的局部坐標系。所有繪制操作都是相對于變換后的物體的局部坐標系進行的。也就是說,在draw函數中定義物體時,其頂點坐標都是相對于局部坐標系原點的偏移。
5、這樣的好處是,只要定義一次后,通過translate、 rotate和scale等操作,便可以將物體變換到任意位置,朝著任意角度,以及任意大小,這是一個非常棒的特性,可分離渲染數據源(不變性)及對渲染數據源的操作(可變性)。translate、rotate和scale這些局部坐標系變換方法都具有累積性,每次變換操作都是相對上一次結果的疊加,可以通過精心設計save和restore的層次來修改這種累積性。const context: CanvasRenderingContext2D = $(#canvas).getContext(2d)堆棧操作:save、restore .坐標系變換:trans
6、fer、rotate、scale、transform、setTransform屬性配置:fillStyle、strokeStyle、lineWidth .繪制操作:moveTo、lineTo、arc、fillRect、stroke、drawImage .Canvas原生api示例旋轉炮臺context.save(); / 整個坦克移動和旋轉(局部坐標系變換),注意變換順序( trs:translate - rotate - scale ) context.translate(20, 20); context.rotate(30 * Math.PI / 180); context.scale(t
7、his.scaleX, this.scaleY); / 繪制坦克主體 context.strokeStyle= #000000 context.strokeRect(this.x, this.y, this.width, this.height) / 炮塔作為第二層,受第一層的save所影響 context.save(); / 炮塔作為整個坦克的一部分,是在上一級變換(trs)后的累積操作 context.rotate(30 * Math.PI / 180) ; / 繪制底座 + 炮管 + 炮口(省略部分代碼) context.fillStyle = #FF0000 context.fllRe
8、ct(0, 0, 30, 2) context.restore();context.restore();Canvas的渲染堆棧context.save(); / 整個坦克移動和旋轉(局部坐標系變換) context.translate(20, 20); context.rotate(30 * Math.PI / 180); / 繪制坦克主體 context.strokeStyle= #000000 context.strokeRect(this.x, this.y, this.width, this.height) / 炮塔作為第二層,受第一層的save所影響 context.save();
9、/ 炮塔作為整個坦克的一部分,是在上一級變換(trs)后的累積操作 context.rotate(30 * Math.PI / 180) ; / 繪制底座 + 炮管 + 炮口(省略部分代碼) context.fillStyle = #FF0000 context.fllRect(0, 0, 30, 2) context.restore();context.restore();RenderState繪制屬性:lineWdith/fillStyle/strokeStyle.仿射矩陣:累乘的最終結果RenderStateRenderState1RenderState2Canvas坐標轉換原理1、使用
10、translate、rotate和scale這些方法時,變換的是依附在物體本體上的局部坐標系。2、所有繪制操作都是相對于變換后的局部坐標系所進行的。這是一個非常棒的特性,可分離渲染數據源(不變性)及對渲染數據源的操作(可變性)。3、translate、rotate和scale這些局部坐標系變換方法都具有累積性,每次變換操作都是相對上一次結果的疊加,可以通過精心設計save和restore的層次來修改這種累積性。渲染引擎架構矩陣矩陣(Matrix)是m個行(Row)和n個列(Column)構成的數組。 在數學中,矩陣(Matrix)是指縱橫排列的二維數據表格,其本質是“向量之間的映射”。線性變換
11、是線性空間中的運動, 而矩陣就是用來描述這種變換的映射。矩陣運算:叉乘 A(mxn) X B(nxp) = C(mxp)矩陣特殊形式:單位矩陣、矩陣的逆、仿射變換矩陣矩陣的叉乘仿射變換矩陣縮放和旋轉可以對圖形進行平移變換包含平移的變換稱為仿射變換,線性變換(縮放和旋轉等)是仿射變換的特殊形式。我們只要知道,使用了仿射變換及齊次坐標系后,就能使用矩陣乘法來統一操作圖形的縮放、旋轉和平移等變換。左圖是仿射變換矩陣的一般形式,矩陣中的每個元素都有一定含義。圖形投影變換整體縮放變換矩陣運算平移矩陣縮放矩陣旋轉矩陣(繞Z軸)旋轉矩陣推導依據矩陣乘法法則,以上關系式用矩陣表示為:三維變換就是比二維變換多了
12、一個 z 軸了,當空間內的物體繞 z 軸旋轉時,我們可以理解為在 xy 平面進行二位變換。實際推到過程與上式類似,只是 z 坐標保持不變:場景圖樹狀“父-子”層級結構。父級數據變化后,同步影響所有子節點;而子節點的數據變化,不影響父節點。通過場景圖的特性,可以實現控制解決各個層級精靈之間的坐標系變換數據同步問題。層次尋址與更新通過場景圖的特性,可以實現控制解決各個層級精靈之間的坐標系變換數據同步問題。通過先根、深度優先遍歷從根節點開始逐層累計矩陣相乘運算結果。事件收集/ 事件注冊/ Application類接管事件的收集與派發,并包含以下幾個關鍵功能:動畫循環的啟動和關閉。提供可以基于不同幀率
13、進行回調的定時器。需要子類實現的update抽象方法。需要子類實現的render抽象方法。需要子類實現的Touch事件分發或響應抽象方法。碰撞檢測(精確點選)Touch事件全局坐標點,依次變換到每個精靈的局部坐標系中。1、依次計算每個精靈的世界-局部矩陣M(世界坐標矩陣求逆)2、確定用戶Touch點世界坐標(x,y),表示為向量OP。3、通過矩陣變換向量得到全局坐標點在此精靈的局部坐標。4、確定該精靈的輪廓數據(0,0,width,height)5、確定碰撞檢測方法:軸向包圍盒(AABB)6、判斷點是否在矩形內。事件分發事件分發采用后根、從右到左的廣度優先遍歷方式。Canvas屬于立即繪制模式
14、,后繪制的圖形層級高。因此從最后繪制的精靈往根節點方向,逐步進行觸摸點的碰撞檢測(后根層次)。精靈移動如何確定精靈組內的局部坐標偏移量?x1y11、已知用戶Touch事件全局坐標 GlobalPt(x,y)2、命中檢測(從下到上、從右到左、深度優先)求當前節點的 局部-世界變換矩陣 GlobalMatrix (從根節點開始到當前節點累計矩陣乘)通過矩陣求逆,得到 世界-局部變換矩陣 LocalMatrix通過矩陣 LocalMatrix 作用于向量GlobalPt,得出該GlobalPt在該精靈內局部坐標 LocalPt檢測LocalPt與該精靈的碰撞3、通過LocalPt修正拖拽偏移量基于時
15、間的更新與重繪通過 requestAnimationFrame() 產生固定的調用頻率,在每一幀內都進行一次場景圖中的各層級矩陣運算,以計算所有元素每一幀的平移、旋轉、縮放數據,并驅動Canvas繪制最新的畫面。/ BaseApplication.js/ 啟動應用主循環start() if (!this._start) this._start = true; / 核心代碼 this._requestId = requestAnimationFrame(msec) = this.step(msec); ); / BaseApplication.jsstep(timeStamp) . 省略代碼 t
16、his.update(elapsedMsec, intervalSec); this.render(); requestAnimationFrame(elapsedMsec) = this.step(elapsedMsec); );JavaScript與Java通信交互LocalParticleAbility通過 LocalParticleAbility 實現 js 調用 java 側代碼,以實現多設備協同能力。createLocalParticleAbility:獲取java接口實例register:注冊接口實例到框架層reply:PA端使用該接口向JS側回調函數發送消息Java方法通過LP
17、A注冊到MainAbility新建JSInterface.java,并實現LocalParticleAbility接口。(js無法實現動態權限申請)public class JSInterface implements LocalParticleAbility private final MainAbility mainAbility; public JSInterface(MainAbility mainAbility) this.mainAbility = mainAbility; 在MainAbility的onStart()方法中,通過調用register()方法,注冊LocalPart
18、icleAbility接口實例到框架層。代碼如下:public class MainAbility extends AceAbility private JSInterface jsInterface; Override public void onStart(Intent intent) super.onStart(intent); jsInterface = new JSInterface(this); jsInterface.register(this); JavaScript通過LPA調用java方法在index.js文件中,調用createLocalParticleAbility()
19、方法,得到Java中LocalParticleAbility接口實例,也即JSInterface調用getNetWorkIdAsync()方法,就會執行到Java中JSInterface定義的方法,參數result是Java端回調結果給JS端的數據var JS_PATH = com.likeyo.dreamwedding.manager.JSInterface;/以實際包名為準 export default data: localNetWorkId:, , async startFA() var that = this; this.javaInterface = createLocalPart
20、icleAbility(JS_PATH); / getNetWorkIdAsync方法名字要和Java中JSInterface類的getNetWorkIdAsync方法名字一致 this.javaInterface.getNetWorkIdAsync(result = that.localNetWorkId = result; this.showDeviceList(); ) Java回調數據給Javascript在requestPermissionAndGetNetWorkId()方法中,先獲取分布式權限(這個權限僅是分布式拉起需要,在獲取設備networkId時一起處理);在成功得到權限后
21、,再調用DeviceManager.createInstance()方法得到設備的networkId;最后調用LocalParticleAbility.Callback類的reply()方法(必須在子線程調用,實現異步操作),將獲取到的設備networkId傳遞給JS中。public class MainAbility extends AceAbility private LocalParticleAbility.Callback callback; public void setCallback(LocalParticleAbility.Callback callback) this.cal
22、lback = callback; public void requestPermissionAndGetNetWorkId() permission = new HPermission(); permission.requestPermissions(this, this:getNetWorkId); private void jsCallBack(String networkId) if (callback != null) new Thread() - callback.reply(networkId).start(); 流程圖動態申請權限獲取在線設備拉起遠程FA動態申請權限拉起遠程FA單例發送控制指令指令完成JSJavaJSJava華為分享華為分享1、創建IDL接口文件 集成IDL接口,用于建立分享方與華為分享的交互通道,完成后續服務分享過程。 在“java”目錄同級目錄創建“idl”接口目錄:com/huawei/hwshare/third(固定路徑),然后創建名為IHwShareCallback.idl和IHwShareService.idl的IDL文件。華為分享通過IDE自
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 文秘工作心得體會
- 2024年湘中幼兒師范高等專科學校輔導員考試真題
- 歷史城市文化政策研究基礎知識點歸納
- 2025年產品開發和設計階段試題
- 智慧空間下高校學生未來學習需求分析
- 特種紙企業經營管理方案
- 小學六年級作文寫事
- 高中思想政治與其他學科融合的現狀與前景
- 2025至2030年中國手挽帶行業投資前景及策略咨詢報告
- 商用車企業經營管理方案
- 2025年福建三明經開區控股集團有限公司子公司招聘筆試沖刺題(帶答案解析)
- 北京市朝陽區2023-2024學年三年級下學期語文期末考試卷
- 2025年馬克思主義基本原理考試復習試卷及答案
- 理論聯系實際談一談如何傳承發展中華優-秀傳統文化?參考答案三
- 酒店拆除工程協議書
- 2025年遼寧省沈陽市于洪區中考二模道德與法治歷史試題
- 人工智能芯片研究報告
- DB43-T 2066-2021 河湖管理范圍劃定技術規程
- 新疆開放大學2025年春《國家安全教育》形考作業1-4終考作業答案
- 機電維修筆試試題及答案
- T-GXAS 421-2022 成人急性中毒洗胃操作技術規范
評論
0/150
提交評論