How to calculate 3d point on a 2d triangle in a 3d space?

I’m making my own 3D renderer in JS and am trying to create a z-buffer. However, I need to then get the position of each pixel on the triangles being rendered to get the distance from the camera. I can get which pixels I need to measure, but how can I find the cooridnates on the triangle?

To clarify, I’m not trying to render a triangle or find the coordinates of the vertice. I’m trying to find the position of a point on the triangle that is spread through three dimensions.

Mock one function under object instantiated from class in jest

I need to test how my function would respond when only one of the methods under an object instantiated in the function script returns a certain value.

The function’s script:

import TTLCache from '@isaacs/ttlcache';

const DATA_KEY = 'barks';

const dataCache = new TTLCache({ ttl: 100, checkAgeOnGet: true, max: 1 });

export const getCachedData = async (): Promise<string | undefined> => {    
    if (!dataCache.has(DATA_KEY)) {
        dataCache.set(DATA_KEY, 'new-item');
    }

    return dataCache.get(DATA_KEY);
};

My test:

import { getCachedData } from '../functionScript';

const mockGetRemainingTTL = jest.fn();

jest.mock('@isaacs/ttlcache', () => {
    return jest.fn().mockImplementation(() => ({
        ...jest.requireActual('@isaacs/ttlcache'),
        getRemainingTTL: () => mockGetRemainingTTL(),
    }));
})

describe('ttlCaching', () => {
    test('Return undefined when ttl has expired', async () => {
        mockGetRemainingTTL.mockReturnValue(0);
        expect(await getCachedData()).toEqual(undefined);
    });
});

getRemainingTTL is a method under the cache object that gets called internally.

For the above test, I get the error:
“TypeError: dataCache.has is not a function”

I do not understand why the ...jest.requireActual('@isaacs/ttlcache') part did not fill in the original implementations.

How can I create a rotating slider with clickable circles and arrow controls?

I’m developing a rotating slider interface where several circles are arranged in a circular layout. I want the slider to have two main functionalities:

Clickable Circles: When a user clicks on any circle, it should smoothly rotate and reposition so that the clicked circle becomes the central, prominent element.

Arrow Controls: In addition to clicking the circles, I’d like to include left/right arrow buttons that allow the user to rotate through the circles.

I’ve attempted to implement this behavior using HTML/CSS/JavaScript, but I’m encountering issues with the position of circles, rotation animations and ensuring the clicked circle transitions correctly to the main position. Additionally, managing the arrow control rotations has proven challenging.

Could someone provide guidance or examples on how to achieve this functionality? Any suggestions for libraries, frameworks, or code examples that can help me implement a smooth, interactive rotating slider would be greatly appreciated.

Thank you in advance for your help.

Rotating Circles Slider

  // Grab all carousel items and the main circle
  const items = document.querySelectorAll('.carousel-item');
  const mainCircle = document.getElementById('mainCircle');
  const arrowLeft = document.getElementById('arrowLeft');
  const arrowRight = document.getElementById('arrowRight');
  
  // Track which item is "active"
  let activeIndex = 0;

  // Update positions based on the active index
  function updateCarousel() {
    // Update main circle text to match the active item
    mainCircle.textContent = items[activeIndex].textContent;
    
    const totalItems = items.length;
    const angleStep = 360 / totalItems;
    
    // Define ellipse radii (must match the SVG ellipse)
    const radiusX = 250;  // horizontal radius
    const radiusY = 50;   // vertical radius
    
    items.forEach((item, i) => {
      // Calculate angle relative to the active index
      const angle = (i - activeIndex) * angleStep;
      const rad = angle * Math.PI / 180;
      
      // Calculate x/y positions for elliptical orbit
      const x = radiusX * Math.cos(rad);
      const y = radiusY * Math.sin(rad);
      
      // Move each item into position around the main circle
      item.style.transform = `translate(-50%, -50%) translate(${x}px, ${y}px)`;
    });
  }

  // Event listeners for arrow clicks
  arrowLeft.addEventListener('click', () => {
    activeIndex = (activeIndex - 1 + items.length) % items.length;
    updateCarousel();
  });
  
  arrowRight.addEventListener('click', () => {
    activeIndex = (activeIndex + 1) % items.length;
    updateCarousel();
  });

  // Event listener for clicking on an outer item
  items.forEach((item, i) => {
    item.addEventListener('click', () => {
      activeIndex = i;
      updateCarousel();
    });
  });

  // Initialize the carousel on page load
  updateCarousel();
 .carousel-container {
      position: relative;
      width: 900px;
      height: 300px;
      margin:  auto;
      overflow: hidden;
      /* Remove the container border since we use an SVG for the orbit */
    }
    
    /* SVG orbit drawn behind the circles */
    .orbit {
      position: absolute;
      top: 0;
      left: 0;
      z-index: 1;
    }
    
    /* The central circle (the "sun") */
    .carousel-center {
      position: absolute;
      top: 80%; /* Orbit center vertical position */
      left: 50%;
      width: 120px;
      height: 120px;
      background-color: orange;
      border-radius: 50%;
      transform: translate(-50%, -50%);
      display: flex;
      align-items: center;
      justify-content: center;
      text-align: center;
      font-weight: bold;
      color: #fff;
      z-index: 10;
      box-shadow: 0 0 8px rgba(0,0,0,0.3);
      cursor: default;
    }
    
    /* Outer circles (the "planets") */
    .carousel-item {
      position: absolute;
      top: 80%; /* Same center as the main circle */
      left: 50%;
      width: 80px;
      height: 80px;
      background-color: #ffe0a2;
      border-radius: 50%;
      transform: translate(-50%, -50%);
      display: flex;
      align-items: center;
      justify-content: center;
      text-align: center;
      cursor: pointer;
      transition: transform 0.5s;
      box-shadow: 0 0 5px rgba(0,0,0,0.2);
      z-index: 5;
    }

    /* Arrows for manual sliding */
    .carousel-arrow {
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      background-color: #ddd;
      border: none;
      padding: 10px 15px;
      cursor: pointer;
      z-index: 20;
      font-size: 16px;
      border-radius: 4px;
      box-shadow: 0 0 5px rgba(0,0,0,0.2);
    }
    .carousel-arrow.left {
      left: 10px;
    }
    .carousel-arrow.right {
      right: 10px;
    }
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Carousel Orbit</title>
</head>
<body>

