.. role:: ts-api-decorator

##############
PartImageLabel
##############

.. js:module:: cee.mrk
   :noindex:

.. container:: ts-api-section

   .. js:class:: PartImageLabel

      Defines a part showing an image attached to a 3d coordinate that can be shown in a ``MarkupModel``.

      The image is provided as a ``Texture``. The texture can be created from ImageData or from a 
      HTMLImageElement.

      The label will always be visible and rendered in front of any model. The anchor point will be rendered
      at the depth of the specified 3d coordinate.

      **Creating the texture**

      To create the ImageData for the texture you have some options:

      1) Create an offscreen canvas element, and use the 2d context to render text, draw lines, etc


      .. code-block::


         let canvas = document.createElement("canvas");
         let ctx = canvas.getContext("2d");

         canvas.width = 200;
         canvas.height = 50;
         ctx.font = "20px Georgia";
         ctx.fillStyle = "red";
         ctx.fillText("Hello EnvisionWeb!", 10, 40);

         const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
         const texture = cee.Texture.fromImageData(imageData, 
            { generateMipmaps: false, 
              wrapMode: cee.TextureWrapMode.CLAMP_TO_EDGE, 
              minFilter: cee.TextureMinFilter.LINEAR 
            });  
         part.set(texture, pickInfo.intersectionPoint);



      2) Provide an RGBA array with pixel data for the image


      .. code-block::


         const sizeX = 256;
         const sizeY = 256;
         const pixelArr = new Uint8ClampedArray(4*sizeX*sizeY);
         let idx = 0;

         for (let y = 0; y < sizeY; ++y) {
             for (let x = 0; x < sizeX; ++x) {
                 pixelArr[idx++]  = y%2 == 0 ? 255 : 0;  
                 pixelArr[idx++]  = x%2 == 0 ? 255 : 0;  
                 pixelArr[idx++]  = (x+y)%2 == 0 ? 255 : 0;  
                 pixelArr[idx++]  = 255; 
             }
         }

         const imageData  = new ImageData(pixelArr, sizeX, sizeY);
         const texture = cee.Texture.fromImageData(imageData, 
            { generateMipmaps: false, 
              wrapMode: cee.TextureWrapMode.CLAMP_TO_EDGE, 
              minFilter: cee.TextureMinFilter.LINEAR 
            });  
         part.set(texture, pickInfo.intersectionPoint);



      3) Render HTML using SVG/XML


      .. code-block::


         // Render HTML with SVG and XML
         const canvas = document.createElement("canvas");
         const ctx = canvas.getContext("2d");
         canvas.width = 300;
         canvas.height = 200;

         // Background gradient
         {
            var grd = ctx.createLinearGradient(0, 0, canvas.width, 0);
            grd.addColorStop(0, "#eeeeee");
            grd.addColorStop(1, "#ffffff");
   
            ctx.fillStyle = grd;
            ctx.fillRect(0, 0, canvas.width, canvas.height);
         }            

         // Draw border
         {
            ctx.lineWidth = 2;
            ctx.fillStyle = "black";
            ctx.strokeRect(0, 0, canvas.width, canvas.height);
         }

         const data = `
         data:image/svg+xml,
         <svg xmlns='http://www.w3.org/2000/svg' width='${canvas.width}' height='${canvas.height}'>
          <foreignObject width='100%' height='100%'>
            <div xmlns='http://www.w3.org/1999/xhtml' style='font-size:12px;font-family:verdana;   padding-top: 0px; padding-right: 10px;padding-bottom: 10px;padding-left: 10px;'>
              <h1>Region ${this.m_labelMrkModel.partCount}</h1>
              <table>
                <tr><td><b>Surface Area</b></td><td></td><td>0.02e-4 m^2</td></tr>
                <tr><td><b>Minimum</b></td><td><b>Average</b></td><td><b>Maximum</b></td></tr>
                <tr><td>0.1e-2 m^2</td><td>0.2e-2 m^2</td><td>0.4e-2 m^2</td></tr>
                <tr><td><b>Flow rate:</b></td><td></td><td>0.2e-2 m^3/s</td></tr>
                <tr><td> </td><td></td><td></td></tr>
                <tr><td><b>Pressure force:</b></td><td></td><td></td></tr>
                <tr><td>x: 0.1e-2 N</td><td>y: 0.2e-2 N</td><td>z: 0.4e-2 N</td></tr>
              </table>
            </div>
          </foreignObject>
         </svg>
         `;

         const img = new Image();
         img.src = data;
         const myThis = this;
         img.onload = (_ev: Event) => { 
            ctx.drawImage(img, 0, 0); 
            const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
            const texture = cee.Texture.fromImageData(imageData,     
              { generateMipmaps: false, 
                wrapMode: cee.TextureWrapMode.CLAMP_TO_EDGE, 
                minFilter: cee.TextureMinFilter.LINEAR 
              });  
            myThis.m_pickingImageLabelPart.set(texture, pickInfo.intersectionPoint);
         }                




      **Note:** If you want to use a NPOT (non-power-of-two) texture, make sure you provide texture
      options ``cee.TextureOptions`` without mipmap when you generate the texture, e.g.:


      .. code-block::


         { 
           generateMipmaps: false, 
           wrapMode: cee.TextureWrapMode.CLAMP_TO_EDGE, 
           minFilter: cee.TextureMinFilter.LINEAR 
         }



      Use ``MarkupModel.addImageLabelPart`` to create a new instance of this class. 

      **Example showing HTML text rendered to SVG/XML and shown as PartImageLabel parts:**
      .. image:: /images/MrkPartImageLabel.png





.. container:: api-index-section

   .. rubric:: Accessors

   .. rst-class:: api-index-list-item api-kind-accessor api-parent-kind-class

   * :js:attr:`~cee.mrk.PartImageLabel.attachmentAppearance`
   * :js:attr:`~cee.mrk.PartImageLabel.customData`



.. container:: api-index-section

   .. rubric:: Methods

   .. rst-class:: api-index-list-item api-kind-method api-parent-kind-class

   * :js:meth:`~cee.mrk.PartImageLabel.rayIntersect`
   * :js:meth:`~cee.mrk.PartImageLabel.set`





------------

Accessors
=========

.. container:: ts-api-section

   .. js:function:: PartImageLabel.attachmentAppearance()



      Returns an active reference to the attachment appearance settings for this part.


      :rtype: LabelAttachmentAppearance



.. container:: ts-api-section

   .. js:function:: PartImageLabel.customData()



      Custom data for the part. This field is not used by EnvisionWeb.


      :rtype: any

   .. js:function:: PartImageLabel.customData( data)

      :param data: None
      :type data: any


      :rtype: void



Methods
=======

.. rst-class:: ts-api-section

rayIntersect
------------

.. js:method:: PartImageLabel.rayIntersect( ray, hitItem)

   :param ray: None
   :type ray: Ray
   :param hitItem: None
   :type hitItem: PartHitItem


   Picking


   :rtype: boolean

.. rst-class:: ts-api-section

set
---

.. js:method:: PartImageLabel.set( image, pos)

   :param image: None
   :type image: Texture
   :param pos: None
   :type pos: Vec3


   Set the image to use for the label and the position (3d coordinate) of the label


   :rtype: void

