夢(mèng)中的婚禮-51CTO公開課_第1頁
夢(mèng)中的婚禮-51CTO公開課_第2頁
夢(mèng)中的婚禮-51CTO公開課_第3頁
夢(mèng)中的婚禮-51CTO公開課_第4頁
夢(mèng)中的婚禮-51CTO公開課_第5頁
已閱讀5頁,還剩43頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、夢(mèng)中的婚禮于鵬飛技術(shù)解析主題圖形渲染引擎的設(shè)計(jì)與實(shí)現(xiàn) 華為分享與原子化服務(wù) 項(xiàng)目設(shè)計(jì)理念與技術(shù)解析JavaScript與Java相互通信Web前端從業(yè)者如何學(xué)習(xí)鴻蒙應(yīng)用設(shè)計(jì)理念與核心功能應(yīng)用背景2D版換裝秀!結(jié)合疫情當(dāng)下的時(shí)代背景,彌補(bǔ)新人無法蜜月旅行的遺憾,軟件模擬夢(mèng)中婚禮的盛況。這是一款傳統(tǒng)Web應(yīng)用,在鴻蒙系統(tǒng)分布式能力的加持下,迸發(fā)出新的活力。核心功能 單機(jī)模式單機(jī)模式核心功能:切換場(chǎng)景:選擇舞臺(tái)場(chǎng)景,切換場(chǎng)景主題。創(chuàng)建精靈:創(chuàng)建精靈元素:人物、裝飾、寵物等。拖拽精靈:拖拽調(diào)整精靈擺放位置。縮放精靈:通過縮放改變精靈尺寸。刪除精靈:從場(chǎng)景中移除不需要的精靈。局部替換:新郎/新娘可替換發(fā)

2、型與服裝。旋轉(zhuǎn)精靈:精靈主體旋轉(zhuǎn),局部精靈同步操作。核心功能 多端協(xié)同多端協(xié)同操作,便捷又高效!主設(shè)備將應(yīng)用的部分能力遷移到另一臺(tái)設(shè)備中(控制面板)。主設(shè)備:場(chǎng)景鋪滿,最大化可視區(qū)域。從設(shè)備:作為控制面板,負(fù)責(zé)選擇精靈。核心功能 快捷分享華為分享,實(shí)現(xiàn)獨(dú)立設(shè)備之間的應(yīng)用共享!通過華為的近場(chǎng)通訊技術(shù),將原子化服務(wù)快捷的分享給其他設(shè)備,打破傳統(tǒng)束縛,分享更方便,服務(wù)更貼近。藍(lán)牙+WLAN技術(shù)解析技術(shù)解析Canvas畫布二次編輯選中畫布中的某個(gè)精靈平移、縮放、旋轉(zhuǎn)精靈替換精靈局部?jī)?nèi)容精靈與其組成部分同比例縮放系統(tǒng)分布式能力多設(shè)備協(xié)同(控制面板遷移)從設(shè)備控制主設(shè)備創(chuàng)建精靈技術(shù)解析鴻蒙系統(tǒng)分布式渲染引