<div class="carousel-container">
  <!-- SVG Orbit Path matching the ellipse in JS -->
  <svg class="orbit" width="900" height="300">
    <!-- The ellipse is centered at (450, 240) which is 50% (450px) horizontally and 80% (240px of 300px) vertically -->
    <ellipse cx="450" cy="240" rx="250" ry="50" fill="none" stroke="#ccc" stroke-dasharray="5,5" />
  </svg>

  <!-- Main circle (active item) -->
  <div class="carousel-center" id="mainCircle">API Applications</div>
  
  <!-- Outer circles (planets) -->
  <div class="carousel-item" data-index="0">E2E Testing</div>
  <div class="carousel-item" data-index="1">API Portal</div>
  <div class="carousel-item" data-index="2">API Governance</div>
  <div class="carousel-item" data-index="3">API Navigator</div>
  
  <!-- Navigation arrows -->
  <button class="carousel-arrow left" id="arrowLeft">&lt;</button>
  <button class="carousel-arrow right" id="arrowRight">&gt;</button>
</div>


 
</body>
</html>

JavaScript drop Table row before or after an other row

my script for dragging and dropping table rows inserts the rows always before (in function dropHandler).
This works fine, but I additionally would like to check if I dropped the row AFTER the last existing row and then insert the row at the end of the table body.

Is there a way to do this?

/*** Drag und Drop der Tabellenzeilen */
function dragstartHandler(ev) {
  sourceRow = ev.target;
  sourceTableId = sourceRow.closest("table").id;
}

function dragoverHandler(ev) {
  ev.preventDefault();
}

function dropHandler(ev) {
  ev.preventDefault();
  targetRow = ev.target.closest("tr");
  targetTable = targetRow.closest("table");
  targetTableId = targetRow.closest("table").id;
  if (sourceTableId === targetTableId) {
    //console.log("richtige Tabelle");
    targetTableBody = targetRow.closest("tbody");
    targetTableBody.insertBefore(sourceRow, targetRow);
    rebuildIndex(targetTableBody);
    //sourceRow.classList.remove("dragRow");
  } else {
    console.log("falsche Tabelle")
  }
}
<table id="table2">
  <thead>
    <tr>
      <th>Head1</th>
      <th>Head2</th>
      <th>Head3</th>
      <th>Head4</th>
    </tr>
  </thead>
  <tbody id="tableBody-table2">
    <tr id="table2_row1" draggable="true" ondragstart="dragstartHandler(event)" ondrop="dropHandler(event)" ondragover="dragoverHandler(event)">
      <td>table 2 values 1</td>
      <td>table 2 values 2</td>
      <td>table 2 values 3</td>
      <td>table 2 values 4</td>
    </tr>
    <tr id="table2_row2" draggable="true" ondragstart="dragstartHandler(event)" ondrop="dropHandler(event)" ondragover="dragoverHandler(event)">
      <td>table 2 values 5</td>
      <td>table 2 values 6</td>
      <td>table 2 values 7</td>
      <td>table 2 values 8</td>
    </tr>
    <tr id="table2_row3" draggable="true" ondragstart="dragstartHandler(event)" ondrop="dropHandler(event)" ondragover="dragoverHandler(event)">
      <td>table 2 values 8</td>
      <td>table 2 values 9</td>
      <td>table 2 values 10</td>
      <td>table 2 values 11</td>
    </tr>
  </tbody>
