HarmonyOS圖形處理:Canvas繪制與動畫開發實戰

本文將全面介紹HarmonyOS 5中Canvas組件的使用方法和動畫開發技巧,通過詳細的代碼示例和最佳實踐,幫助您掌握圖形繪制和動態效果實現的核心技能。

1. Canvas組件基礎與核心API

Canvas是HarmonyOS中用于2D圖形繪制的重要組件,提供了豐富的繪圖接口和靈活的動畫支持。

1.1 Canvas基本用法

import { CanvasRenderingContext2D } from '@ohos.graphics.canvas';@Entry
@Component
struct BasicCanvasDemo {private settings: RenderingContextSettings = new RenderingContextSettings(true);private ctx: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);build() {Column() {// 創建Canvas組件Canvas(this.ctx).width('100%').height(300).backgroundColor('#f0f0f0').onReady(() => {this.drawBasicShapes();})}.padding(12)}// 繪制基本圖形private drawBasicShapes() {// 繪制矩形this.ctx.fillStyle = '#3498db';this.ctx.fillRect(50, 50, 100, 80);// 繪制圓形this.ctx.beginPath();this.ctx.arc(250, 90, 40, 0, Math.PI * 2);this.ctx.fillStyle = '#e74c3c';this.ctx.fill();// 繪制文本this.ctx.font = '16px sans-serif';this.ctx.fillStyle = '#2c3e50';this.ctx.fillText('HarmonyOS Canvas', 120, 180);// 繪制線條this.ctx.beginPath();this.ctx.moveTo(50, 220);this.ctx.lineTo(300, 220);this.ctx.strokeStyle = '#27ae60';this.ctx.lineWidth = 3;this.ctx.stroke();}
}

1.2 核心繪圖API詳解

HarmonyOS Canvas提供了完整的2D繪圖API,主要包含以下幾類方法:

