.. role:: clio-inherited
   :class: clio-flag clio-flag-inherited


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

.. js:class:: cee.mrk.PartImageLabel

   Defines a part showing an image attached to a 3d coordinate that can be shown in a :js:class:`MarkupModel <cee.mrk.MarkupModel>`\ .
   
   The image is provided as a :js:class:`Texture <cee.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
   
   
   ::
   
      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
   
   
   ::
   
      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
   
   
   ::
   
      // 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 :js:class:`~cee.TextureOptions` without mipmap when you generate the texture, e.g.:
   
   
   ::
   
      { 
        generateMipmaps: false, 
        wrapMode: cee.TextureWrapMode.CLAMP_TO_EDGE, 
        minFilter: cee.TextureMinFilter.LINEAR 
      }
   
   Use :js:meth:`MarkupModel.addImageLabelPart <cee.mrk.MarkupModel.addImageLabelPart>` to create a new instance of this class.
   
   .. image:: /images/MrkPartImageLabel.png
      :alt: None
   
   **Example showing HTML text rendered to SVG/XML and shown as PartImageLabel parts:** 
   
   
   Index
   =====
   
   .. rubric:: Accessors
   
   
   .. rst-class:: api-xref-list
   
   
   * :js:func:`~cee.mrk.PartImageLabel.attachmentAppearance`
   * :js:func:`~cee.mrk.PartImageLabel.customData`
   
   .. rubric:: Methods
   
   
   .. rst-class:: api-xref-list
   
   
   * :js:meth:`~cee.mrk.PartImageLabel.rayIntersect`
   * :js:meth:`~cee.mrk.PartImageLabel.set`
   
   



.. rst-class:: kind-group kind-accessors

.. rubric:: Accessors
   :class: kind-group-title


.. js:method:: cee.mrk.PartImageLabel.attachmentAppearance

      .. rst-class:: sig-pretty-signature
      
         | *get* attachmentAppearance(): :js:class:`LabelAttachmentAppearance <cee.mrk.LabelAttachmentAppearance>`
      
      Returns an active reference to the attachment appearance settings for this part.
      
      **Returns**\ : :js:class:`LabelAttachmentAppearance <cee.mrk.LabelAttachmentAppearance>`
      



.. js:method:: cee.mrk.PartImageLabel.customData

      .. rst-class:: clio-flags
      
         :clio-inherited:`inherited`
      
      .. rst-class:: sig-pretty-signature
      
         | *get* customData(): *any*
      
      Custom data for the part. This field is not used by EnvisionWeb.
      
      **Returns**\ : *any*
      
      .. rst-class:: sig-pretty-signature
      
         | *set* customData(**data**\ : *any*\ ): *void*
      
      **Parameters**
      
      
         **data**\ : *any*
      
      
      **Returns**\ : *void*
      



.. rst-class:: kind-group kind-methods

.. rubric:: Methods
   :class: kind-group-title


.. js:method:: cee.mrk.PartImageLabel.rayIntersect

      .. rst-class:: sig-pretty-signature
      
         | rayIntersect(**ray**\ : :js:class:`Ray <cee.Ray>`\ , **hitItem**\ : :js:class:`PartHitItem <cee.mrk.PartHitItem>`\ ): *boolean*
      
      Picking
      
      **Parameters**
      
      
         **ray**\ : :js:class:`Ray <cee.Ray>`
      
         **hitItem**\ : :js:class:`PartHitItem <cee.mrk.PartHitItem>`
      
      
      **Returns**\ : *boolean*
      



.. js:method:: cee.mrk.PartImageLabel.set

      .. rst-class:: sig-pretty-signature
      
         | set(**image**\ : :js:class:`Texture <cee.Texture>`\ , **pos**\ : :js:class:`Vec3 <cee.Vec3>`\ ): *void*
      
      Set the image to use for the label and the position (3d coordinate) of the label
      
      **Parameters**
      
      
         **image**\ : :js:class:`Texture <cee.Texture>`
      
         **pos**\ : :js:class:`Vec3 <cee.Vec3>`
      
      
      **Returns**\ : *void*
      