</table>

Can’t change line thickness

I’m creating an axis with circles in it, I need the logic for interpolation, so the solution should work with it. Everything works normally, I just can’t change line thickness, I tried various methods and none work, or they do but I can’t integrate interpolation (or I’m just dumb)
I tried using meshlinematerial with a mesh instead of linebasicmaterial and lineloop but they didn’t even appear (no idea what the problem was and it was the closest to my current logic, so if it does work I think it’s my best bet)

import { MeshLineGeometry, MeshLineMaterial } from "meshline";
import { useRef, useEffect } from "react";
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
import {
  Line2,
  LineGeometry,
  LineMaterial,
} from "three/examples/jsm/Addons.js";

const Axis = () => {
  const mountRef = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    const mountain = mountRef.current;
    const textureLoader = new THREE.TextureLoader();
    const starTexture = textureLoader.load("star3.png");
    const axisLength = 80;
    //# Scene
    const scene = new THREE.Scene();
    scene.frustumCulled = false;
    scene.background = new THREE.Color("#000");
    scene.fog = new THREE.FogExp2(0x000000, 0.001);

    //# Renderer
    const renderer = new THREE.WebGLRenderer({ antialias: true });
    if (mountRef.current) {
      renderer.setSize(window.innerWidth, window.innerHeight);
      renderer.setPixelRatio(window.devicePixelRatio);
      // Append the renderer's canvas element to our container.
      mountRef.current.appendChild(renderer.domElement);
      console.log(renderer.domElement);
    }
    //# Camera
    const camera = new THREE.PerspectiveCamera(
      50,
      window.innerWidth / window.innerHeight,
      0.5,
      10000
    );
    camera.position.set(200, 100, -30);

    //# OrbitControls
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true;
    controls.dampingFactor = 0.05;

    //# Group
    const objectGroup = new THREE.Group();

    //# Axes
    function createAxis(
      points: THREE.Vector3[],
      color: string,
      thickness: number
    ) {
      const positions = points.flatMap((p) => [p.x, p.y, p.z]);
      const geometry = new LineGeometry();
      geometry.setPositions(positions);

      const material = new LineMaterial({
        color,
        linewidth: thickness, // Now works reliably
        resolution: new THREE.Vector2(window.innerWidth, window.innerHeight),
      });

      return new Line2(geometry, material);
    }
    // function createAxis(points: THREE.Vector3[], color: string) {
    //   const segments = 1000;
    //   const newPoints = [];

    //   for (let i = 0; i < segments; i++) {
    //     const t = i / segments; // 0 - 1
    //     const x = (1 - t) * points[0].x + t * points[1].x;
    //     const y = (1 - t) * points[0].y + t * points[1].y;
    //     const z = (1 - t) * points[0].z + t * points[1].z;
    //     newPoints.push(new THREE.Vector3(x, y, z));
    //   }

    //   for (let i = 0; i < segments; i++) {
    //     const t = i / segments;
    //     const x = (1 - t) * points[1].x + t * points[2].x;
    //     const y = (1 - t) * points[1].y + t * points[2].y;
    //     const z = (1 - t) * points[1].z + t * points[2].z;
    //     newPoints.push(new THREE.Vector3(x, y, z));
    //   }

    //   const geometry = new THREE.BufferGeometry().setFromPoints(newPoints);
    //   const material = new THREE.LineBasicMaterial({ color, linewidth: 15 });
    //   const line = new THREE.Line(geometry, material);
    //   line.frustumCulled = false;
    //   return line;
    // }
    // scene.add(
    //   createAxis(
    //     [
    //       new THREE.Vector3(-100, 0, 0),
    //       new THREE.Vector3(0, 0, 0),
    //       new THREE.Vector3(100, 0, 0),
    //     ],
    //     xColor
    //   )
    // ); //x axis

    // scene.add(
    //   createAxis(
    //     [
    //       new THREE.Vector3(0, -100, 0),
    //       new THREE.Vector3(0, 0, 0),
    //       new THREE.Vector3(0, 100, 0),
    //     ],
    //     xColor
    //   )
    // ); //y axis

    // scene.add(
    //   createAxis(
    //     [
    //       new THREE.Vector3(0, 0, -100),
    //       new THREE.Vector3(0, 0, 0),
    //       new THREE.Vector3(0, 0, 100),
    //     ],
    //     xColor
    //   )
    // ); //z axis
    const xColor = "#fff";
    const lineThickness = 3;
    objectGroup.add(
      createAxis(
        [
          new THREE.Vector3(-axisLength, 0, 0),
          new THREE.Vector3(0, 0, 0),
          new THREE.Vector3(axisLength, 0, 0),
        ],
        xColor,
        lineThickness
      ),
      createAxis(
        [
          new THREE.Vector3(0, -axisLength, 0),
          new THREE.Vector3(0, 0, 0),
          new THREE.Vector3(0, axisLength, 0),
        ],
        xColor,
        lineThickness
      ),
      createAxis(
        [
          new THREE.Vector3(0, 0, -axisLength),
          new THREE.Vector3(0, 0, 0),
          new THREE.Vector3(0, 0, axisLength),
        ],
        xColor,
        lineThickness
      )
    );

    //# Arrow
    const arrowLength = 1;
    const headLength = 3;
    const headWidth = 3;
    const arrowColor = "#fff";

    // Positive X
    const posXArrow = new THREE.ArrowHelper(
      new THREE.Vector3(1, 0, 0), // Direction
      new THREE.Vector3(axisLength, 0, 0), // Origin
      arrowLength,
      arrowColor,
      headLength,
      headWidth
    );
    objectGroup.add(posXArrow);

    // Negative X
    const negXArrow = new THREE.ArrowHelper(
      new THREE.Vector3(-1, 0, 0),
      new THREE.Vector3(-axisLength, 0, 0),
      arrowLength,
      arrowColor,
      headLength,
      headWidth
    );
    objectGroup.add(negXArrow);
    // Positive Y
    const posYArrow = new THREE.ArrowHelper(
      new THREE.Vector3(0, 1, 0), // Direction
      new THREE.Vector3(0, axisLength, 0), // Origin
      arrowLength,
      arrowColor,
      headLength,
      headWidth
    );
    objectGroup.add(posYArrow);

    // Negative Y
    const negYArrow = new THREE.ArrowHelper(
      new THREE.Vector3(0, -1, 0),
      new THREE.Vector3(0, -axisLength, 0),
      arrowLength,
      arrowColor,
      headLength,
      headWidth
    );
    objectGroup.add(negYArrow);
    // Positive Z
    const posZArrow = new THREE.ArrowHelper(
      new THREE.Vector3(0, 0, 1), // Direction
      new THREE.Vector3(0, 0, axisLength), // Origin
      arrowLength,
      arrowColor,
      headLength,
      headWidth
    );
    objectGroup.add(posZArrow);

    // Negative X
    const negZArrow = new THREE.ArrowHelper(
      new THREE.Vector3(0, 0, -1),
      new THREE.Vector3(0, 0, -axisLength),
      arrowLength,
      arrowColor,
      headLength,
      headWidth
    );
    objectGroup.add(negZArrow);

    //# Circle
    function createOrbitalCircle(
      radius: number,
      color: string,
      rotationAxis: THREE.Vector3,
      rotationAngle: number
    ) {
      const points = [];
      const segments = 128;

      // Base circle
      const baseGeometry = new THREE.CircleGeometry(radius, segments);
      const positions = baseGeometry.getAttribute("position").array;

      // Apply 3D rotation
      const quaternion = new THREE.Quaternion().setFromAxisAngle(
        rotationAxis,
        rotationAngle
      );

      for (let i = 0; i < positions.length; i += 3) {
        const vec = new THREE.Vector3(
          positions[i],
          positions[i + 1],
          positions[i + 2]
        );
        vec.applyQuaternion(quaternion);
        if (i !== 0) {
          points.push(vec);
        }
        // console.log(points);
      }

      const geometry = new MeshLineGeometry().setFromPoints(points);
      const material = new  THREE.LineBasicMaterial({
        color: new THREE.Color(color),
        lineWidth: 0.1,
        resolution: new THREE.Vector2(window.innerWidth, window.innerHeight),
        // transparent: true,
        opacity: 0.9,
      });

      return new THREE.LineLoop(geometry, material);
    }
    const outerCircles = 3;
    const radius = 70;
    // const innerCircles = 2;
    for (let i = 0; i < outerCircles; i++) {
      const inter = i / outerCircles;
      objectGroup.add(
        createOrbitalCircle(
          radius,
          "#ffcc00",
          new THREE.Vector3(1, 0, 0),
          Math.PI * inter
        )
      );
    }

    // const sphereGeo = new THREE.BufferGeometry();
    const starPositions = new Float32Array([0, 0, 0]);

    const starGeometry = new THREE.BufferGeometry();
    starGeometry.setAttribute(
      "position",
      new THREE.BufferAttribute(starPositions, 3) // 3 components per vertex
    );
    // const sphereGeometry = new THREE.SphereGeometry(15, 32, 16);
    // const material = new THREE.MeshBasicMaterial({ color: "#fff" });
    const sphereMaterial = new THREE.PointsMaterial({
      color: 0xffffff,
      size: 120,
      sizeAttenuation: true,
      transparent: true,
      opacity: 0.99,
      map: starTexture,
      alphaTest: 0.01,
    });
    const star = new THREE.Points(starGeometry, sphereMaterial);
    objectGroup.add(star);
    scene.add(objectGroup);

    //# Particles
    const particleGeometry = new THREE.BufferGeometry();
    const particleCount = 20000;
    const positions = new Float32Array(particleCount * 3);

    for (let i = 0; i < particleCount; i++) {
      positions[i * 3] = (Math.random() - 0.5) * 2000; // x
      positions[i * 3 + 1] = (Math.random() - 0.5) * 2000; // y
      positions[i * 3 + 2] = (Math.random() - 0.5) * 2000; // z
    }
    particleGeometry.setAttribute(
      "position",
      new THREE.BufferAttribute(positions, 3)
    );

    const particleMaterial = new THREE.PointsMaterial({
      color: 0xffffff,
      size: 8,
      sizeAttenuation: true,
      transparent: true,
      opacity: 0.99,
      map: starTexture,
      alphaTest: 0.01,
    });

    const particles = new THREE.Points(particleGeometry, particleMaterial);
    scene.add(particles);

    //# Animation
    const animate = () => {
      const positions = particleGeometry.attributes.position.array;
      const minXPos = 201;
      const maxXPos = 300;
      const minXNeg = -201;
      const maxXNeg = -300;
      for (let i = 0; i < positions.length; i += 3) {
        const x = positions[i];
        const z = positions[i + 2];

        if (x >= -201 && x <= 0 && z >= -201 && z <= 0) {
          positions[i] = Math.random() * (maxXPos - minXPos) + minXPos;
          positions[i + 2] = Math.random() * (maxXPos - minXPos) + minXPos;
        } else if (x >= 0 && x <= 201 && z >= 0 && z <= 201) {
          positions[i] = Math.random() * (maxXNeg - minXNeg) + minXNeg;
          positions[i + 2] = Math.random() * (maxXNeg - minXNeg) + minXNeg;
        } else if (x >= -201 && x <= 0 && z >= 0 && z <= 201) {
          positions[i] = Math.random() * (maxXPos - minXPos) + minXPos;
          positions[i + 2] = Math.random() * (maxXNeg - minXNeg) + minXNeg;
        } else if (x >= 0 && x <= 201 && z >= -201 && z <= 0) {
          positions[i] = Math.random() * (maxXNeg - minXNeg) + minXNeg;
          positions[i + 2] = Math.random() * (maxXPos - minXPos) + minXPos;
        }
      }
      particleGeometry.attributes.position.needsUpdate = true;
      particles.rotation.y += 0.003;
      objectGroup.rotation.y -= 0.002;
      renderer.render(scene, camera);
      requestAnimationFrame(animate);
    };
    animate();

    //# Window Resize
    const handleResize = () => {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
    };
    window.addEventListener("resize", handleResize);

    // const mountain = mountRef.current;
    //# Cleanup
    return () => {
      window.removeEventListener("resize", handleResize);
      if (mountain) mountain.removeChild(renderer.domElement);
    };
    // console.log(renderer.domElement);
  }, []);

  return <div ref={mountRef} />;
};