  • 路徑繪制beginPath(), moveTo(), lineTo(), arc(), rect(), closePath()
  • 樣式設置fillStyle, strokeStyle, lineWidth, lineCap, lineJoin
  • 填充與描邊fill(), stroke(), fillRect(), strokeRect()
  • 文本繪制fillText(), strokeText(), font, textAlign
  • 變換操作translate(), rotate(), scale(), transform(), setTransform()
  • 圖像繪制drawImage(), createImageData(), putImageData()

2. 高級繪圖技巧

2.1 復雜路徑與貝塞爾曲線

@Component
struct AdvancedPathDemo {private settings: RenderingContextSettings = new RenderingContextSettings(true);private ctx: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);build() {Canvas(this.ctx).width('100%').height(400).onReady(() => {this.drawComplexPaths();})}private drawComplexPaths() {// 繪制二次貝塞爾曲線this.ctx.beginPath();this.ctx.moveTo(50, 200);this.ctx.quadraticCurveTo(150, 50, 250, 200);this.ctx.strokeStyle = '#8e44ad';this.ctx.lineWidth = 4;this.ctx.stroke();// 繪制三次貝塞爾曲線this.ctx.beginPath();this.ctx.moveTo(50, 250);this.ctx.bezierCurveTo(100, 150, 200, 350, 250, 250);this.ctx.strokeStyle = '#f39c12';this.ctx.lineWidth = 4;this.ctx.stroke();// 繪制復雜形狀this.ctx.beginPath();this.ctx.moveTo(300, 50);this.ctx.lineTo(350, 150);this.ctx.arcTo(400, 200, 350, 250, 50);this.ctx.lineTo(300, 200);this.ctx.closePath();this.ctx.fillStyle = 'rgba(52, 152, 219, 0.7)';this.ctx.fill();}
}

2.2 漸變與陰影效果

@Component
struct GradientShadowDemo {private settings: RenderingContextSettings = new RenderingContextSettings(true);private ctx: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);build() {Canvas(this.ctx).width('100%').height(300).onReady(() => {this.drawGradientEffects();})}private drawGradientEffects() {// 創建線性漸變const linearGradient = this.ctx.createLinearGradient(0, 0, 300, 0);linearGradient.addColorStop(0, '#ff9a9e');linearGradient.addColorStop(1, '#fad0c4');this.ctx.fillStyle = linearGradient;this.ctx.fillRect(50, 50, 100, 100);// 創建徑向漸變const radialGradient = this.ctx.createRadialGradient(250, 100, 10, 250, 100, 60);radialGradient.addColorStop(0, '#a1c4fd');radialGradient.addColorStop(1, '#c2e9fb');this.ctx.fillStyle = radialGradient;this.ctx.beginPath();this.ctx.arc(250, 100, 60, 0, Math.PI * 2);this.ctx.fill();// 添加陰影效果this.ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';this.ctx.shadowBlur = 15;this.ctx.shadowOffsetX = 10;this.ctx.shadowOffsetY = 10;this.ctx.fillStyle = '#27ae60';this.ctx.fillRect(150, 180, 100, 80);// 重置陰影this.ctx.shadowColor = 'transparent';}
}

3. 動畫開發實戰

3.1 基礎動畫實現

@Entry
@Component
struct BasicAnimationDemo {private settings: RenderingContextSettings = new RenderingContextSettings(true);private ctx: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);@State private angle: number = 0;@State private position: number = 50;private animationId: number = 0;build() {Column() {Canvas(this.ctx).width('100%').height(300).onReady(() => {this.startAnimation();}).onDisappear(() => {this.stopAnimation();})Button('重置動畫').onClick(() => {this.resetAnimation();}).margin(10).width(200)}}private startAnimation() {const animate = () => {this.ctx.clearRect(0, 0, 400, 300);// 更新動畫狀態this.angle = (this.angle + 2) % 360;this.position = 50 + Math.sin(Date.now() / 500) * 100;// 繪制旋轉矩形this.ctx.save();this.ctx.translate(150, 150);this.ctx.rotate(this.angle * Math.PI / 180);this.ctx.fillStyle = '#3498db';this.ctx.fillRect(-40, -40, 80, 80);this.ctx.restore();// 繪制彈跳球this.ctx.beginPath();this.ctx.arc(this.position, 250, 20, 0, Math.PI * 2);this.ctx.fillStyle = '#e74c3c';this.ctx.fill();this.animationId = requestAnimationFrame(animate);};animate();}private stopAnimation() {if (this.animationId) {cancelAnimationFrame(this.animationId);}}private resetAnimation() {this.stopAnimation();this.angle = 0;this.position = 50;this.startAnimation();}
}

3.2 高級動畫:粒子系統

class Particle {x: number;y: number;vx: number;vy: number;radius: number;color: string;alpha: number;constructor(width: number, height: number) {this.x = Math.random() * width;this.y = Math.random() * height;this.vx = (Math.random() - 0.5) * 2;this.vy = (Math.random() - 0.5) * 2;this.radius = Math.random() * 5 + 1;this.color = `hsl(${Math.random() * 360}, 50%, 50%)`;this.alpha = Math.random() * 0.5 + 0.5;}update(width: number, height: number) {this.x += this.vx;this.y += this.vy;// 邊界檢測if (this.x < 0 || this.x > width) this.vx *= -1;if (this.y < 0 || this.y > height) this.vy *= -1;// 透明度衰減this.alpha -= 0.005;if (this.alpha <= 0) {this.alpha = 0;}}
}@Entry
@Component
struct ParticleSystemDemo {private settings: RenderingContextSettings = new RenderingContextSettings(true);private ctx: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);private particles: Particle[] = [];private animationId: number = 0;private width: number = 400;private height: number = 400;build() {Canvas(this.ctx).width('100%').height(this.height).onReady(() => {this.initializeParticles();this.startAnimation();}).onDisappear(() => {this.stopAnimation();})}private initializeParticles() {for (let i = 0; i < 100; i++) {this.particles.push(new Particle(this.width, this.height));}}private startAnimation() {const animate = () => {// 清空畫布this.ctx.clearRect(0, 0, this.width, this.height);// 更新并繪制粒子this.particles.forEach((particle, index) => {particle.update(this.width, this.height);// 移除消失的粒子并添加新粒子if (particle.alpha <= 0) {this.particles.splice(index, 1);this.particles.push(new Particle(this.width, this.height));}// 繪制粒子this.ctx.beginPath();this.ctx.arc(particle.x, particle.y, particle.radius, 0, Math.PI * 2);this.ctx.fillStyle = particle.color;this.ctx.globalAlpha = particle.alpha;this.ctx.fill();});// 重置透明度this.ctx.globalAlpha = 1;this.animationId = requestAnimationFrame(animate);};animate();}private stopAnimation() {if (this.animationId) {cancelAnimationFrame(this.animationId);}}
}

4. 性能優化技巧

4.1 離屏Canvas與緩存

@Component
struct OffscreenCanvasDemo {private mainSettings: RenderingContextSettings = new RenderingContextSettings(true);private mainCtx: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.mainSettings);private offscreenSettings: RenderingContextSettings = new RenderingContextSettings(true);private offscreenCtx: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.offscreenSettings);private complexPattern: ImageBitmap | null = null;build() {Canvas(this.mainCtx).width('100%').height(300).onReady(async () => {await this.createOffscreenPattern();this.drawUsingCache();})}private async createOffscreenPattern() {// 在離屏Canvas上繪制復雜圖案this.offscreenCtx.fillStyle = '#34495e';this.offscreenCtx.fillRect(0, 0, 100, 100);for (let i = 0; i < 20; i++) {this.offscreenCtx.beginPath();this.offscreenCtx.arc(Math.random() * 100,Math.random() * 100,Math.random() * 5 + 1,0,Math.PI * 2);this.offscreenCtx.fillStyle = `hsl(${Math.random() * 360}, 70%, 60%)`;this.offscreenCtx.fill();}// 轉換為ImageBitmap用于高效重繪this.complexPattern = await createImageBitmap(this.offscreenCtx.canvas);}private drawUsingCache() {if (!this.complexPattern) return;// 使用緩存圖案進行繪制(性能優化)for (let i = 0; i < 5; i++) {for (let j = 0; j < 3; j++) {this.mainCtx.drawImage(this.complexPattern,i * 110 + 20,j * 110 + 20,100,100);}}}
}

4.2 分層渲染與臟矩形優化

@Component
struct LayeredRenderingDemo {private backgroundSettings: RenderingContextSettings = new RenderingContextSettings(true);private backgroundCtx: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.backgroundSettings);private foregroundSettings: RenderingContextSettings = new RenderingContextSettings(true);private foregroundCtx: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.foregroundSettings);@State private mouseX: number = 0;@State private mouseY: number = 0;build() {Stack() {// 背景層(靜態內容,只需繪制一次)Canvas(this.backgroundCtx).width('100%').height(400).onReady(() => {this.drawBackground();})// 前景層(動態內容,頻繁更新)Canvas(this.foregroundCtx).width('100%').height(400).onReady(() => {this.startInteraction();}).onTouchMove((event) => {this.handleTouchMove(event);})}}private drawBackground() {// 繪制靜態背景const gradient = this.backgroundCtx.createLinearGradient(0, 0, 400, 400);gradient.addColorStop(0, '#1a2980');gradient.addColorStop(1, '#26d0ce');this.backgroundCtx.fillStyle = gradient;this.backgroundCtx.fillRect(0, 0, 400, 400);// 繪制網格this.backgroundCtx.strokeStyle = 'rgba(255, 255, 255, 0.1)';this.backgroundCtx.lineWidth = 1;for (let i = 0; i < 400; i += 20) {this.backgroundCtx.beginPath();this.backgroundCtx.moveTo(i, 0);this.backgroundCtx.lineTo(i, 400);this.backgroundCtx.stroke();this.backgroundCtx.beginPath();this.backgroundCtx.moveTo(0, i);this.backgroundCtx.lineTo(400, i);this.backgroundCtx.stroke();}}private handleTouchMove(event: TouchEvent) {const touch = event.touches[0];if (touch) {this.mouseX = touch.x;this.mouseY = touch.y;this.updateForeground();}}private updateForeground() {// 只清除需要更新的區域(臟矩形優化)this.foregroundCtx.clearRect(0, 0, 400, 400);// 繪制交互效果this.foregroundCtx.beginPath();this.foregroundCtx.arc(this.mouseX, this.mouseY, 50, 0, Math.PI * 2);this.foregroundCtx.fillStyle = 'rgba(255, 255, 255, 0.2)';this.foregroundCtx.fill();this.foregroundCtx.beginPath();this.foregroundCtx.arc(this.mouseX, this.mouseY, 20, 0, Math.PI * 2);this.foregroundCtx.fillStyle = 'rgba(255, 255, 255, 0.5)';this.foregroundCtx.fill();}private startInteraction() {// 初始繪制this.updateForeground();}
}

5. 實戰案例:數據可視化圖表

interface ChartData {label: string;value: number;color: string;
}@Entry
@Component
struct DataChartDemo {private settings: RenderingContextSettings = new RenderingContextSettings(true);private ctx: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);@State private chartData: ChartData[] = [{ label: 'Q1', value: 120, color: '#3498db' },{ label: 'Q2', value: 180, color: '#2ecc71' },{ label: 'Q3', value: 90, color: '#e74c3c' },{ label: 'Q4', value: 210, color: '#f39c12' }];build() {Column() {Canvas(this.ctx).width('100%').height(400).onReady(() => {this.drawBarChart();})Button('更新數據').onClick(() => {this.updateData();}).margin(10).width(200)}}private drawBarChart() {const padding = 40;const chartWidth = 400 - padding * 2;const chartHeight = 300 - padding * 2;const barWidth = chartWidth / this.chartData.length * 0.6;const maxValue = Math.max(...this.chartData.map(item => item.value));// 清空畫布this.ctx.clearRect(0, 0, 400, 400);// 繪制坐標軸this.ctx.strokeStyle = '#7f8c8d';this.ctx.lineWidth = 2;this.ctx.beginPath();this.ctx.moveTo(padding, padding);this.ctx.lineTo(padding, 400 - padding);this.ctx.lineTo(400 - padding, 400 - padding);this.ctx.stroke();// 繪制刻度this.ctx.textAlign = 'right';this.ctx.font = '12px sans-serif';this.ctx.fillStyle = '#7f8c8d';for (let i = 0; i <= 5; i++) {const value = (maxValue / 5) * i;const y = 400 - padding - (value / maxValue) * chartHeight;this.ctx.beginPath();this.ctx.moveTo(padding - 5, y);this.ctx.lineTo(padding, y);this.ctx.stroke();this.ctx.fillText(value.toString(), padding - 10, y + 4);}// 繪制柱狀圖this.chartData.forEach((item, index) => {const barHeight = (item.value / maxValue) * chartHeight;const x = padding + index * (chartWidth / this.chartData.length) + (chartWidth / this.chartData.length - barWidth) / 2;const y = 400 - padding - barHeight;// 繪制柱子this.ctx.fillStyle = item.color;this.ctx.fillRect(x, y, barWidth, barHeight);// 繪制數值this.ctx.textAlign = 'center';this.ctx.fillStyle = '#2c3e50';this.ctx.fillText(item.value.toString(), x + barWidth / 2, y - 5);// 繪制標簽this.ctx.fillText(item.label, x + barWidth / 2, 400 - padding + 20);});// 繪制標題this.ctx.textAlign = 'center';this.ctx.font = '16px sans-serif';this.ctx.fillStyle = '#2c3e50';this.ctx.fillText('季度銷售數據', 200, 30);}private updateData() {// 隨機更新數據this.chartData = this.chartData.map(item => ({...item,value: Math.floor(Math.random() * 200) + 50}));this.drawBarChart();}
}

6. 最佳實踐與性能建議

