লিট-এলিমেন্ট সহ একটি ইট ভিউয়ার তৈরি করুন

1. ভূমিকা

ওয়েব উপাদান

ওয়েব কম্পোনেন্ট হল ওয়েব স্ট্যান্ডার্ডের একটি সংগ্রহ যা ডেভেলপারদের কাস্টম উপাদান সহ HTML প্রসারিত করতে দেয়। এই কোডল্যাবে, আপনি <brick-viewer> উপাদানটি সংজ্ঞায়িত করবেন, যা ইটের মডেলগুলি প্রদর্শন করতে সক্ষম হবে!

আলোক-উপাদান

আমাদের কাস্টম উপাদান <brick-viewer> সংজ্ঞায়িত করতে সাহায্য করার জন্য, আমরা lit-element ব্যবহার করব। lit-element হল একটি লাইটওয়েট বেস ক্লাস যা ওয়েব কম্পোনেন্ট স্ট্যান্ডার্ডে কিছু সিনট্যাকটিক চিনি যোগ করে। এটি আমাদের জন্য আমাদের কাস্টম উপাদানের সাথে উঠা এবং চালানো সহজ করে তুলবে।

শুরু করুন

আমরা একটি অনলাইন স্ট্যাকব্লিটজ পরিবেশে কোডিং করব, তাই একটি নতুন উইন্ডোতে এই লিঙ্কটি খুলুন:

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-এ ব্যবহারের জন্য প্রস্তুত। কিন্তু, যদি আপনি এটি চেষ্টা করেন, কিছুই রেন্ডার হবে না। এর ঠিক করা যাক.

রেন্ডার পদ্ধতি

কম্পোনেন্টের ভিউ বাস্তবায়ন করতে, রেন্ডার নামে একটি পদ্ধতি নির্ধারণ করুন। এই পদ্ধতিটি 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 ক্লাসের মধ্যে থেকে পাঠযোগ্য, ধন্যবাদ lit-element-এর জন্য।

মান প্রদর্শন করা হচ্ছে

আমরা রেন্ডার পদ্ধতির টেমপ্লেট লিটারাল ব্যবহার করে src অ্যাট্রিবিউটের মান প্রদর্শন করতে পারি। ${value} সিনট্যাক্স ব্যবহার করে টেমপ্লেট লিটারেলে মানগুলিকে ইন্টারপোলেট করুন।

export class BrickViewer extends LitElement {
  render() {
    return html`<div>Brick model: ${this.src}</div>`;
  }
}

এখন, আমরা উইন্ডোতে <brick-viewer> এলিমেন্টে src অ্যাট্রিবিউটের মান দেখতে পাচ্ছি। এটি চেষ্টা করুন: আপনার ব্রাউজারের বিকাশকারী সরঞ্জামগুলি খুলুন এবং ম্যানুয়ালি src বৈশিষ্ট্যটি পরিবর্তন করুন৷ এগিয়ে যান, চেষ্টা করুন...

...আপনি কি লক্ষ্য করেছেন যে উপাদানটির পাঠ্য স্বয়ংক্রিয়ভাবে আপডেট হয়? lit-element @property দিয়ে সজ্জিত শ্রেণী বৈশিষ্ট্যগুলি পর্যবেক্ষণ করে এবং আপনার জন্য দৃশ্যটি পুনরায় রেন্ডার করে! lit-element ভারী উত্তোলন করে তাই আপনাকে করতে হবে না।

4. Three.js দিয়ে দৃশ্য সেট করুন

লাইট, ক্যামেরা, রেন্ডার!

আমাদের কাস্টম উপাদান আমাদের 3D ইট মডেল রেন্ডার করতে three.js ব্যবহার করবে। কিছু জিনিস আছে যা আমরা একটি <brick-viewer> উপাদানের প্রতিটি উদাহরণের জন্য একবার করতে চাই, যেমন three.js দৃশ্য, ক্যামেরা এবং আলো সেট আপ করা। আমরা কন্সট্রাক্টর ব্রিকভিউয়ার ক্লাসে এগুলি যোগ করব। আমরা কিছু বস্তুকে শ্রেণি বৈশিষ্ট্য হিসেবে রাখব যাতে আমরা সেগুলিকে পরে ব্যবহার করতে পারি: ক্যামেরা, দৃশ্য, নিয়ন্ত্রণ এবং রেন্ডারার।

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}
    `;
  }
}

রেন্ডারারের ডোম উপাদানটিকে সম্পূর্ণরূপে দেখানোর অনুমতি দেওয়ার জন্য, আমাদের প্রদর্শনের জন্য <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> একটি রেন্ডার করা three.js দৃশ্য প্রদর্শন করছে:

একটি ইট-দর্শক উপাদান একটি রেন্ডার করা, কিন্তু খালি, দৃশ্য প্রদর্শন করছে।

কিন্তু... এটা খালি। এর একটি মডেল দিয়ে এটি প্রদান করা যাক.

ইট লোডার

আমরা আগে সংজ্ঞায়িত src প্রপার্টি LDrawLoader-এ পাস করব, যেটি three.js দিয়ে পাঠানো হয়েছে।

LDraw ফাইলগুলি একটি ইট মডেলকে পৃথক বিল্ডিং ধাপে আলাদা করতে পারে। 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 বৈশিষ্ট্য যুক্ত করুন, যেমন:

একটি ইট-ভিউয়ার এলিমেন্টের HTML কোড, একটি স্টেপ অ্যাট্রিবিউট 10 এ সেট করা আছে।

রেন্ডার করা মডেলের কি হয় দেখুন! মডেলের কতটা দেখানো হয়েছে তা নিয়ন্ত্রণ করতে আমরা step বৈশিষ্ট্য ব্যবহার করতে পারি। step অ্যাট্রিবিউটটি "10" এ সেট করা হলে এটি কেমন হওয়া উচিত তা এখানে:

মাত্র দশটি নির্মাণ ধাপ সহ একটি ইটের মডেল।

6. ইট সেট নেভিগেশন

mwc-আইকন-বোতাম

আমাদের <brick-viewer> -এর শেষ-ব্যবহারকারীরও UI-এর মাধ্যমে বিল্ড স্টেপ নেভিগেট করতে সক্ষম হওয়া উচিত। চলুন পরবর্তী ধাপ, পূর্ববর্তী ধাপ এবং প্রথম ধাপে যাওয়ার জন্য বোতাম যোগ করি। এটিকে সহজ করতে আমরা মেটেরিয়াল ডিজাইনের বোতাম ওয়েব কম্পোনেন্ট ব্যবহার করব। যেহেতু @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>
    `;
  }
}