3、擎業(yè)務(wù)功能多端協(xié)同跨端遷移為什么要自己做渲染引擎?1、目前無鴻蒙專用Canvas圖形引擎。2、Web端圖形引擎體積大,存在DOM api與平臺(tái)兼容性代碼,不易抽離邏輯(Pixi6.2.2 500KB)。3、極致壓縮應(yīng)用體積,輕量化易于分享(應(yīng)用3MB,引擎4KB)。4、2D圖形復(fù)雜度可控,理論與實(shí)踐相結(jié)合。5、易于擴(kuò)展,與后期計(jì)劃開發(fā)的補(bǔ)間動(dòng)畫、粒子效果、碰撞檢測(cè)庫無縫結(jié)合。技術(shù)選型背景:HarmonyOS2.0(api6)UI界面 :ArkUI(JSUI)系統(tǒng)能力 :java2D圖形渲染引擎渲染引擎最小系統(tǒng)實(shí)現(xiàn)保留模式記錄渲染狀態(tài)、幾何數(shù)據(jù)、變換信息?;诙嗖鏄涞膱?chǎng)景圖(Scence Gra

4、ph)層次渲染。支持精確點(diǎn)選,擁有完整的事件分發(fā)體系。自定義渲染系統(tǒng)坐標(biāo)系變換(局部-世界坐標(biāo)系)?;跁r(shí)間的更新與重繪機(jī)制。一套小的算法庫,包含多叉樹尋址、矩陣運(yùn)算、向量運(yùn)算、單位化、遞歸更新等內(nèi)容。Canvas繪制核心原理依賴于canvas標(biāo)簽所提供的渲染上下文(CanvasRenderingContext2D)對(duì)象,該對(duì)象包含了所有渲染所需要的屬性和繪制命令。使用translate、rotate和scale這些方法時(shí),變換的是依附在物體本體上的局部坐標(biāo)系。所有繪制操作都是相對(duì)于變換后的物體的局部坐標(biāo)系進(jìn)行的。也就是說,在draw函數(shù)中定義物體時(shí),其頂點(diǎn)坐標(biāo)都是相對(duì)于局部坐標(biāo)系原點(diǎn)的偏移。

