一个大包的专案程序码解压缩後看着满满的程序码思考着我可以实现计画案的目标吗...。接下来这三天会将专案开发的部分分为前端篇、後端篇以及资料库概念与网站上线篇的艰辛路程。
昨天提到的专案执行的过程中同时也进行另外一个计划,由於之前有实习经验因此开发APP的过程虽然痛苦但是起码可以依照过去的经验处理一些问题,但接着要提到的计画一听到内容的当下先是傻眼然後WTF也太多和太杂了吧。计画目标是要建构一个平台,并且前端能够搭配3D场景的载入和记录使用者的操作行为,另外也提供储存场景、预购订单以及购买的相关功能。
今天分享的前端篇简单分享当时常做的部分,分为画面响应式的设计方式以及载入3D场景参考的开源专案。
回想当时刚学习网页设计的时候,都是直接定义CSS然後确认不同萤幕大小的情况下画面要怎麽更着变动,但在这个专案开发实在是没有太多的时间慢慢调整,因此就直接引用了你知我知大家知的响应式开源前端框架-Bootstrap。
@media screen and (max-width: 600px){
.class{
background: #ccc;
}
}
从官方的说明文件可以看到各种网页物件类型的参考范例和设计规则,其中只要掌握几个原则就会很好上手,首先Bootstrap使用em或rems来定义大多数物件大小,而px的单位是用於网格断点和容器宽度。在使用区块设计宽度时会需要计算全部的宽度加起来需要12,从下图的说明可以了解当要对特定的萤幕大小时需要带的栏位名称。
通常使用的时候很常透过CDN的方式去引用
另外画面上给使用者点击的按键有时候需要区别颜色以利操作上的便利(例如绿色代表确认红色代表取消或是中止),这时候透过预设的参数直接设定可以省去蛮多的时间。
<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场景的开发套件最後是选择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 11 - 用Kotlin解数学题:考拉兹猜想
>>: Day 11 Arbitrary attributes
今天要主要来分享一下特性描述器。 特性描述器 (property descriptor) 在 ES...
虽然我们或多或少听过 Gradle 这个名字,但其实在学习 Kotlin 程序语言时,好像没什麽机会...
前言:昨天介绍完了二元树的两种储存方式,今天要来介绍如何读取二元树,称之为走访,而走访方式就有大约四...
tuple 可放任意物件,但不可变 ; tuple用法如下 建立多个元素 tupleSample =...
建好专案之後,来看看专案里已经帮你准备好哪些档案吧!先大致认识每个资料夹如何分门别类的规则,日後自己...