export default Axis;

what my current code shows

Invalid content security policy (CSP) header when receiving an Ajax request?

nonce works in the script tag but it doesn’t work when I have a request to another page.

index.php :

<?php
$nonce = base64_encode(random_bytes(16));
header("Content-Security-Policy: script-src 'nonce-$nonce'");
?>
<!DOCTYPE html>
<html>
    <head>
        <title>submit data</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>

        <input type="text" id="username" placeholder="username" autocomplete="off">
        <input type="password" id="password" placeholder="password" autocomplete="off">
        <button id="submitButton">submit data</button>
        <p id="demo"></p>

        <script nonce="<?php echo $nonce; ?>">
            document.getElementById("submitButton").addEventListener("click", function () {
                submitdata(document.getElementById('username').value, document.getElementById('password').value);
            });

            function submitdata(submitdata1, submitdata2) {
                const xhttp = new XMLHttpRequest();
                xhttp.onload = function () {
                    document.getElementById("demo").innerHTML = this.responseText;
                };
                xhttp.onerror = function () {
                    document.getElementById("demo").innerHTML = 'there is a problem!';
                };
                xhttp.open("POST", "./check.php");
                xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                xhttp.send("username=" + encodeURIComponent(submitdata1) + "&password=" + encodeURIComponent(submitdata2));
            }

            document.body.style.background = '#eee';
        </script>

    </body>
