1. บทนำ
คอมโพเนนต์เว็บ
คอมโพเนนต์เว็บคือชุดมาตรฐานเว็บที่ช่วยให้นักพัฒนาซอฟต์แวร์ขยาย HTML ด้วยองค์ประกอบที่กําหนดเองได้ ใน Codelab นี้ คุณจะได้กำหนดองค์ประกอบ <brick-viewer>
ซึ่งจะแสดงโมเดลตัวต่อได้
lit-element
เราจะใช้องค์ประกอบ "lit" เพื่อช่วยกำหนดองค์ประกอบที่กำหนดเอง <brick-viewer>
โดย "lit-element" เป็นคลาสพื้นฐานขนาดเล็กที่เพิ่มน้ำตาลไวยากรณ์ลงในมาตรฐานคอมโพเนนต์เว็บ วิธีนี้จะช่วยให้เราเริ่มต้นใช้งานองค์ประกอบที่กำหนดเองได้ง่าย
เริ่มต้นใช้งาน
เราจะเขียนโค้ดในสภาพแวดล้อม Stackblitz ออนไลน์ ดังนั้นให้เปิดลิงก์นี้ในหน้าต่างใหม่
stackblitz.com/edit/brick-viewer
มาเริ่มกันเลย
2. กำหนดองค์ประกอบที่กำหนดเอง
คำจำกัดความของชั้นเรียน
หากต้องการระบุองค์ประกอบที่กำหนดเอง ให้สร้างคลาสที่ขยาย LitElement
และตกแต่งด้วย @customElement
อาร์กิวเมนต์ของ @customElement
จะเป็นชื่อขององค์ประกอบที่กําหนดเอง
ใน brick-viewer.ts ให้ใส่ข้อมูลต่อไปนี้
@customElement('brick-viewer')
export class BrickViewer extends LitElement {
}
ตอนนี้องค์ประกอบ <brick-viewer></brick-viewer>
พร้อมใช้งานใน HTML แล้ว แต่หากลองใช้ ก็จะไม่แสดงผลใดๆ เรามาแก้ปัญหานั้นกันดีกว่า
วิธีแสดงผล
หากต้องการใช้มุมมองของคอมโพเนนต์ ให้กำหนดเมธอดที่ชื่อว่า Render เมธอดนี้ควรแสดงผลเทมเพลตตัวอักษรล้วนที่ติดแท็กด้วยฟังก์ชัน html
ใส่ HTML ที่คุณต้องการในลิเทอรัลของเทมเพลตที่ติดแท็ก ข้อความนี้จะแสดงผลเมื่อคุณใช้ <brick-viewer>
เพิ่มเมธอด render
:
export class BrickViewer extends LitElement {
render() {
return html`<div>Brick viewer</div>`;
}
}
3. การระบุไฟล์ LDraw
กำหนดพร็อพเพอร์ตี้
คงจะดีไม่น้อยหากผู้ใช้ของ <brick-viewer>
สามารถระบุโมเดลตัวต่อที่จะแสดงโดยใช้แอตทริบิวต์ดังตัวอย่างต่อไปนี้
<brick-viewer src="path/to/model.ldraw"></brick-viewer>
เนื่องจากเรากำลังสร้างองค์ประกอบ HTML เราจึงใช้ประโยชน์จาก API แบบประกาศและกำหนดแอตทริบิวต์แหล่งที่มาได้ เช่นเดียวกับแท็ก <img>
หรือ <video>
เมื่อมีองค์ประกอบส่องสว่างจะช่วยให้ตกแต่งที่พักได้ง่ายดายพอๆ กับการตกแต่งที่พักระดับชั้นเรียนด้วย @property
ตัวเลือก type
ให้คุณระบุวิธีที่องค์ประกอบที่มีแสงสว่างเพียงพอจะแยกวิเคราะห์พร็อพเพอร์ตี้เพื่อใช้เป็นแอตทริบิวต์ HTML
กำหนดพร็อพเพอร์ตี้และแอตทริบิวต์ src
ดังนี้
export class BrickViewer extends LitElement {
@property({type: String})
src: string|null = null;
}
ตอนนี้ <brick-viewer>
มีแอตทริบิวต์ src
ที่เราตั้งค่าใน HTML ได้ ค่านี้สามารถอ่านได้จากภายในคลาส BrickViewer
ด้วยองค์ประกอบที่มีแสง
กำลังแสดงค่า
เราสามารถแสดงค่าของแอตทริบิวต์ src
โดยใช้ค่านั้นในเทมเพลตลิเทอรัลของเมธอดแสดงผล แปลงค่าลงในลิเทอรัลเทมเพลตโดยใช้ไวยากรณ์ ${value}
export class BrickViewer extends LitElement {
render() {
return html`<div>Brick model: ${this.src}</div>`;
}
}
ตอนนี้เราเห็นค่าของแอตทริบิวต์ src ในองค์ประกอบ <brick-viewer>
ในหน้าต่าง ลองใช้: เปิดเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของเบราว์เซอร์และเปลี่ยนแอตทริบิวต์ src ด้วยตนเอง ลองใช้งาน...
...คุณสังเกตเห็นไหมว่าข้อความในองค์ประกอบอัปเดตโดยอัตโนมัติ องค์ประกอบที่มีแสงจะคอยสังเกตคุณสมบัติของคลาสที่ตกแต่งด้วย @property
แล้วแสดงผลมุมมองให้คุณอีกครั้ง ส่วนองค์ประกอบแสงจะช่วยปลดปล่อยภาระงานให้คุณได้โดยที่คุณไม่ต้องทำอะไรเลย
4. ตั้งค่าฉากด้วย Three.js
แสงพร้อม กล้องพร้อม เรนเดอร์!
องค์ประกอบที่กำหนดเองจะใช้ three.js เพื่อแสดงผลโมเดลอิฐ 3 มิติ เราต้องการทำบางสิ่งเพียงครั้งเดียวสำหรับแต่ละอินสแตนซ์ขององค์ประกอบ <brick-viewer>
เช่น ตั้งค่าฉาก 3.js, กล้อง และการจัดแสง เราจะเพิ่มข้อมูลเหล่านี้ลงในคลาส BrickViewer เราจะเก็บวัตถุบางอย่างไว้เป็นคุณสมบัติของคลาสเพื่อใช้ในภายหลัง ได้แก่ กล้อง ฉาก การควบคุม และโหมดแสดงภาพ
เพิ่มการตั้งค่าฉากThree.js ดังนี้
export class BrickViewer extends LitElement {
private _camera: THREE.PerspectiveCamera;
private _scene: THREE.Scene;
private _controls: OrbitControls;
private _renderer: THREE.WebGLRenderer;
constructor() {
super();
this._camera = new THREE.PerspectiveCamera(45, this.clientWidth/this.clientHeight, 1, 10000);
this._camera.position.set(150, 200, 250);
this._scene = new THREE.Scene();
this._scene.background = new THREE.Color(0xdeebed);
const ambientLight = new THREE.AmbientLight(0xdeebed, 0.4);
this._scene.add( ambientLight );
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
directionalLight.position.set(-1000, 1200, 1500);
this._scene.add(directionalLight);
this._renderer = new THREE.WebGLRenderer({antialias: true});
this._renderer.setPixelRatio(window.devicePixelRatio);
this._renderer.setSize(this.offsetWidth, this.offsetHeight);
this._controls = new OrbitControls(this._camera, this._renderer.domElement);
this._controls.addEventListener("change", () =>
requestAnimationFrame(this._animate)
);
this._animate();
const resizeObserver = new ResizeObserver(this._onResize);
resizeObserver.observe(this);
}
private _onResize = (entries: ResizeObserverEntry[]) => {
const { width, height } = entries[0].contentRect;
this._renderer.setSize(width, height);
this._camera.aspect = width / height;
this._camera.updateProjectionMatrix();
requestAnimationFrame(this._animate);
};
private _animate = () => {
this._renderer.render(this._scene, this._camera);
};
}
ออบเจ็กต์ WebGLRenderer
มีองค์ประกอบ DOM ที่แสดงฉาก three.js ที่ผ่านการจัดการแสดงผล เข้าถึงได้ผ่านพร็อพเพอร์ตี้ domElement
เราสามารถแปลค่านี้ลงในลิเทอรัลของเทมเพลตการแสดงผลโดยใช้ไวยากรณ์ ${value}
นำข้อความ src
ที่เรามีในเทมเพลตออก แล้วแทรกองค์ประกอบ DOM ของโปรแกรมแสดงผล
export class BrickViewer extends LitElement {
render() {
return html`
${this._renderer.domElement}
`;
}
}
หากต้องการให้องค์ประกอบ DOM ของโปรแกรมแสดงผลแสดงอย่างสมบูรณ์ เราจะต้องตั้งค่าองค์ประกอบ <brick-viewer>
เป็น display: block
ด้วย เราสามารถใส่รูปแบบในพร็อพเพอร์ตี้แบบคงที่ที่เรียกว่า styles
ซึ่งตั้งค่าเป็นลิเทอรัลของเทมเพลต css
เพิ่มการจัดรูปแบบนี้ในชั้นเรียน:
export class BrickViewer extends LitElement {
static styles = css`
/* The :host selector styles the brick-viewer itself! */
:host {
display: block;
}
`;
}
ตอนนี้ <brick-viewer>
กำลังแสดงโหมด 3.js ที่แสดงผล:
แต่... ว่างเปล่า เราจะลองระบุโมเดล
รถตักอิฐ
เราจะส่งพร็อพเพอร์ตี้ src
ที่เรากำหนดไว้ก่อนหน้านี้ไปยัง LDrawLoader ซึ่งจัดส่งด้วย 3.js
ไฟล์ LDraw สามารถแยกโมเดล Brick เป็นขั้นตอนสิ่งปลูกสร้างที่แยกจากกัน คุณดูจำนวนขั้นตอนทั้งหมดและระดับการมองเห็นของบล็อกแต่ละรายการผ่าน LDrawLoader API ได้
คัดลอกพร็อพเพอร์ตี้เหล่านี้ เมธอด _loadModel
ใหม่ และบรรทัดใหม่ในคอนสตรัคเตอร์
@customElement('brick-viewer')
export class BrickViewer extends LitElement {
private _loader = new LDrawLoader();
private _model: any;
private _numConstructionSteps?: number;
step?: number;
constructor() {
// ...
// Add this line right before this._animate();
(this._loader as any).separateObjects = true;
this._animate();
}
private _loadModel() {
if (this.src === null) {
return;
}
this._loader
.setPath('')
// Using our src property!
.load(this.src, (newModel) => {
if (this._model !== undefined) {
this._scene.remove(this._model);
this._model = undefined;
}
this._model = newModel;
// Convert from LDraw coordinates: rotate 180 degrees around OX
this._model.rotation.x = Math.PI;
this._scene.add(this._model);
this._numConstructionSteps = this._model.userData.numConstructionSteps;
this.step = this._numConstructionSteps!;
const bbox = new THREE.Box3().setFromObject(this._model);
this._controls.target.copy(bbox.getCenter(new THREE.Vector3()));
this._controls.update();
this._controls.saveState();
});
}
}
ควรโทรหา _loadModel
เมื่อใด โดยจะต้องเรียกใช้ทุกครั้งที่แอตทริบิวต์ src มีการเปลี่ยนแปลง ในการตกแต่งพร็อพเพอร์ตี้ src
ด้วย @property
เราได้เลือกใช้วงจรการอัปเดตองค์ประกอบที่มีแสงสว่าง เมื่อใดก็ตามที่ค่าของพร็อพเพอร์ตี้ที่ตกแต่งเหล่านี้เปลี่ยนแปลง ระบบจะเรียกใช้เมธอดชุดหนึ่งที่เข้าถึงค่าใหม่และค่าเก่าของพร็อพเพอร์ตี้ได้ วิธีการใช้วงจรที่เราสนใจชื่อว่า update
เมธอด update
จะใช้อาร์กิวเมนต์ PropertyValues
ซึ่งจะมีข้อมูลเกี่ยวกับพร็อพเพอร์ตี้ที่เพิ่งเปลี่ยนแปลง นี่เป็นวิธีที่เหมาะที่สุดในการโทรหา _loadModel
เพิ่มเมธอด update
:
export class BrickViewer extends LitElement {
update(changedProperties: PropertyValues) {
if (changedProperties.has('src')) {
this._loadModel();
}
super.update(changedProperties);
}
}
ตอนนี้องค์ประกอบ <brick-viewer>
สามารถแสดงไฟล์ตัวต่อที่ระบุด้วยแอตทริบิวต์ src
ได้แล้ว
5. การแสดงโมเดลบางส่วน
ทีนี้เรามากำหนดค่าขั้นตอนการสร้างปัจจุบันกัน เราต้องการระบุ <brick-viewer step="5"></brick-viewer>
และควรเห็นลักษณะของโมเดลอิฐในขั้นตอนการก่อสร้างที่ 5 มาทำให้พร็อพเพอร์ตี้ step
เป็นพร็อพเพอร์ตี้ที่สังเกตได้ด้วยการตกแต่งด้วย @property
ตกแต่งพร็อพเพอร์ตี้ step
ดังนี้
export class BrickViewer extends LitElement {
@property({type: Number})
step?: number;
}
ตอนนี้เราจะเพิ่มเมธอดตัวช่วยที่จะแสดงเฉพาะบล็อกจนถึงขั้นตอนการสร้างปัจจุบัน เราจะเรียกใช้ตัวช่วยในเมธอดการอัปเดตเพื่อให้ทำงานทุกครั้งที่พร็อพเพอร์ตี้ step
มีการเปลี่ยนแปลง
อัปเดตเมธอด update
และเพิ่มเมธอด _updateBricksVisibility
ใหม่
export class BrickViewer extends LitElement {
update(changedProperties: PropertyValues) {
if (changedProperties.has('src')) {
this._loadModel();
}
if (changedProperties.has('step')) {
this._updateBricksVisibility();
}
super.update(changedProperties);
}
private _updateBricksVisibility() {
this._model && this._model.traverse((c: any) => {
if (c.isGroup && this.step) {
c.visible = c.userData.constructionStep <= this.step;
}
});
requestAnimationFrame(this._animate);
}
}
โอเค ตอนนี้ให้เปิด devtools ของเบราว์เซอร์ แล้วตรวจสอบองค์ประกอบ <brick-viewer>
เพิ่มแอตทริบิวต์ step
เข้าไปในลักษณะดังนี้
ดูสิ่งที่เกิดขึ้นกับโมเดลที่ผ่านการจัดการแสดงผล เราสามารถใช้แอตทริบิวต์ step
เพื่อควบคุมจำนวนของโมเดลที่จะแสดง ลักษณะที่ควรจะเป็นเมื่อตั้งค่าแอตทริบิวต์ step
เป็น "10"
6. การนำทางชุดอิฐ
mwc-icon-button
ผู้ใช้ปลายทางของ <brick-viewer>
ควรที่จะสามารถไปยังขั้นตอนบิลด์ผ่าน UI ได้ เรามาเพิ่มปุ่มสำหรับไปที่ขั้นตอนถัดไป ก่อนหน้า และขั้นตอนแรกกัน เราจะใช้องค์ประกอบเว็บของปุ่มของดีไซน์ Material เพื่อทำให้ง่าย เนื่องจากนำเข้า @material/mwc-icon-button
แล้ว เราพร้อมที่จะลดลงใน <mwc-icon-button></mwc-icon-button>
เราระบุไอคอนที่ต้องการใช้กับแอตทริบิวต์ไอคอนได้ เช่น <mwc-icon-button icon="thumb_up"></mwc-icon-button>
ดูไอคอนทั้งหมดที่เป็นไปได้ได้ที่นี่ material.io/resources/icons
ลองเพิ่มปุ่มไอคอนบางปุ่มลงในวิธีการแสดงผลกัน
export class BrickViewer extends LitElement {
render() {
return html`
${this._renderer.domElement}
<div id="controls">
<mwc-icon-button icon="replay"></mwc-icon-button>
<mwc-icon-button icon="navigate_before"></mwc-icon-button>
<mwc-icon-button icon="navigate_next"></mwc-icon-button>
</div>
`;
}
}
การใช้ดีไซน์ Material ในหน้าเว็บของเรานั้นง่ายนิดเดียว ด้วยองค์ประกอบของเว็บ
การเชื่อมโยงเหตุการณ์
ปุ่มเหล่านี้ควรทํางานจริง ปุ่ม "ตอบกลับ" ควรรีเซ็ตขั้นตอนการสร้างเป็น 1 ปุ่ม "navigate_before" ควรลดขั้นตอนการสร้าง และปุ่ม "navigate_next" ควรเพิ่มขึ้น องค์ประกอบที่มีแสงสว่างช่วยให้เพิ่มฟังก์ชันการทำงานนี้ได้ง่ายด้วยการเชื่อมโยงเหตุการณ์ ในลิเทอรัลเทมเพลต HTML ให้ใช้ไวยากรณ์ @eventname=${eventHandler}
เป็นแอตทริบิวต์ขององค์ประกอบ ตอนนี้ eventHandler
จะทํางานเมื่อตรวจพบเหตุการณ์ eventname
ในองค์ประกอบนั้น ลองดูตัวอย่างจากการเพิ่มเครื่องจัดการกิจกรรมการคลิกลงในปุ่มไอคอน 3 ปุ่มดังนี้
export class BrickViewer extends LitElement {
private _restart() {
this.step! = 1;
}
private _stepBack() {
this.step! -= 1;
}
private _stepForward() {
this.step! += 1;
}
render() {
return html`
${this._renderer.domElement}
<div id="controls">
<mwc-icon-button @click=${this._restart} icon="replay"></mwc-icon-button>
<mwc-icon-button @click=${this._stepBack} icon="navigate_before"></mwc-icon-button>
<mwc-icon-button @click=${this._stepForward} icon="navigate_next"></mwc-icon-button>
</div>
`;
}
}
ลองคลิกปุ่มต่างๆ ได้ทันที เยี่ยมมาก
รูปแบบ
ปุ่มใช้งานได้ แต่ประสิทธิภาพไม่ดี ทุกคนอยู่รวมกันที่ด้านล่าง มาจัดรูปแบบให้วางซ้อนกันในฉากกัน
หากต้องการใช้สไตล์กับปุ่มเหล่านี้ เราจะกลับไปที่พร็อพเพอร์ตี้ static styles
รูปแบบเหล่านี้มีขอบเขต ซึ่งหมายความว่าจะมีผลกับองค์ประกอบภายในคอมโพเนนต์เว็บนี้เท่านั้น ซึ่งนี่เป็นหนึ่งในข้อดีของการเขียนคอมโพเนนต์เว็บ ตัวเลือกจะเขียนได้ง่ายขึ้น และ CSS จะอ่านและเขียนได้ง่ายขึ้น สวัสดี BEM
อัปเดตรูปแบบให้มีลักษณะเช่นนี้
export class BrickViewer extends LitElement {
static styles = css`
:host {
display: block;
position: relative;
}
#controls {
position: absolute;
bottom: 0;
width: 100%;
display: flex;
}
`;
}
รีเซ็ตปุ่มกล้อง
ผู้ใช้ปลายทางของ <brick-viewer>
สามารถหมุนฉากโดยใช้การควบคุมด้วยเมาส์ ระหว่างที่เราเพิ่มปุ่ม มาเพิ่มปุ่มสำหรับรีเซ็ตกล้องไปยังตำแหน่งเริ่มต้นกัน <mwc-icon-button>
อีกรายการหนึ่งที่มีการเชื่อมโยงเหตุการณ์คลิกจะทํางานได้
export class BrickViewer extends LitElement {
private _resetCamera() {
this._controls.reset();
}
render() {
return html`
<div id="controls">
<!-- ... -->
<!-- Add this button: -->
<mwc-icon-button @click=${this._resetCamera} icon="center_focus_strong"></mwc-icon-button>
</div>
`;
}
}
การนำทางที่รวดเร็วขึ้น
ชุดบล็อกบางชุดมีขั้นตอนจำนวนมาก ผู้ใช้อาจต้องการข้ามไปยังขั้นตอนที่เฉพาะเจาะจง การเพิ่มแถบเลื่อนพร้อมหมายเลขขั้นตอนจะช่วยในการไปยังส่วนต่างๆ ได้อย่างรวดเร็ว เราจะใช้องค์ประกอบ <mwc-slider>
สำหรับขั้นตอนนี้
แถบเลื่อน mwc
องค์ประกอบแถบเลื่อนต้องมีข้อมูลสำคัญ 2-3 อย่าง เช่น ค่าต่ำสุดและสูงสุดของแถบเลื่อน ค่าต่ำสุดของแถบเลื่อนต้องเป็น "1" เสมอ ค่าสูงสุดของแถบเลื่อนควรเป็น this._numConstructionSteps
หากโหลดโมเดลแล้ว เราบอกค่าเหล่านี้ได้ <mwc-slider>
ผ่านแอตทริบิวต์ นอกจากนี้ เรายังใช้คําสั่ง ifDefined
lit-html เพื่อหลีกเลี่ยงการตั้งค่าแอตทริบิวต์ max
ได้หากไม่ได้กําหนดพร็อพเพอร์ตี้ _numConstructionSteps
เพิ่ม <mwc-slider>
ระหว่างปุ่ม "ย้อนกลับ" และ "ไปข้างหน้า"
export class BrickViewer extends LitElement {
render() {
return html`
<div id="controls">
<!-- ... backwards button -->
<!-- Add this slider: -->
<mwc-slider
step="1"
pin
markers
min="1"
max=${ifDefined(this._numConstructionSteps)}
></mwc-slider>
<!-- ... forwards button -->
</div>
`;
}
}
ข้อมูล "ขึ้น"
เมื่อผู้ใช้เลื่อนแถบเลื่อน ขั้นตอนการสร้างในปัจจุบันควรเปลี่ยนแปลงไป และการแสดงผลของโมเดลควรได้รับการอัปเดตให้สอดคล้องกัน องค์ประกอบแถบเลื่อนจะส่งเหตุการณ์อินพุตทุกครั้งที่มีการลากแถบเลื่อน เพิ่มการเชื่อมโยงเหตุการณ์ในแถบเลื่อนเองเพื่อจับเหตุการณ์นี้และเปลี่ยนขั้นตอนการสร้าง
เพิ่มการเชื่อมโยงกิจกรรม
export class BrickViewer extends LitElement {
render() {
return html`
<div id="controls">
<!-- ... -->
<!-- Add the @input event binding: -->
<mwc-slider
...
@input=${(e: CustomEvent) => this.step = e.detail.value}
></mwc-slider>
<!-- ... -->
</div>
`;
}
}
เย่! เราสามารถใช้แถบเลื่อนเพื่อเปลี่ยนขั้นตอนที่จะแสดงได้
ข้อมูล "ลดลง"
อีกเรื่องหนึ่ง เมื่อใช้ปุ่ม "ย้อนกลับ" และ "ถัดไป" เพื่อเปลี่ยนขั้นตอน ต้องอัปเดตแฮนเดิลแถบเลื่อน เชื่อมโยงแอตทริบิวต์ค่าของ <mwc-slider>
กับ this.step
เพิ่มการเชื่อมโยง value
:
export class BrickViewer extends LitElement {
render() {
return html`
<div id="controls">
<!-- ... -->
<!-- Add the value property binding: -->
<mwc-slider
...
value=${ifDefined(this.step)}
></mwc-slider>
<!-- ... -->
</div>
`;
}
}
เรากําลังจะสร้างแถบเลื่อนเกือบเสร็จแล้ว เพิ่มสไตล์ Flex เพื่อให้ทำงานร่วมกับตัวควบคุมอื่นๆ ได้ดี
export class BrickViewer extends LitElement {
static styles = css`
/* ... */
mwc-slider {
flex-grow: 1;
}
`;
}
นอกจากนี้ เรายังต้องเรียก layout
ในองค์ประกอบแถบเลื่อนด้วย เราจะทำแบบนั้นในเมธอดอายุการใช้งาน firstUpdated
ซึ่งเรียกว่าเมื่อมีการจัดวาง DOM ครั้งแรก เครื่องมือตกแต่ง query
จะช่วยให้เรารับการอ้างอิงองค์ประกอบแถบเลื่อนในเทมเพลตได้
export class BrickViewer extends LitElement {
@query('mwc-slider')
slider!: Slider|null;
async firstUpdated() {
if (this.slider) {
await this.slider.updateComplete
this.slider.layout();
}
}
}
รายการต่อไปนี้คือการเพิ่มแถบเลื่อนทั้งหมดไว้ด้วยกัน (พร้อมแอตทริบิวต์ pin
และ markers
เพิ่มเติมบนแถบเลื่อนเพื่อทำให้ดูเท่)
export class BrickViewer extends LitElement {
@query('mwc-slider')
slider!: Slider|null;
static styles = css`
/* ... */
mwc-slider {
flex-grow: 1;
}
`;
async firstUpdated() {
if (this.slider) {
await this.slider.updateComplete
this.slider.layout();
}
}
render() {
return html`
${this._renderer.domElement}
<div id="controls">
<mwc-icon-button @click=${this._restart} icon="replay"></mwc-icon-button>
<mwc-icon-button @click=${this._stepBack} icon="navigate_before"></mwc-icon-button>
<mwc-slider
step="1"
pin
markers
min="1"
max=${ifDefined(this._numConstructionSteps)}
?disabled=${this._numConstructionSteps === undefined}
value=${ifDefined(this.step)}
@input=${(e: CustomEvent) => this.constructionStep = e.detail.value}
></mwc-slider>
<mwc-icon-button @click=${this._stepForward} icon="navigate_next"></mwc-icon-button>
<mwc-icon-button @click=${this._resetCamera} icon="center_focus_strong"></mwc-icon-button>
</div>
`;
}
}
สินค้าสุดท้ายมาแล้ว
7. บทสรุป
เราเรียนรู้วิธีใช้ lit-element เพื่อสร้างองค์ประกอบ HTML ของเราเองมากมาย เราเรียนรู้วิธีต่อไปนี้
- กำหนดองค์ประกอบที่กำหนดเอง
- ประกาศแอตทริบิวต์ API
- แสดงผลมุมมองสําหรับองค์ประกอบที่กําหนดเอง
- บรรจุรูปแบบ
- ใช้เหตุการณ์และพร็อพเพอร์ตี้เพื่อส่งข้อมูล
หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับ lit-element โปรดอ่านเว็บไซต์อย่างเป็นทางการ
คุณดูองค์ประกอบ brick-viewer ที่เสร็จสมบูรณ์ได้ที่ stackblitz.com/edit/brick-viewer-complete
นอกจากนี้ brick-viewer ยังมาพร้อมกับ NPM และคุณสามารถดูแหล่งที่มาได้ที่นี่ Github repo