5、這樣的好處是,只要定義一次后,通過translate、 rotate和scale等操作,便可以將物體變換到任意位置,朝著任意角度,以及任意大小,這是一個(gè)非常棒的特性,可分離渲染數(shù)據(jù)源(不變性)及對(duì)渲染數(shù)據(jù)源的操作(可變性)。translate、rotate和scale這些局部坐標(biāo)系變換方法都具有累積性,每次變換操作都是相對(duì)上一次結(jié)果的疊加,可以通過精心設(shè)計(jì)save和restore的層次來修改這種累積性。const context: CanvasRenderingContext2D = $(#canvas).getContext(2d)堆棧操作:save、restore .坐標(biāo)系變換:trans

6、fer、rotate、scale、transform、setTransform屬性配置:fillStyle、strokeStyle、lineWidth .繪制操作:moveTo、lineTo、arc、fillRect、stroke、drawImage .Canvas原生api示例旋轉(zhuǎn)炮臺(tái)context.save(); / 整個(gè)坦克移動(dòng)和旋轉(zhuǎn)(局部坐標(biāo)系變換),注意變換順序( 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(); / 炮塔作為整個(gè)坦克的一部分,是在上一級(jí)變換(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(); / 整個(gè)坦克移動(dòng)和旋轉(zhuǎn)(局部坐標(biāo)系變換) 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、/ 炮塔作為整個(gè)坦克的一部分,是在上一級(jí)變換(trs)后的累積操作 context.rotate(30 * Math.PI / 180) ; / 繪制底座 + 炮管 + 炮口(省略部分代碼) context.fillStyle = #FF0000 context.fllRect(0, 0, 30, 2) context.restore();context.restore();RenderState繪制屬性:lineWdith/fillStyle/strokeStyle.仿射矩陣:累乘的最終結(jié)果RenderStateRenderState1RenderState2Canvas坐標(biāo)轉(zhuǎn)換原理1、使用

10、translate、rotate和scale這些方法時(shí),變換的是依附在物體本體上的局部坐標(biāo)系。2、所有繪制操作都是相對(duì)于變換后的局部坐標(biāo)系所進(jìn)行的。這是一個(gè)非常棒的特性,可分離渲染數(shù)據(jù)源(不變性)及對(duì)渲染數(shù)據(jù)源的操作(可變性)。3、translate、rotate和scale這些局部坐標(biāo)系變換方法都具有累積性,每次變換操作都是相對(duì)上一次結(jié)果的疊加,可以通過精心設(shè)計(jì)save和restore的層次來修改這種累積性。渲染引擎架構(gòu)矩陣矩陣(Matrix)是m個(gè)行(Row)和n個(gè)列(Column)構(gòu)成的數(shù)組。 在數(shù)學(xué)中,矩陣(Matrix)是指縱橫排列的二維數(shù)據(jù)表格,其本質(zhì)是“向量之間的映射”。線性變換

11、是線性空間中的運(yùn)動(dòng), 而矩陣就是用來描述這種變換的映射。矩陣運(yùn)算:叉乘 A(mxn) X B(nxp) = C(mxp)矩陣特殊形式:?jiǎn)挝痪仃?、矩陣的逆、仿射變換矩陣矩陣的叉乘仿射變換矩陣縮放和旋轉(zhuǎn)可以對(duì)圖形進(jìn)行平移變換包含平移的變換稱為仿射變換,線性變換(縮放和旋轉(zhuǎn)等)是仿射變換的特殊形式。我們只要知道,使用了仿射變換及齊次坐標(biāo)系后,就能使用矩陣乘法來統(tǒng)一操作圖形的縮放、旋轉(zhuǎn)和平移等變換。左圖是仿射變換矩陣的一般形式,矩陣中的每個(gè)元素都有一定含義。圖形投影變換整體縮放變換矩陣運(yùn)算平移矩陣縮放矩陣旋轉(zhuǎn)矩陣(繞Z軸)旋轉(zhuǎn)矩陣推導(dǎo)依據(jù)矩陣乘法法則,以上關(guān)系式用矩陣表示為:三維變換就是比二維變換多了

12、一個(gè) z 軸了,當(dāng)空間內(nèi)的物體繞 z 軸旋轉(zhuǎn)時(shí),我們可以理解為在 xy 平面進(jìn)行二位變換。實(shí)際推到過程與上式類似,只是 z 坐標(biāo)保持不變:場(chǎng)景圖樹狀“父-子”層級(jí)結(jié)構(gòu)。父級(jí)數(shù)據(jù)變化后,同步影響所有子節(jié)點(diǎn);而子節(jié)點(diǎn)的數(shù)據(jù)變化,不影響父節(jié)點(diǎn)。通過場(chǎng)景圖的特性,可以實(shí)現(xiàn)控制解決各個(gè)層級(jí)精靈之間的坐標(biāo)系變換數(shù)據(jù)同步問題。層次尋址與更新通過場(chǎng)景圖的特性,可以實(shí)現(xiàn)控制解決各個(gè)層級(jí)精靈之間的坐標(biāo)系變換數(shù)據(jù)同步問題。通過先根、深度優(yōu)先遍歷從根節(jié)點(diǎn)開始逐層累計(jì)矩陣相乘運(yùn)算結(jié)果。事件收集/ 事件注冊(cè)/ Application類接管事件的收集與派發(fā),并包含以下幾個(gè)關(guān)鍵功能:動(dòng)畫循環(huán)的啟動(dòng)和關(guān)閉。提供可以基于不同幀率

13、進(jìn)行回調(diào)的定時(shí)器。需要子類實(shí)現(xiàn)的update抽象方法。需要子類實(shí)現(xiàn)的render抽象方法。需要子類實(shí)現(xiàn)的Touch事件分發(fā)或響應(yīng)抽象方法。碰撞檢測(cè)(精確點(diǎn)選)Touch事件全局坐標(biāo)點(diǎn),依次變換到每個(gè)精靈的局部坐標(biāo)系中。1、依次計(jì)算每個(gè)精靈的世界-局部矩陣M(世界坐標(biāo)矩陣求逆)2、確定用戶Touch點(diǎn)世界坐標(biāo)(x,y),表示為向量OP。3、通過矩陣變換向量得到全局坐標(biāo)點(diǎn)在此精靈的局部坐標(biāo)。4、確定該精靈的輪廓數(shù)據(jù)(0,0,width,height)5、確定碰撞檢測(cè)方法:軸向包圍盒(AABB)6、判斷點(diǎn)是否在矩形內(nèi)。事件分發(fā)事件分發(fā)采用后根、從右到左的廣度優(yōu)先遍歷方式。Canvas屬于立即繪制模式

14、,后繪制的圖形層級(jí)高。因此從最后繪制的精靈往根節(jié)點(diǎn)方向,逐步進(jìn)行觸摸點(diǎn)的碰撞檢測(cè)(后根層次)。精靈移動(dòng)如何確定精靈組內(nèi)的局部坐標(biāo)偏移量?x1y11、已知用戶Touch事件全局坐標(biāo) GlobalPt(x,y)2、命中檢測(cè)(從下到上、從右到左、深度優(yōu)先)求當(dāng)前節(jié)點(diǎn)的 局部-世界變換矩陣 GlobalMatrix (從根節(jié)點(diǎn)開始到當(dāng)前節(jié)點(diǎn)累計(jì)矩陣乘)通過矩陣求逆,得到 世界-局部變換矩陣 LocalMatrix通過矩陣 LocalMatrix 作用于向量GlobalPt,得出該GlobalPt在該精靈內(nèi)局部坐標(biāo) LocalPt檢測(cè)LocalPt與該精靈的碰撞3、通過LocalPt修正拖拽偏移量基于時(shí)

15、間的更新與重繪通過 requestAnimationFrame() 產(chǎn)生固定的調(diào)用頻率,在每一幀內(nèi)都進(jìn)行一次場(chǎng)景圖中的各層級(jí)矩陣運(yùn)算,以計(jì)算所有元素每一幀的平移、旋轉(zhuǎn)、縮放數(shù)據(jù),并驅(qū)動(dòng)Canvas繪制最新的畫面。/ BaseApplication.js/ 啟動(dòng)應(yīng)用主循環(huán)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 實(shí)現(xiàn) js 調(diào)用 java 側(cè)代碼,以實(shí)現(xiàn)多設(shè)備協(xié)同能力。createLocalParticleAbility:獲取java接口實(shí)例register:注冊(cè)接口實(shí)例到框架層reply:PA端使用該接口向JS側(cè)回調(diào)函數(shù)發(fā)送消息Java方法通過LP

17、A注冊(cè)到MainAbility新建JSInterface.java,并實(shí)現(xiàn)LocalParticleAbility接口。(js無法實(shí)現(xiàn)動(dòng)態(tài)權(quán)限申請(qǐng))public class JSInterface implements LocalParticleAbility private final MainAbility mainAbility; public JSInterface(MainAbility mainAbility) this.mainAbility = mainAbility; 在MainAbility的onStart()方法中,通過調(diào)用register()方法,注冊(cè)LocalPart

18、icleAbility接口實(shí)例到框架層。代碼如下: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調(diào)用java方法在index.js文件中,調(diào)用createLocalParticleAbility()

19、方法,得到Java中LocalParticleAbility接口實(shí)例,也即JSInterface調(diào)用getNetWorkIdAsync()方法,就會(huì)執(zhí)行到Java中JSInterface定義的方法,參數(shù)result是Java端回調(diào)結(jié)果給JS端的數(shù)據(jù)var JS_PATH = com.likeyo.dreamwedding.manager.JSInterface;/以實(shí)際包名為準(zhǔn) 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回調(diào)數(shù)據(jù)給Javascript在requestPermissionAndGetNetWorkId()方法中,先獲取分布式權(quán)限(這個(gè)權(quán)限僅是分布式拉起需要,在獲取設(shè)備networkId時(shí)一起處理);在成功得到權(quán)限后

21、,再調(diào)用DeviceManager.createInstance()方法得到設(shè)備的networkId;最后調(diào)用LocalParticleAbility.Callback類的reply()方法(必須在子線程調(diào)用,實(shí)現(xiàn)異步操作),將獲取到的設(shè)備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(); 流程圖動(dòng)態(tài)申請(qǐng)權(quán)限獲取在線設(shè)備拉起遠(yuǎn)程FA動(dòng)態(tài)申請(qǐng)權(quán)限拉起遠(yuǎn)程FA單例發(fā)送控制指令指令完成JSJavaJSJava華為分享華為分享1、創(chuàng)建IDL接口文件 集成IDL接口,用于建立分享方與華為分享的交互通道,完成后續(xù)服務(wù)分享過程。 在“java”目錄同級(jí)目錄創(chuàng)建“idl”接口目錄:com/huawei/hwshare/third(固定路徑),然后創(chuàng)建名為IHwShareCallback.idl和IHwShareService.idl的IDL文件。華為分享通過IDE自

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論