</html>

check.php :

<?php

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    if (isset($_POST['username']) && !empty($_POST['username']) && isset($_POST['password']) && !empty($_POST['password'])) {

        if (preg_match('/^[0-9a-z]+$/', $_POST['username'])) {

            echo '<button type="button" onclick="this.innerText = this.value;" value="' . $_POST['username'] . ' : ' . $_POST['password'] . '">' . $_POST['username'] . '</button>';
        } else {
            echo 'Username is invalid!';
        }
    } else {
        echo 'Please complete all fields!';
    }
} else {
    echo 'Your request is not allowed!';
}
?>

I don’t have the option to add a new script to the index file. If there is a script solution, please consider it in the check file ( my problem is exactly here ).

thank you in advance for your guidance and i will appreciate it.

I am a newbie. I have an array of numbers. I want to loop through it to find the maximum consecutive times numbers Less than 3 appear in a row. in JS [closed]

I am a new to Programming. I have an array of numbers. I want to loop through it to find the maximum consecutive times numbers Less than 3 appear in a row. in JS

const Numbers = [
  1.52,
  1.79,
  1.83,
  1.25,
  73.99,
  1.02,
  2.89,
  1.75,
  1.41,
  1.26,
  7.61,
  1.3,
  1.11,
  6.72,
  2.27,
  1.17,
  1.6,
  3.16
];