আমাদের পৃষ্ঠায় উপাদান ডিজাইন ব্যবহার করা সহজ, ওয়েব উপাদানগুলির জন্য ধন্যবাদ!

ইভেন্ট বাঁধাই

এই বোতাম আসলে কিছু করা উচিত. "উত্তর" বোতামটি নির্মাণের ধাপটি 1 এ রিসেট করা উচিত। "নেভিগেট_আগে" বোতামটি নির্মাণের ধাপটি হ্রাস করবে এবং "নেভিগেট_নেক্সট" বোতামটি এটিকে বৃদ্ধি করবে। lit-element ইভেন্ট বাইন্ডিং সহ এই কার্যকারিতা যোগ করা সহজ করে তোলে। আপনার এইচটিএমএল টেমপ্লেট আক্ষরিক, একটি উপাদান বৈশিষ্ট্য হিসাবে সিনট্যাক্স @eventname=${eventHandler} ব্যবহার করুন। eventHandler এখন চালানো হবে যখন সেই উপাদানটিতে একটি eventname ইভেন্ট সনাক্ত করা হয়! উদাহরণ হিসেবে, আমাদের তিনটি আইকন বোতামে ক্লিক ইভেন্ট হ্যান্ডলার যোগ করা যাক:

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 পড়তে এবং লিখতে সহজ হবে। বাই-বাই, বিইএম !

শৈলীগুলি আপডেট করুন যাতে সেগুলি এইরকম দেখায়:

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-স্লাইডার

স্লাইডার উপাদানটির জন্য ন্যূনতম এবং সর্বাধিক স্লাইডার মানের মতো গুরুত্বপূর্ণ ডেটার কয়েকটি টুকরো প্রয়োজন। সর্বনিম্ন স্লাইডার মান সর্বদা "1" হতে পারে। স্লাইডারের সর্বোচ্চ মান this._numConstructionSteps হওয়া উচিত।_numConstructionSteps , যদি মডেলটি লোড হয়ে থাকে। আমরা <mwc-slider> এর বৈশিষ্ট্যগুলির মাধ্যমে এই মানগুলি বলতে পারি। যদি _numConstructionSteps প্রপার্টি সংজ্ঞায়িত করা না থাকে তাহলে max অ্যাট্রিবিউট সেট করা এড়াতে আমরা ifDefined lit-html নির্দেশিকা ব্যবহার করতে পারি।

"ব্যাক" এবং "ফরওয়ার্ড" বোতামগুলির মধ্যে একটি <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>
    `;
  }
}

উঃ! কোন ধাপটি প্রদর্শিত হবে তা পরিবর্তন করতে আমরা স্লাইডার ব্যবহার করতে পারি।

ডেটা "ডাউন"

আর একটা জিনিস আছে। যখন "পিছনে" এবং "পরবর্তী" বোতামগুলি পদক্ষেপটি পরিবর্তন করতে ব্যবহার করা হয়, তখন স্লাইডার হ্যান্ডেল আপডেট করা প্রয়োজন৷ this.step<mwc-slider> -এর মান বৈশিষ্ট্য বাঁধুন।

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>
    `;
  }
}

আমরা স্লাইডারের সাথে প্রায় সম্পন্ন করেছি। এটি অন্যান্য নিয়ন্ত্রণের সাথে সুন্দরভাবে খেলতে একটি ফ্লেক্স শৈলী যোগ করুন:

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 ব্যবহার করতে হয় সে সম্পর্কে অনেক কিছু শিখেছি। আমরা শিখেছি কিভাবে:

  • একটি কাস্টম উপাদান সংজ্ঞায়িত করুন
  • একটি অ্যাট্রিবিউট API ঘোষণা করুন
  • একটি কাস্টম উপাদানের জন্য একটি দৃশ্য রেন্ডার করুন
  • শৈলী encapsulate
  • ডেটা পাস করতে ইভেন্ট এবং বৈশিষ্ট্য ব্যবহার করুন

আপনি যদি লিট-এলিমেন্ট সম্পর্কে আরও জানতে চান তবে আপনি এর অফিসিয়াল সাইটে আরও পড়তে পারেন।

আপনি stackblitz.com/edit/brick-viewer-complete এ একটি সম্পূর্ণ ইট-ভিউয়ার উপাদান দেখতে পারেন।

ইট-ভিউয়ারও NPM-এ পাঠানো হয়, এবং আপনি এখানে উৎস দেখতে পারেন: Github repo