国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務器之家 - 編程語言 - JavaScript - js教程 - 如何在CocosCreator里畫個炫酷的雷達圖

如何在CocosCreator里畫個炫酷的雷達圖

2022-03-03 16:54文弱書生陳皮皮 js教程

這篇文章主要介紹了如何在CocosCreator里畫個炫酷的雷達圖,對Graphics感興趣的同學,一定要看看,并且把代碼實踐一下

前言

雷達圖(Radar Chart) 也稱為網絡圖、星圖或蜘蛛網圖。

是以從同一點開始的軸上表示的三個或更多個定量變量的二維圖表的形式顯示多元數據的圖形方法。

適用于顯示三個或更多的維度的變量。

如何在CocosCreator里畫個炫酷的雷達圖

雷達圖常用于數據統計或對比,對于查看哪些變量具有相似的值、變量之間是否有異常值都很有用。

同時在不少游戲中都有雷達圖的身影,可以很直觀地展示并對比一些數據。

例如王者榮耀中的對戰資料中就用到了:

如何在CocosCreator里畫個炫酷的雷達圖

那么在本篇文章中,皮皮就來分享下在 Cocos Creator 中如何利用 Graphics 組件來繪制炫酷的雷達圖~

文中會對原始代碼進行一定的削減以保證閱讀體驗。

雷達圖組件:https://gitee.com/ifaswind/eazax-ccc/blob/master/components/RadarChart.ts


預覽

先來看看效果吧~

在線預覽:https://ifaswind.gitee.io/eazax-cases/?case=radarChart

兩條數據

如何在CocosCreator里畫個炫酷的雷達圖

緩動數據

如何在CocosCreator里畫個炫酷的雷達圖

花里胡哨

如何在CocosCreator里畫個炫酷的雷達圖

藝術就是爆炸

如何在CocosCreator里畫個炫酷的雷達圖

逐漸偏離主題

如何在CocosCreator里畫個炫酷的雷達圖

正文

Graphics 組件

在我們正式開始制作雷達圖之前,讓我們先來大概了解一下 Cocos Creator 引擎中的 Graphics 組件。

Graphics 組件繼承于 cc.RenderComponent,利用該組件我們可以實現畫板和表格之類的功能。

屬性(Properties)

下面是我們本次將會用到的屬性:

  • lineCap:設置或返回線條兩端的樣式(無、圓形線帽或方形線帽)
  • lineJoin:設置或返回兩條線相交時的拐角樣式(斜角、圓角或尖角)
  • lineWidth:設置或返回當前畫筆的粗細(線條的寬度)
  • strokeColor:設置或返回當前畫筆的顏色
  • fillColor:設置或返回填充用的顏色(油漆桶)

函數(Functions)