The answer should be 5

I tried for loop, but I get confused

Javascript find older date and newer date into an array of arrays

I am receiving this JSON structure :

 data[0].json_report.bank_orders[0].itens[23].payment_date

I need to find the first most older, and the last most newer payment_dates. Or just the last most newer payment_date.

There will be always one data element and one json_report but many bank_orders with many itens having payment_date ordered from older first to newer in the last position.

data[0].
  |_json_report.
  |__bank_orders[0].
  |__bank_orders[1].
  |__bank_orders[2].



data[0].
  |_report_json.
  |__bank_orders[0].
  |___itens[0].payment_date
  |___itens[1].payment_date
  |__bank_orders[1].
  |___itens[0].payment_date
  |____payment_date
  |___itens[1].payment_date
  |___itens[2].payment_date
  |__bank_orders[2].
  |___itens[0].payment_date
  |___itens[1].payment_date
  |___itens[2].payment_date
  |___itens[3].payment_date

I Try to iterate but could not enter into the second loop. how can i loop and find the most older date ?

const latestDate = {};
const actualLatestDate = {};


for (let n of response.data[0].report_json.bank_orders) {
        n.itens.forEach( di => {
            
            //latestDate = di.payment_date;
            //if(latestDate >actualLatestDate ){
                console.log("> "+di.payment_date);
            //}
            //actualLatestDate = di.payment_date
        });
    }

Which event should be triggered to accept input?

Background

I am still learning a bit about creating DOM JavaScript methods so I apologize if this is something that is considered straight forward or I am missing something very simple. I have a few automations I am trying to set up to automatically log into online accounts. I am testing my JavaScript within the Chrome browser.

Problem

In this example I am trying to log into Fidelity so using the URL https://digital.fidelity.com/prgw/digital/login/full-page I am presented with a username and password form to fill out. My goal is to programmically fill this out and log in. After inspecting the page I have gathered the username ID name and have the following code:

var username_field = window.document.getElementById("dom-username-input");
username_field.value = "myusername";
username_field.dispatchEvent(new Event("input"));

The issue is that when I click the submit button, it tells me that the username field needs to be filled out and is blank, so for some reason it is not registering what was put in through my JavaScript. On other automations, I have to dispatch the correct event. I have tried using input, change, keydown, and a few others but have not been able to succeed. I believe I do not know the correct event to dispatch or possibly I am missing something else?

HTML used to create the element from Fidelity’s site

