iT邦幫忙

2021 iThome 鐵人賽

DAY 7
0
自我挑戰組

菜鳥工程師的奇幻旅程系列 第 7

Day 7 - 拯救落後的專案能撐一天是一天(前端篇)

一個大包的專案程式碼解壓縮後看著滿滿的程式碼思考著我可以實現計畫案的目標嗎...。接下來這三天會將專案開發的部分分為前端篇、後端篇以及資料庫概念與網站上線篇的艱辛路程。

三個月內要完成的極限開發之旅

昨天提到的專案執行的過程中同時也進行另外一個計劃,由於之前有實習經驗因此開發APP的過程雖然痛苦但是起碼可以依照過去的經驗處理一些問題,但接著要提到的計畫一聽到內容的當下先是傻眼然後WTF也太多和太雜了吧。計畫目標是要建構一個平台,並且前端能夠搭配3D場景的載入和記錄使用者的操作行為,另外也提供儲存場景、預購訂單以及購買的相關功能。

今天分享的前端篇簡單分享當時常做的部分,分為畫面響應式的設計方式以及載入3D場景參考的開源專案。

響應式畫面

回想當時剛學習網頁設計的時候,都是直接定義CSS然後確認不同螢幕大小的情況下畫面要怎麼更著變動,但在這個專案開發實在是沒有太多的時間慢慢調整,因此就直接引用了你知我知大家知的響應式開源前端框架-Bootstrap。

@media screen and (max-width: 600px){
    .class{
        background: #ccc;
    }
}

從官方的說明文件可以看到各種網頁物件類型的參考範例和設計規則,其中只要掌握幾個原則就會很好上手,首先Bootstrap使用em或rems來定義大多數物件大小,而px的單位是用於網格斷點和容器寬度。在使用區塊設計寬度時會需要計算全部的寬度加起來需要12,從下圖的說明可以了解當要對特定的螢幕大小時需要帶的欄位名稱。
Imgur
Imgur

通常使用的時候很常透過CDN的方式去引用
Imgur

參考來源

另外畫面上給使用者點擊的按鍵有時候需要區別顏色以利操作上的便利(例如綠色代表確認紅色代表取消或是中止),這時候透過預設的參數直接設定可以省去蠻多的時間。
Imgur

<button type="button" class="btn btn-primary">Primary</button>
<button type="button" class="btn btn-secondary">Secondary</button>
<button type="button" class="btn btn-success">Success</button>
<button type="button" class="btn btn-danger">Danger</button>
<button type="button" class="btn btn-warning">Warning</button>
<button type="button" class="btn btn-info">Info</button>
<button type="button" class="btn btn-light">Light</button>
<button type="button" class="btn btn-dark">Dark</button>
<button type="button" class="btn btn-link">Link</button>

3D場景的載入方法

Imgur

Github連結

當初在尋找可以載入3D場景的開發套件最後是選擇Three.js,接著先參考他們的官方說明文件了解基本場景的載入、切換場景的動作、清除場景的動作等等。除此之外想要更了解整包開源專案的大部分功能可以檢視three.js editor,找個範例的檔案類型實際操作怎麼載入、怎麼更換紋理、怎麼調整物件的參數值等等,透過這樣的方式可以了解需要開發特定功能時實際的流程與呈現的效果。

文件說明連結

由於當時建立3D場景的同事輸出後的檔案類型是Json,因此在載入場景時可以使用ObjectLoader的方法,從下面的官方參考程式碼可以看到場景引用的路徑定義、場景載入時監聽xhr轉換成進度log的方法以及場景載入後加入已經定義好的scene。

const loader = new THREE.ObjectLoader();

loader.load(
	// resource URL
	"models/json/example.json",

	// onLoad callback
	// Here the loaded data is assumed to be an object
	function ( obj ) {
		// Add the loaded object to the scene
		scene.add( obj );
	},

	// onProgress callback
	function ( xhr ) {
		console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
	},

	// onError callback
	function ( err ) {
		console.error( 'An error happened' );
	}
);

// Alternatively, to parse a previously loaded JSON structure
const object = loader.parse( a_json_object );

scene.add( object );

場景載入後如果只有單純瀏覽對於互動性的體驗就沒有加分的效果,在這個需求下使用了TextureLoader的方法接著從官方網站的說明檢視程式碼,可以看到載入時定義圖片路徑外,接著宣告一個新的Material將該texture做置換的動作。而在當時處理需求的時候是使用現有的場景直接置換texture,因此需要先了解場景是由多個物件組合起來所以會有各自對應的Material,直接更換的方式就是去讀取該Material上層的物件名稱後就可以更換了。

const texture = new THREE.TextureLoader().load( 'textures/land_ocean_ice_cloud_2048.jpg' );

// immediately use the texture for material creation
const material = new THREE.MeshBasicMaterial( { map: texture } );

但除了更換外如果需要做重覆拼貼的動作可以下面的程式碼設定

//  load a texture, set wrap mode to repeat
const texture = new THREE.TextureLoader().load( "textures/water.jpg" );
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( 4, 4 );

上述提到的幾個行為算是比較常用到的,另外像是場景載入時使用的camera也有蠻多參數可以設定,例如初始的位置、視角以及縮放的極限、使用者移動場景時需要固定一個範圍或者是隨意拖拉等等,例外像是scene也可以設定縮放到一定距離時的fog效果(還蠻酷的功能)。

開發時遇到的困難點

第一個挑戰是之前幾乎沒有深入使用Javascript,所以前期花了一點時間了解該語言的特性以確保在開發時不必要的錯誤發生,接著則是確認如何log數值以及除錯時錯誤訊息的處理方式。學習上網路非常多個來源,通常自己的習慣會先從語法的相關技術文件了解,如果實作功能較複雜則是會去看有沒有sample code、教學影片或者是技術論壇等等,從他們的程式碼理解執行的邏輯後轉換成自己的寫法。

W3Schools教學資源
Javascript Coding Style參考
Youtube相關教學(他的教學影片淺顯易懂很實用!)

當時因為時間的壓力關係只有剛開始參考文件的說明一個一個測試,到後來是直接clone專案並且直接參考editor版本的現有功能,修改成能夠符合計畫的需求以及搭配同事設計的多個3D場景和紋理的版本。在這樣的情況開發會發生許多問題(要客製化時是要放在哪個js檔案內),因此很多時間都時從實際操作畫面的標籤(id、class名稱)然後去尋找哪個檔案做觸發此標籤的動作,並且多次的來會測試修改後的效果是否正常。


上一篇
Day 6 - 唯一與職缺有關的工作內容
下一篇
Day 8 - 拯救落後的專案能撐一天是一天(後端篇)
系列文
菜鳥工程師的奇幻旅程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言