下面是我們本次將會用到的函數:

  • moveTo(x, y):抬起畫筆并移動到指定位置(不創建線條)
  • lineTo(x, y):放下畫筆并創建一條直線至指定位置
  • circle(cx, cy, r):在指定位置(圓心)畫一個圓
  • close():閉合已創建的線條(相當于 lineTo(起點)
  • stroke():繪制已創建(但未被繪制)的線條(將線條想象成默認透明的,此行為則是賦予線條顏色)
  • fill():填充當前線條包圍的區域(如果線條沒有閉合則會嘗試”模擬閉合“起點和終點)
  • clear():擦掉當前畫板上的所有東西

Graphics 組件文檔:http://docs.cocos.com/creator/manual/zh/components/graphics.html?h=graphics

畫網格

先來看看一個標準的雷達圖有啥特點:

如何在CocosCreator里畫個炫酷的雷達圖

發現了嗎?雷達圖的基本特點如下:

  • 有 3 條或以上的軸線
  • 軸與軸之間的夾角相同
  • 每條軸上除中心點外應至少有 1 個刻度
  • 每條軸上都有相同的刻度
  • 刻度與刻度之間的距離也相同
  • 軸之間的刻度相連形成網格線

計算軸線角度

先算出軸之間的夾角度數 [ 360 ÷ 軸數 ],再計算所有軸的角度:

this.angles = [];
// 軸間夾角
const iAngle = 360 / this.axes;
for (let i = 0; i < this.axes; i++) {
    // 計算
    const angle = iAngle * i;
    this.angles.push(angle);
}

計算刻度坐標

雷達圖至少擁有 3 條軸,且每條軸上都應有 1 個或以上的刻度(不包含中心點)

如何在CocosCreator里畫個炫酷的雷達圖

所以我們需使用一個二維數組來保存所有刻度的坐標,從最外層(即軸線的末端)的刻度開始記錄,方便我們繪制時讀取:

// 創建一個二維數組
let scalesSet: cc.Vec2[][] = [];
for (let i = 0; i < 軸上刻度個數; i++) {
    // 用來保存當前層上的刻度坐標
    let scales = [];
    // 計算刻度在軸上的位置
    const length = 軸線長度 - (軸線長度 / 軸上刻度個數 * i);
    for (let j = 0; j < this.angles.length; j++) {
        // 將角度轉為弧度
        const radian = (Math.PI / 180) * this.angles[j];
        // 根據三角公式計算刻度相對于中心點(0, 0)的坐標
        const pos = cc.v2(length * Math.cos(radian), length * Math.sin(radian));
        // 推進數組
        scales.push(pos);
    }
    // 推進二維數組
    scalesSet.push(scales);
}

繪制軸線和外網格線

軸線

連接中心點 (0, 0) 和最外層 scalesSet[0] 的刻度即為軸線:

// 遍歷全部最外層的刻度
for (let i = 0; i < scalesSet[0].length; i++) {
    // 畫筆移動至中心點
    this.graphics.moveTo(0, 0);
    // 創建線條
    this.graphics.lineTo(scalesSet[0][i].x, scalesSet[0][i].y);
}

外網格線

連接所有軸上最外層 scalesSet[0] 的刻度即形成外網格線:

// 畫筆移動至第一個點
this.graphics.moveTo(scalesSet[0][0].x, scalesSet[0][0].y);
for (let i = 1; i < scalesSet[0].length; i++) {
    // 創建線條
    this.graphics.lineTo(scalesSet[0][i].x, scalesSet[0][i].y);
}
// 閉合當前線條(外網格線)
this.graphics.close();

填充并繪制

這里需要注意先填充顏色再繪制線條,要不然軸線和網格線就被擋住了:

// 填充線條包圍的空白區域
this.graphics.fill();
// 繪制已創建的線條(軸線和外網格線)
this.graphics.stroke();

于是現在我們就有了這么個玩意兒:

如何在CocosCreator里畫個炫酷的雷達圖

繪制內網格線

當刻度大于 1 個時就需要繪制內網格線,從刻度坐標集的下標 1 開始繪制:

// 刻度大于 1 個時才繪制內網格線
if (scalesSet.length > 1) {
    // 從下邊 1 開始(下標 0 是外網格線)
    for (let i = 1; i < scalesSet.length; i++) {
        // 畫筆移動至第一個點
        this.graphics.moveTo(scalesSet[i][0].x, scalesSet[i][0].y);
        for (let j = 1; j < scalesSet[i].length; j++) {
            // 創建線條
            this.graphics.lineTo(scalesSet[i][j].x, scalesSet[i][j].y);
        }
        // 閉合當前線條(內網格線)
        this.graphics.close();
    }
    // 繪制已創建的線條(內網格線)
    this.graphics.stroke();
}

就這樣我們雷達圖的底子就畫好啦:

如何在CocosCreator里畫個炫酷的雷達圖

畫數據 

編寫畫線邏輯之前,先確定一下我們需要的數據結構:

  • 數值數組(必須,小數形式的比例,至少包含 3 個值)
  • 線的寬度(可選,不指定則使用默認值)
  • 線的顏色(可選,不指定則使用默認值)
  • 填充的顏色(可選,不指定則使用默認值)
  • 節點的顏色(可選,不指定則使用默認值)

具體的數據結構如下(導出類型方便外部使用):

/**
 * 雷達圖數據
 */
export interface RadarChartData {

    /** 數值 */
    values: number[];

    /** 線的寬度 */
    lineWidth?: number;

    /** 線的顏色 */
    lineColor?: cc.Color;

    /** 填充的顏色 */
    fillColor?: cc.Color;

    /** 節點的顏色 */
    joinColor?: cc.Color;

}

繪制數據

繪制數據比較簡單,我們只需要算出數據點在圖表中的位置,并將數據連起來就好了。

draw 函數中我們接收一份或以上的雷達圖數據,并按照順序遍歷繪制出來(??長代碼警告):

/**
 * 繪制數據
 * @param data 數據
 */
public draw(data: RadarChartData | RadarChartData[]) {
    // 處理數據
    const datas = Array.isArray(data) ? data : [data];

    // 開始繪制數據
    for (let i = 0; i < datas.length; i++) {
        // 裝填染料
        this.graphics.strokeColor = datas[i].lineColor || defaultOptions.lineColor;
        this.graphics.fillColor = datas[i].fillColor || defaultOptions.fillColor;
        this.graphics.lineWidth = datas[i].lineWidth || defaultOptions.lineWidth;

        // 計算節點坐標
        let coords = [];
        for (let j = 0; j < this.axes; j++) {
            const value = datas[i].values[j] > 1 ? 1 : datas[i].values[j];
            const length = value * this.axisLength;
            const radian = (Math.PI / 180) * this.angles[j];
            const pos = cc.v2(length * Math.cos(radian), length * Math.sin(radian))
            coords.push(pos);
        }

        // 創建線條
        this.graphics.moveTo(coords[0].x, coords[0].y);
        for (let j = 1; j < coords.length; j++) {
            this.graphics.lineTo(coords[j].x, coords[j].y);
        }
        this.graphics.close(); // 閉合線條
        
        // 填充包圍區域
        this.graphics.fill();
        // 繪制線條
        this.graphics.stroke();

        // 繪制數據節點
        for (let j = 0; j < coords.length; j++) {
            // 大圓
            this.graphics.strokeColor = datas[i].lineColor || defaultOptions.lineColor;
            this.graphics.circle(coords[j].x, coords[j].y, 2);
            this.graphics.stroke();
            // 小圓
            this.graphics.strokeColor = datas[i].joinColor || defaultOptions.joinColor;
            this.graphics.circle(coords[j].x, coords[j].y, .65);
            this.graphics.stroke();
        }

    }
}

到這里我們已經成功制作了一個可用的雷達圖:

如何在CocosCreator里畫個炫酷的雷達圖

但是!我們的征途是星辰大海!必須加點料!

完全靜態的雷達圖實在是太無趣太普通,得想想辦法讓它動起來!

我們的雷達圖數據的數值是數組形式,想到怎么樣才能讓這些數值動起來了嗎?

得益于 Cocos Creator 為我們提供的 Tween 緩動系統,讓復雜的數據動起來變得異常簡單!

我們只需要這樣,這樣,然后那樣,是不是很簡單?

cc.tween 支持緩動任意對象的任意屬性

緩動系統:http://docs.cocos.com/creator/manual/zh/scripting/tween.html

另外我在《一個全能的挖孔 Shader》中也是使用了緩動系統來讓挖孔動起來~

在線預覽:https://ifaswind.gitee.io/eazax-cases/?case=newGuide

我的思路是:

  1. 將當前的數據保存到當前實例的 this.curDatas
  2. 接收到新的數據時,使用 cc.tweenthis.curData 的屬性進行緩動
  3. update 中調用 draw 函數,每幀都重新繪制 this.curDatas 中的數據

每幀更新

// 當前雷達圖數據
private curDatas: RadarChartData[] = [];

protected update() {
    if (!this.keepUpdating) return;
    // 繪制當前數據
    this.draw(this.curDatas);
}

緩動數據

/**
 * 緩動繪制
 * @param data 目標數據
 * @param duration 動畫時長
 */
public to(data: RadarChartData | RadarChartData[], duration: number) {
    // 處理重復調用
    this.unscheduleAllCallbacks();
    
    // 包裝單條數據
    const datas = Array.isArray(data) ? data : [data];

    // 打開每幀更新
    this.keepUpdating = true;

    // 動起來!
    for (let i = 0; i < datas.length; i++) {
        // 數值動起來!
        // 遍歷數據中的全部數值,逐個讓他們動起來!
        for (let j = 0; j < this.curDatas[i].values.length; j++) {
            // 限制最大值為 1(即 100%)
            const value = datas[i].values[j] > 1 ? 1 : datas[i].values[j];
            cc.tween(this.curDatas[i].values)
                .to(duration, { [j]: value })
                .start();
        }
        // 樣式動起來!
        // 沒有指定則使用原來的樣式!
        cc.tween(this.curDatas[i])
            .to(duration, {
                lineWidth: datas[i].lineWidth || this.curDatas[i].lineWidth,
                lineColor: datas[i].lineColor || this.curDatas[i].lineColor,
                fillColor: datas[i].fillColor || this.curDatas[i].fillColor,
                joinColor: datas[i].joinColor || this.curDatas[i].joinColor
            })
            .start();
    }

    this.scheduleOnce(() => {
        // 關閉每幀更新
        this.keepUpdating = false;
    }, duration);
}

數值和樣式都動起來了:

如何在CocosCreator里畫個炫酷的雷達圖

雷達圖組件:https://gitee.com/ifaswind/eazax-ccc/blob/master/components/RadarChart.ts

以上就是如何在CocosCreator里畫個炫酷的雷達圖的詳細內容,更多關于CocosCreator畫個雷達圖的資料請關注服務器之家其它相關文章!

原文鏈接:https://blog.csdn.net/iFasWind/article/details/108111906

延伸 · 閱讀

精彩推薦
  • js教程CocosCreator通用框架設計之網絡

    CocosCreator通用框架設計之網絡

    這篇文章主要介紹了CocosCreator通用框架設計之網絡,詳細講解了WebSocket的原理和使用方法,對WebSocket感興趣的同學,一定要看一下...

    weixin_397524348822022-03-01
  • js教程js繼承的6種方式詳解

    js繼承的6種方式詳解

    這篇文章主要給大家介紹了關于js繼承的6種方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面...

    Selfimpr歐10992022-02-24
  • js教程javascript實現表格信息增添與刪除

    javascript實現表格信息增添與刪除

    這篇文章主要為大家詳細介紹了javascript實現表格信息增添與刪除,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    小徐世界第一可愛8722022-02-23
  • js教程前端開發之JS中編寫For循環的方法

    前端開發之JS中編寫For循環的方法

    這些年來,JavaScript 發展得如此之快。如果你之前有其他編程語言經驗的話,你可能無法相信在 JavaScript 中有4種方法可以編寫for 循環。...

    清閑的帆船先生8972021-12-24
  • js教程js實現調用網絡攝像頭及常見錯誤處理

    js實現調用網絡攝像頭及常見錯誤處理

    這篇文章主要介紹了js實現調用網絡攝像頭及常見錯誤處理,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的...

    飛灰4632022-02-13
  • js教程整理CocosCreator常用知識點

    整理CocosCreator常用知識點

    這篇文章主要介紹了整理CocosCreator常用知識點,這些知識點,平時幾乎都能用到,希望同學們看完后,可以自己去試一下,加深印象...

    代碼猴兒5292022-03-01
  • js教程一文帶你用80行代碼實現簡易 RxJS

    一文帶你用80行代碼實現簡易 RxJS

    RxJS 是一個響應式的庫,它接收從事件源發出的一個個事件,經過處理管道的層層處理之后,傳入最終的接收者,這個處理管道是由操作符組成的,開發者...

    神光的編程秘籍5912022-02-28
  • js教程javascript中閉包closure的深入講解

    javascript中閉包closure的深入講解

    這篇文章主要給大家介紹了關于javascript中閉包closure的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需...

    flydean11382022-01-25
主站蜘蛛池模板: 自拍在线 | 亚洲国产精品自拍 | 欧美日韩免费一区二区三区 | 精品国产乱码久久久久久影片 | 极品久久 | 男女视频网址 | 午夜爱| 成人自拍视频 | 免费观看黄色12片一级视频 | 免费成人在线网站 | 久久久国产一区二区三区 | 日本一区二区在线视频 | 黄色影视网址 | 久久久www成人免费无遮挡大片 | 久久久久久久久久久国产 | 在线日本中文字幕 | 日本在线观看 | 国产欧美日韩综合精品 | 欧洲精品 | 精品国产色 | 日本一区二区三区四区 | 亚洲久久一区二区 | 国产精品美女久久久久久免费 | 99视频在线 | 亚洲久久 | yy6080久久伦理一区二区 | 成人在线视频免费观看 | 国产黄色在线播放 | 五月综合激情 | 亚洲第一视频网站 | 精品久久影院 | 欧美视频精品 | 国产精品毛片久久久久久久明星 | 一级黄色免费毛片 | 丝袜天堂 | 久久综合伊人77777蜜臀 | 麻豆精品国产91久久久久久 | 美女久久久 | 精品国产一区二区 | 亚洲国产aⅴ成人精品无吗 成人午夜视频在线观看 | 亚洲国产精品激情在线观看 |