<input class="pvd-input__input" required="" aria-describedby="dom-username-error-alert" aria-required="true" id="dom-username-input" type="text" maxlength="50" autocomplete="off" data-gtm-form-interact-field-id="0" aria-invalid="true">

As you can see it is just an input element which is why I don’t know why triggering an input event doesn’t work

How do I apply fabricjs filters to an image loaded to a canvas using ctx.drawimage?

I am using fabricjs version 5.2.1 to layer images on top of each other. At first, the load order was not always correct, because the canvas would load the images before the previous image was completed loading. I found this excellent post on stackoverflow that worked flawlessly to load the images. Fabric.js add images order The only slight change I made to that example was var SelfLoadingImage = fabric.util.createClass(fabric.Image, { instead of var SelfLoadingImage = fabric.util.createClass(fabric.Object, {. I assumed I would need the self-loading image to be of type Image in order to manipulate the image.

However, the object that is created by this method does not appear to be the same as the object that gets created by fabric.Image.fromURL.

When I attempt to applyFilters on any of these images, it returns the error: Uncaught TypeError: Cannot read properties of undefined (reading 'naturalWidth') at klass.applyFilters (fabric.js:23335:36)

Is there a way to force the object that gets created by the ctx.drawImage to be the same as a normal fabric.Image object?

How to fix camera vibrations and unreadable pixels in IFC.js viewer with Three.js and React

I’m developing a React application using IFC.js and Three.js to visualize complex BIM models. However, I’m facing two major issues:

  • Camera vibrations during transitions/selections

    When clicking on an element or transitioning through the model, the camera experiences unpleasant vibrations.

  • A Unreadable pixels on some elements

    Some elements appear with pixelation artifacts, making text and fine details difficult to read.

Here is the useEffect hook that initializes the IFC.js viewer:

useEffect(() => {
  const initViewer = async () => {
    if (!containerRef.current || initializedRef.current) return;
    
    try {
      initializedRef.current = true;

      // Initialize IFC.js Viewer
      const viewer = new IfcViewerAPI({
        container: containerRef.current,
        backgroundColor: new THREE.Color(0xeeeeee),
      });

      // Ensure renderer is ready
      await new Promise<void>((resolve) => {
        const checkReady = () => {
          if (viewer.context?.getRenderer()) {
            const renderer = viewer.context.getRenderer();
            renderer.setPixelRatio(window.devicePixelRatio);
            renderer.logarithmicDepthBuffer = true;
            renderer.sortObjects = true;
            resolve();
          } else {
            setTimeout(checkReady, 50);
          }
        };
        checkReady();
      });

      // Set IFC.js configurations
      await viewer.IFC.setWasmPath("wasm/");
      viewer.clipper.active = true;
      viewerRef.current = viewer;
      
      // Handle element selection (causing vibrations)
      containerRef.current.ondblclick = async () => {
         const result = await viewer.IFC.selector.pickIfcItem(false);
         if (!result) {
           viewer.IFC.selector.unpickIfcItems();
         }
      };

      // Handle resizing
      const resizeObserver = new ResizeObserver(() => {
        if (containerRef.current && viewer.context?.getRenderer()) {
          viewer.context.getRenderer().setSize(
            containerRef.current.clientWidth,
            containerRef.current.clientHeight
          );
          viewer.context.ifcCamera?.cameraControls?.update();
        }
      });
      resizeObserver.observe(containerRef.current);

      // Loading IFC models...
    } catch (error) {
      console.error("Initialization error:", error);
    }
  };

  initViewer();
}, [searchParams]);

What I’ve already tried

  • Adjusting pixelRatio (renderer.setPixelRatio(window.devicePixelRatio))
  • Enabling logarithmicDepthBuffer and sortObjects
  • Dynamically resizing the renderer

Questions

  • How can I eliminate vibrations during transitions and element selections?

  • How can I improve the display quality to make unreadable elements sharper?

  • Are there specific Three.js or IFC.js parameters that could solve these issues?

Technical environment

  • React 18

  • Three.js (latest version)

  • IFC.js

  • Tested browsers: Chrome & Firefox (latest versions)

Start and repeat video by timing

I have a video in a video tag with a videoplayer class. I need it to start 3 seconds after the html page loads and repeat every 12 seconds. My script triggers it but it doesn’t repeat. Where is my mistake?

HTML

<video playsinline preload="none" class="videoplayer" muted=""> 
 <source src="" type="video/mp4" /> 
</video>

JS

function rrv() {
    document.querySelector(".videoplayer").play();
}
    setTimeout(rrv, 4e3), self.setInterval(rrv, 12e4);

How to get the old state in a input by doing Undo (Ctrl + Z) when the value is formatted using a directive?

I’m creating a thousand separator directive where 1234 will be shown as 1,234 visually but behind the scene it will be 1234 only. So after everything is working expected. Problem is happening when I’m pressing Ctrl + Z. I’m giving 1 case below –

When form loads input field is BLANK. Then I type 123 then do Ctrl + Z works fine it resets back to BLANK. Now if I type 1234 my directive transforms it to 1,234 but now if I do Undo it doesn’t do anything. Which in this case also I want to reset it to BLANK or whatever the state was previously like normally happens.

When I debugged the code I found that Ctrl + Z does try to make it BLANK but during that time the directive opposes it by again reperforming same operation which creates an image that it doesn’t do anything. You can view my Stackblitz solution which I tried.

Directive code:

import { Directive, ElementRef, HostListener, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Directive({
  selector: '[thousandSeperator]',
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => ThousandSeperatorDirective),
      multi: true,
    },
  ],
  standalone: true,
})
export class ThousandSeperatorDirective implements ControlValueAccessor {
  private onChange: (_: any) => void = () => {};
  private onTouched: () => void = () => {};
  constructor(private el: ElementRef) {}

  @HostListener('input', ['$event'])
  @HostListener('paste', ['$event'])
  @HostListener('blur', ['$event'])
  onInput(event: Event | ClipboardEvent) {
    const rawValue = (event.target as HTMLInputElement).value;
    const unformattedValue = rawValue.replace(/,/g, '');

    this.onChange(unformattedValue);

    if (rawValue) {
      const formattedValue = this.formatValue(unformattedValue);
      setTimeout(() => (this.el.nativeElement.value = formattedValue), 0);
    }
  }

  writeValue(value: any): void {
    if (value || value == 0) {
      this.el.nativeElement.value = this.formatValue(value);
    } else {
      this.el.nativeElement.value = '';
    }
  }

  registerOnChange(fn: any): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: any): void {
    this.onTouched = fn;
  }

  private formatValue(value: string): string {
    const [integer, decimal] = value.toString().split('.'),
      HAS_DECIMAL_POINT = value.toString().includes('.');
    return (
      integer.replace(/,/g, '').replace(/B(?=(d{3})+(?!d))/g, ',') +
      (decimal ? `.${decimal}` : !decimal && HAS_DECIMAL_POINT ? '.' : '')
    );
  }
}

HTML –

<input [formControl]="abc" thousandSeperator />

Any idea if its possible, and why, Remix.run makes numerous API calls on the route loader?

I had an issue using Google Maps Places API inside the loader function of my _index.tsx route on my app. The code for the loader function is below.

For relevance, I would point out that I tried to protect the API call by storing the result of the API call, on the Session Cookie, which has a Max-Age of 3600 seconds (1 hour), thus the protection should retrieve the data from the Session Cookie rather than doing another API call. When I tested it seemed to work correctly, but somehow, on Production, it ended up producing thousands of API requests.

From the GPC usage statistics charts, there was a huge amount of calls, in sorts of above 300 per day, even on days where the website had no visits (according to the session charts on Google Analytics), which I find really puzzling.

Has anyone already had such an experience, and can anyone provide some insights on what might be behind this ?

For the moment I removed the calls to GCP APIs but if I’m not able to understand this, I think I won’t be able to use Remix.run in production on my projects.

Below the code, you can also see the Google Analytics chart and the GCP Api Calls chart.

export async function loader({
  request,
}: LoaderFunctionArgs): Promise<LoaderData> {
  const session = await getSession(request.headers.get('Cookie'));

  let gdpr = null;
  let place = null;
  let message = null;
  let error = null;

  if(session.has("gdpr")){
    gdpr = session.get("gdpr");
  }

  if(session.has("place")){
    place = JSON.parse(session.get("place") as string);
  }else{
    const options = {
      method:'GET',
      headers:{
        'Accept': 'application/json',
        'X-Goog-Api-Key':`${process.env.GOOGLE_PLACES_API_KEY}`,
        'X-Goog-FieldMask':'rating,userRatingCount'
      }
    };

    const res = await fetch('https://places.googleapis.com/v1/places/XXX',options);
    place = await res.json();
    session.set("place", JSON.stringify(place));
  }

  if (session.has("message")) {
    message = session.get("message");
  }
  if (session.has("error")) {
    error = session.get("error");
  }
  return json({ message, error, place, gdpr},
    {
      headers: {
        'Set-Cookie': await commitSession(session),
      },
    }
  );
}

Google Analytics sessions / users chart

Google Analytics sessions / users chart

Google Cloud Platform API calls chart

Google Cloud Platform API calls chart