  1. 減少重繪區域:使用clearRect()只清除需要更新的區域,而不是整個畫布
  2. 使用離屏Canvas:對靜態內容或復雜圖案進行預渲染
  3. 避免頻繁的樣式更改:批量繪制相同樣式的圖形
  4. 使用requestAnimationFrame:實現平滑的動畫效果
  5. 優化路徑繪制:使用beginPath()closePath()管理路徑狀態
  6. 合理使用透明度:過多的透明度計算會增加性能開銷
  7. 分層渲染:將靜態內容和動態內容分離到不同的Canvas層

通過掌握這些Canvas繪制和動畫開發技巧,您將能夠在HarmonyOS應用中創建豐富多樣的圖形界面和流暢的交互體驗。記得在實際開發中根據具體需求選擇合適的優化策略,平衡視覺效果和性能表現。

需要參加鴻蒙認證的請點擊 鴻蒙認證鏈接

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/97787.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/97787.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/97787.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CCAFusion:用于紅外與可見光圖像融合的跨模態坐標注意力網絡

CCAFusion&#xff1a;用于紅外與可見光圖像融合的跨模態坐標注意力網絡 CCAFusion: Cross-Modal Coordinate Attention Network for Infrared and Visible Image Fusion 摘要 紅外與可見光圖像融合旨在生成一幅包含全面信息的圖像&#xff0c;該圖像既能保留豐富的紋理特征&a…

ESP32-P4小智編譯歷險記:從“編譯失敗“到“成功燒錄“的奇幻之旅,xiaozhi智能聊天機器人編譯避坑心得

?? ESP32-P4:AI小智編譯歷險記:從"編譯失敗"到"成功燒錄"的奇幻之旅 要編譯其他芯片esp32s3-s2-c3,遇到問題也可以在這里交流 “每一個編譯錯誤都是成長的機會,每一次成功都是堅持的勝利!” —— 某位被編譯器折磨的程序員 源碼地址:https://githu…

DIFY 項目中通過 Makefile 調用 Dockerfile 并使用 sudo make build-web 命令構建 web 鏡像的方法和注意事項

DIFY 項目中通過 Makefile 調用 Dockerfile 并使用 sudo make build-web 命令構建 web 鏡像的場景,以下是具體方法和注意事項總結: 一、通過 sudo make build-web 構建 web 鏡像的核心方法 1. 理解 Makefile 與 Dockerfile 的關聯 Makefile 的作用:DIFY 的 Makefile 中定義…

重學前端015 --- 響應式網頁設計 CSS變換

文章目錄skew()transformcursortransition.arm .left {} 和 .arm.left {} 區別skew() skew 傾斜變換函數&#xff0c;該函數有兩個參數。第一個是剪切x軸的角度&#xff0c;第二個是剪切y軸的角度。 transform: skew(0deg, 44deg);transform .arm.left {top: 35%;left: 5%;t…

【GMX v1實戰】時序風險結算與資本成本:深度解析 GMX 永續合約的資金費率機制

在去中心化衍生品交易平臺GMX中&#xff0c;當你準備開立杠桿合約倉位&#xff08;無論是做多還是做空某個資產&#xff09;時&#xff0c;系統會默默執行一個關鍵前置動作——調用名為 ??updateCumulativeFundingRate?? 的函數。這個看似普通的“準備工作”&#xff0c;實…

中宇聯云計算SD-WAN的售后服務怎么樣

前言在數字化轉型浪潮中&#xff0c;企業選擇SD-WAN服務商不僅關注技術性能&#xff0c;更看重售后服務的質量與可靠性。中宇聯云計算作為行業領先者&#xff0c;其SD-WAN售后服務體系已成為行業標桿。隨著全球數字化進程加速&#xff0c;企業對廣域網&#xff08;WAN&#xff…

【Kubernetes】K8s 集群外服務配置 Service 訪問

在 Kubernetes 集群中&#xff0c;內部服務可通過 Service-name 進行訪問。那么&#xff0c;對于集群外的服務&#xff0c;Pod 應該如何通過 Service 進行訪問呢&#xff1f;一起來看看吧&#xff01;此處舉例以 Pod 訪問集群外部的 Mysql 數據庫1、創建 Service# 創建 Service…

Linux 開發工具(1)

從開始講Linux&#xff0c;我們的目標絕不止于寫幾個命令這么簡單。我們的目的是在Linux系統上做開發。因此學習Linux的開發工具也是必不可少的。本章將重點講解&#xff1a;包管理器apt(CentOS叫yum&#xff0c;這里用ubuntu舉例)&#xff0c;vim編輯器。一.包管理器apt1.安裝…

redis面試點記錄

1、主從復制psync-> runid->runid是&#xff1f;則是全量->返回fullresync和runid和復制進度->bgsave命令準備RDB文件->之后的命令寫入replication_buffer->發送RDB->發送replication_buffer的信息repl_backlog_buffer環型緩沖區&#xff0c;主節點只有一…

Elastic APM 與 Elasticsearch 集成:構建完整可觀測性棧

引言 Elastic APM 深度依賴 Elasticsearch 作為數據后端&#xff0c;但正確集成可以解鎖更強大的功能&#xff0c;如自定義查詢、聚合分析和與其它 Elastic 工具的協同。本文探討 APM 與 Elasticsearch 的集成細節&#xff0c;包括數據流、索引管理以及高級用例&#xff0c;幫助…

開源模型應用落地-基于DPO的Qwen3-4B意圖理解精準對齊實踐(二十)

一、前言 在大模型技術蓬勃發展的今天,如何讓AI真正“理解”用戶意圖,而非僅僅生成流暢文本,已成為落地應用的核心瓶頸。尤其是在客服、搜索、智能助手等場景中,模型對用戶query的深層語義解析能力,直接決定了交互體驗的成敗。然而,經過標準SFT(監督微調)訓練的模型,往…

23種設計模式案例

一、創建型模式 1. 單例模式 (Singleton Pattern) 應用場景: 全局狀態管理、全局配置、共享資源訪問 // 全局狀態管理器 class Store {constructor() {if (Store.instance) return Store.instance;this.state {};Store.instance this;}getState(key) { return this.state[key…

ctfshow_web13-----------文件上傳.user.ini

打開題目發現是一個文件上傳題掃描后發現存在upload.php.bak.bak是備份文件拿到源碼正則過濾了php&#xff0c;文件大小<24,文件名小于9經嘗試&#xff0c;改后綴php5,ptml均不行&#xff0c;使用.htaccess文件也不成功上傳上傳.user.ini&#xff0c;在文件中寫上auto_prepe…

圖像拼接案例,摳圖案例

目錄 一.圖像拼接案例 1.圖像拼接項目介紹 2.核心步驟 ①計算圖片特征點及描述符 ②匹配特征點&#xff0c;使用暴力匹配器 ③篩選有效匹配 ④計算透視變換矩陣 ⑤應用變換和拼接 二.摳圖案例 1.縮放旋轉處理 2.轉化為灰度圖并二值化 3.找出所有輪廓&#xff0c;并在…

【左程云算法筆記016】雙端隊列-雙鏈表和固定數組實現

目錄 1&#xff09;雙端隊列的介紹 2&#xff09;雙端隊列用雙鏈表的實現代碼演示 3&#xff09;雙端隊列用固定數組的實現 代碼演示 視頻 【算法講解016【入門】雙端隊列-雙鏈表和固定數組實現】 Leecode leecode641 設計循環雙端隊列 1&#xff09;雙端隊列的介紹 可以…

ffplay視頻輸出和尺寸變換

視頻輸出模塊 視頻輸出初始化的主要流程 我們開始分析視頻&#xff08;圖像&#xff09;的顯示。 因為使?了SDL&#xff0c;?video的顯示也依賴SDL的窗?顯示系統&#xff0c;所以先從main函數的SDL初始化看起&#xff08;節選&#xff09;&#xff1a; int main(int argc, c…

協議_https協議

http http協議是將數據以明文的形式在網絡上傳輸。若是傳輸的數據中包含一些敏感信息比如銀行卡信息等可能會被有心人攻擊造成信息泄露或被篡改。 總結&#xff1a;http協議進行數據傳輸難以保證數據的隱私性以及數據完整性&#xff0c;為了保證數據的準確定引入了https這一協…

阿里云 騰訊云 API 自動化查詢指南

文章目錄一、核心思路與架構建議二、經驗與核心建議三、技術方案選型建議四、API使用詳解4.1 阿里云4.2 騰訊云五、進階&#xff1a;與內部系統聯動免費個人運維知識庫&#xff0c;歡迎您的訂閱&#xff1a;literator_ray.flowus.cn 一、核心思路與架構建議 自動化流程可以概括…

【Unity 性能優化之路——概述(0)】

Unity性能優化概述性能優化不是某個環節的極致壓榨&#xff0c;而是所有模塊的協同共進。本文將為你建立完整的Unity性能優化知識體系。很多Unity開發者一提到性能優化&#xff0c;首先想到的就是Draw Call、Batches這些渲染指標。這沒錯&#xff0c;但它們只是性能優化中的一部…

靈碼產品演示:軟件工程架構分析

作者&#xff1a;了哥 演示目的演示靈碼對于整個復雜軟件工程項目的架構分析能力&#xff0c;輸出項目的軟件系統架構圖。演示文檔接口生成能力。演示準備 克隆工程地址到本地&#xff08;需提前安裝好 git 工具&#xff0c; 建議本地配置 brew&#xff09;&#xff1a; git cl…