How to optimize canvas rendering performance for edge detection in images?

I am working on a project that renders edge points of an image on an HTML canvas using JavaScript. Despite several optimizations, the performance is not ideal, especially when dealing with larger images or dynamic updates.

My approach involves scaling down the image, applying a grayscale filter, and using a brightness threshold to detect edge points. These points are then dynamically rendered on the canvas. Here are the basics:


const scale = 0.25;

const brightnessThreshold = 130; 



const canvas = document.getElementById("canvas");

const ctx = canvas.getContext("2d");

canvas.width = window.innerWidth;

canvas.height = window.innerHeight;



const img = new Image();

img.crossOrigin = "anonymous";

img.src = 'https://example.com/image.jpg';

img.onload = () => {

    const smallCanvas = document.createElement('canvas');

    const smallCtx = smallCanvas.getContext('2d');

    smallCanvas.width = img.width * scale;

    smallCanvas.height = img.height * scale;



    smallCtx.filter = 'grayscale(1)';

    smallCtx.drawImage(img, 0, 0, smallCanvas.width, smallCanvas.height);



    const imgData = smallCtx.getImageData(0, 0, smallCanvas.width, smallCanvas.height).data;

    const points = [];



    for (let i = 0; i < smallCanvas.width * smallCanvas.height; i++) {

        const brightness = imgData[i * 4]; // Single channel (grayscale)

        if (brightness < brightnessThreshold) {

            const x = (i % smallCanvas.width) / smallCanvas.width * canvas.width;

            const y = Math.floor(i / smallCanvas.width) / smallCanvas.height * canvas.height;

            points.push({ x, y });

        }

    }



    renderPoints(points);

};



function renderPoints(points) {

    points.forEach(point => {

        ctx.fillStyle = "black";

        ctx.fillRect(point.x, point.y, 1, 1);

    });

}

The edge detection and rendering process becomes slower with larger images or high-density edge points, despite optimizations like scaling and grayscale filters.
Also the project includes additional animations (e.g., a typewriter effect for text overlay), which further strain the rendering pipeline.

What techniques or optimizations can improve canvas rendering performance for edge detection?

Are there algorithmic adjustments or GPU-accelerated approaches (e.g., WebGL) that could be integrated into this workflow for better performance?

I’m looking for technical insights or best practices, rather than recommendations for libraries or external tools.

I hope this fits the guidelines.

Regards,
Konan

React based SPA WP-Theme react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__ is undefined

I’m trying to create a custom react-based WP-Theme for a SPA.

Versions:
Wordpress: 6.7.1.
React: 18.0.0
Npm: 10.8.2
Node: 18.20.5

The functions.php file of my WordPress installations contains the “render-react”-Div, to which I want to render my react components.

<?php
function my_react_theme_scripts() {
    wp_enqueue_script('my-react-theme-app', get_template_directory_uri() . '/build/index.js', array('wp-element'), '1.0.0', true);
}

add_action('wp_enqueue_scripts', 'my_react_theme_scripts');
?>

<div id="render-react"></div>

I can get the div via the query-selector and I can create the root. However, when I try to render anything to it I get an error.

import "./styles/main.scss"
import React from "react"
import ReactDOM from "react-dom/client"


// Render the React Component
console.log("test1");
var rootElement = document.querySelector("#render-react");
console.log(rootElement);
const root = ReactDOM.createRoot(rootElement);
root.render(<h1>Hello, world</h1>); // <- The error occurs here.

Error Message: "react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__ is undefined"

I’m not sure, if this problem is reproduceable, but I’ve tried reading docs again and a again, I’ve tried installing different react versions, looking around in forums and playing around with my code but nothing helps. Any ideas?

How do I build an image zoom navigator feature that allows me to see where in the image iam currently zoomed into

Soooup Stackers!

Appreciating the dedicated help in advance! Thank you so much!

Background

A frontend web application iam building in plain React + vite has a component which returns an <svg>, where within it, is a complex (contains lots of <path> ect..) artwork with all the works.

I have allowed the user to move the image around within the bounds of the <svg> using functions that update the transform attribute along with scroll zooming into the image that manipulate the transform(scale(1)).

What i want is a small <div> containing a minature version of my <svg> that shows the user where they have zoomed into.

Example

A screenshot from Adobe Lightroom showing the “image navigator” where a small whitebox highlights where the user has zoomed into in an image

How would i need to approach this feature implementation?

……

for (let i = 0; i < 10000; i++) {

   console.log("Thank you so much")

}

No feature implemented or currently tested.

Sequence of promise.race() in the event loop

This code, below, executes as a result:

script start
promise1
promise2
script end
promise3
race: A

Chrome version 131.0.6778.26, and node environment 22.4 both give the same result

Why is it that “‘race’: A” is executed after the execution of promise3, my understanding is that Promise.race is also a microtask which is first put into the microtask stack, so it should be executed first, but the result is not like this, this problem has been bothering me for a long time.
I hope to be able to give some official explanation, if you can answer my confusion I will be very grateful!

console.log('script start')

const promise1 = new Promise((resolve, reject) => {
    console.log('promise1')
    resolve("A")
})
const promise2 = new Promise((resolve, reject) => {
    console.log('promise2')
    resolve("B")
})

const p = Promise.race([promise1, promise2])
.then((value) => {
    console.log('race:', value)
}).catch((error) => {
    console.log(error)  
})

Promise.resolve().then(()=> {
    console.log('promise3')
})

console.log('script end')

I’m hoping for some official explanations, going down to the source code level would be best!

Webpack + Static jQuery Load

I’ve been trying and looking at soooo many solutions for how to use Webpack with jQuery and none have really documented how to deal with jQuery if it is already loaded as a static file. And there doesn’t seem to be any updated examples for Webpack 5 and all of its latest plugins. Can someone please help me understand the following:

  1. If my site loads a jQuery version statically on the page and Webpack
    delivers a framework to the site, how do I use that load of jQuery
    within Webpack so that I don’t duplicate it (with likely another
    version) by installing it with Node? Is there a way? (Note: I’ve
    looked at resolve, loader-imports, providePlugin, etc.)

  2. How can I re-use the global $ or jQuery loaded through the static
    file in BOTH Webpack and custom JS added to various pages outside
    Webpack…without duplicating the load of jQuery or stumbling into
    the mess of having two $ instances?

Getting n values along an variable exponential curve that add up to a total

I will first and foremost admit that this area of math is not my strong suit and college was too long ago, so my question lacks actual code because I don’t know where to start.

Given a total sum, n number of points along the curve, and an exponent value, I need to get a series of evenly spaced points curve which add up to the total sum.

let total = 10.00;
let exp = 2.3;
let points = 10;

enter image description here

In the rough example chart above, there are 10 evenly spaced points (along an adjustable exponential curve) which add up to 10.

Prevent extreme slowdown on PEG.js

The bulk of PEG.js (or Peggy) examples don’t support much beyond a basic math formula. I’ve written up this arithmetic logic to provide full math parsing support with a foundation for adding custom functions.

Of course in production the console.log() statements would not be in there, but it is used to investigate how many time the evaluations functions are executed.

It seems with each layer in the order of operations there is a doubling of the amount of code executions.

My questions is– how can this performance problem be avoided?
I’m new to PEG and there might be an advanced feature that would prevent it from taking such a complex attack at it.

The below code can be put into https://peggyjs.org/online.html
Then here’s some example functions to notice:

5*(3+3)
This 7 character function creates over 500 console.log statements
Probably a good first clue this parsing is not optimal. How a 500 step process could be used to parse 7 characters I don’t understand.

It’s rough enough that PEG.js found 500 things to do, but the real issue is that it executes the callback part (the {} part that has the console.log) every time. Every time. Note it is the same language element, and it’s getting passed a “9” and last time it returned 9. Is there a trick so PEG.js can just remember that? This current code is trivial, but more complex functions run significant code and the developer isn’t expect to be executed 64 times when the grammar exists in the formula only once.

1.1 / ( 2 * ( (9 * 9) + (9 * 9) + (9 * 9) ) ) or
1.1 / (( 2 * ( 9 * 9 + 9 * 9 + 9 * 9 ) ) )
Either of these work ok (might as well leave the browser console closed, the number of logs is wild) but note that they do parse quickly.

1.1 / (( 2 * ( (9 * 9) + (9 * 9) + (9 * 9) ) ) )
This is where the cliff shows up. Just one more layer of complexity than the above two but this one will fully lock up the browser for a fair amount of time.

{
  const operations = {
        "√": (power, value) => Math.pow(value, 1 / power),
        "^": (base, exponent) => base ** exponent,
        "*": (multiplicand, multiplier) => multiplicand * multiplier,
        "/": (dividend, divisor) => dividend / divisor,
        "+": (addend1, addend2) => addend1 + addend2,
        "-": (minuend, subtrahend) => minuend||0 - subtrahend,
        "<": (a, b) => a < b,
        ">": (a, b) => a > b,
        "<=": (a, b) => a <= b,
        ">=": (a, b) => a >= b,
        "=": (a, b) => a == b,
        "!=": (a, b) => a != b
    };
}

// Define our end result should be something ReadyToReturn
Start = _ value:ReadyToReturn _ { return value; }

// * means zero or more so even empty strings count as whitespace
_ "whitespace" = [ tnr]*

NumericValue
  = scientific:(_ "-"? [0-9]+ ("." [0-9]+)? [eE] [+-]? [0-9]+) { console.log('scientific'); return text(); }
  / double:(_ $("-"? [0-9]+ "." [0-9]* / "-"? "." [0-9]+)) { console.log('double'); return Number(text()); }
  / integer:(_ "-"? [0-9]+) { console.log('integer'); return parseInt(text(), 10); }

QuoteText = """ chars:([^\"] / "\" .)*  """ { return chars.join(""); }

PlainText = [a-zA-Z0-9 ]+ { return text().trim(); }

SimpleValue = NumericValue / QuoteText / PlainText

// After functions and columns are handled, we are left with simple numbers and ready to do math
ReadyToCalculate
  = negate:[-]? result:Function {
      if (!negate) {
        return result;
      }
      return isNumber(result) ? 0 - result : "-" + result;
  }
  / SimpleValue

// Functions need to be processed in the order they appear in the formula so finding arguments works correctly
Function = firstFunction:(
  Parentheses
  / RoundDown
  / RoundUp
) {
  return firstFunction;
}

Parentheses = "(" _ expr:ReadyToReturn _ ")" {
  console.log('( )');
  return expr;
}

RoundDown = "ROUNDDOWN(" _ value:ReadyToReturn places:(_ "," _ ReadyToReturn)? _ ")" {
  console.log('ROUNDDOWN');
  const digitNum = (places && places[2]) || 0;
  const base = 10 ** digitNum
  if (value < 0) {
    return Math.ceil(value * base) / base;
  }
  return Math.floor(value * base) / base;
}

RoundUp = "ROUNDUP(" _ value:ReadyToReturn _ places:("," _ ReadyToReturn _)? ")" {
  console.log('ROUNDUP');
  const digitNum = (places && places[2]) || 0;
  const base = 10 ** digitNum
  if (value < 0) {
    return Math.floor(value * base) / base;
  }
  return Math.ceil(value * base) / base;
}

////////////////////////////////////////////////////////
// This is the order of operations part.
// Each ReadyTo* definition expects the previous ReadyTo* which means that higher level has completed.
////////////////////////////////////////////////////////

// When handling roots, the two definitions are processed in order.
//  If it can consume a number to the left, it will
//  Then it will process √ characters without needing a number to the left
//  Finally, if no root work needs to be done, a ReadyToCalculate can simploy pass through
ReadyToExponent
  = head:ReadyToCalculate _ tail:(_ "√" _ ReadyToCalculate)+ {
      console.log('_√_');
      return tail.reduce((result, element) => operations[element[1]](result, element[3]), head);
    }
  / negate:[-]? tail:(_ "√" _ ReadyToCalculate)+ {
      console.log('√_');
      if (negate) {
        return 0 - tail.reduce((result, element) => operations[element[1]](result, element[3]), 2);
      }
      return tail.reduce((result, element) => operations[element[1]](result, element[3]), 2);
    }
  / ReadyToCalculate

ReadyToMultiply
  = head:ReadyToExponent tail:(_ "^" _ ReadyToExponent)+ {
      console.log('Exponent');
      return tail.reduce((result, element) => operations[element[1]](result, element[3]), head);
    }
  / ReadyToExponent

ReadyToAdd
  = head:ReadyToMultiply tail:(_ ("*" / "/") _ ReadyToMultiply)+ {
      console.log('Multiply');
      return tail.reduce((result, element) => operations[element[1]](result, element[3]), head);
    }
  / ReadyToMultiply

ReadyToCompare
  = head:ReadyToAdd tail:(_ ("+" / "-") _ ReadyToAdd)+ {
      console.log('Add');
      return tail.reduce((result, element) => operations[element[1]](result, element[3]), head);
    }
  / ReadyToAdd

ReadyToReturn
  = head:ReadyToCompare tail:(_ ("<=" / "<" / ">=" / ">" / "!=" / "=") _ ReadyToCompare)+ {
      console.log('Compare');
      return tail.reduce((result, element) => operations[element[1]](result, element[3]), head);
    }
  / ReadyToCompare

Feedback and Support Inquiry for Jssor Slider

I hope this message finds you well. I have been exploring Jssor Slider for use in my web projects, and I appreciate the features and functionality it offers. However, I have encountered some challenges, and I wanted to reach out to understand more about its current status and support.

Specifically:

I noticed the last update to the slider was some time ago. Is the project still being actively maintained?
Are there any plans for updates to address compatibility with modern frameworks and browsers?
Could you provide guidance or resources for troubleshooting and customization?
I genuinely like the design philosophy behind Jssor Slider and would be happy to continue using it if active development or support is available.

Looking forward to hearing from you. Thank you for your time and assistance.

ExpressJS readdir not allowing for update of variables [duplicate]

I have been trying to use a for loop and readdir to automatically list all files from a specific directory, but whenever I try to, the variables CollectionsHtml and mdFiles are seemingly out of scope as it works properly while in the for loop and readdir function however outside it is as if the variables were not updated. I have tried a += and I’m using concat just to try and see if it works but nothing changed. I would like to know if there are any workarounds to this issue or if I am missing something?

markdownDir is defined at the beginning of the file.

the console.log in the files.forEach loop is printing to console.

mdFiles is a blank list at the bottom of the function.

// send collections.html
app.get('/collections', (req, res) => {
    //read files path from collections/docs
    let CollectionsHtml = `
    <!DOCTYPE html>
    <head>
    <link href="style.css" rel="stylesheet" type="text/css">
    </head>
    <body>
        <div id="container">
            <div id="header">
                <h1>Collections</h1>
            </div>
            <div id="sidebar">
                <a href="/">Home</a>
            </div>
            <div id="collections">`;
    let mdFiles = [];
    fs.readdir(markdownDir, (err, files) => {
        files.forEach(file => {
            const informalName = file.split(".")[0];
            mdFiles.push(informalName);
            console.log(`loaded ${file} in /collections`);
            //console.log(mdFiles.join(""));
        });
    });
    for (let i = 0; i < mdFiles.length; i++) {
        CollectionsHtml.concat(`<div id="article">
                    <a href="/collections/${informalName}">${informalName}</a>
                </div>`);
    };
    CollectionsHtml.concat(`</div >
        </div >
    </body >
        <script type="text/javascript src=""></script>
    `);
    console.log(mdFiles.join(""));
    console.log(CollectionsHtml);
    res.send(CollectionsHtml);
});


Unit test failing because fest.fn() not trigger openConfirmationModal function

it('text field', async () => {
 const props = {
   openConfirmationModal: jest.fn()
  }

  const { queryByTestId, findByTestId } = render(
    <FormInputs
      openConfirmationModal={props.openConfirmationModal}
    />
  );

  const input = queryByTestId('input-component-amount') as HTMLInputElement;
  expect(input).toBeInTheDocument();

  fireEvent.change(input, { target: { value: 123 } });

  const textArea = queryByTestId('textarea-component-textfield') as HTMLTextAreaElement;
  expect(textArea).toBeInTheDocument();
  fireEvent.change(textArea, { target: { value: 'This is some text!' } });

  const submitButton = queryByTestId('button') as HTMLButtonElement;
  expect(submitButton).toBeInTheDocument();
  expect(submitButton).toBeEnabled();

  fireEvent.click(submitButton);

  expect(props.openConfirmationModal).toHaveBeenCalledTimes(1);

  const submitModalButton = queryByTestId('confirmation-modal-submit-button') as HTMLButtonElement;
  expect(submitModalButton).toBeInTheDocument();
});
import React, { useState } from 'react';

interface FormInputsProps {
  openConfirmationModal: () => void;
}

const FormInputs: React.FC<FormInputsProps> = ({ openConfirmationModal }) => {
  const [amount, setAmount] = useState<string>('');
  const [reason, setReason] = useState<string>('');
  const [isModalOpen, setIsModalOpen] = useState<boolean>(false);

  const handleSubmit = () => {
    if (amount && reason) {
      openConfirmationModal();
      setIsModalOpen(true);
    }
  };

  const handleModalSubmit = () => {
    Calling API....
    setIsModalOpen(false); // Close modal on confirmation
  };

  return (
    <div>
      <input
        data-testid="input-component-amount"
        type="number"
        value={amount}
        onChange={(e) => setAmount(e.target.value)}
      />
      <textarea
        data-testid="textarea-component-textfield"
        value={reason}
        onChange={(e) => setReason(e.target.value)}
      />
      <button
        data-testid="button"
        onClick={handleSubmit}
        disabled={!amount || !reason}
      >
        Submit
      </button>
      {isModalOpen && (
        <div data-testid="confirmation-modal">
          <p>Are you sure you want to submit?</p>
          <button
            data-testid="confirmation-modal-submit-button"
            onClick={handleModalSubmit}
          >
            Confirm
          </button>
        </div>
      )}
    </div>
  );
};

export default FormInputs;

After expect(props.openConfirmationModal).toHaveBeenCalledTimes(1) unable to see the modal and getting error “unable to find element” for const submitModalButton = queryByTestId('confirmation-modal-submit-button') as HTMLButtonElement.

VScode debugger causing random files to be downloaded in the browser when running it

Hey Everyone I need help identifying a bug or just a problem with my VScode, so the problem is that when I run my app.js it opens up the localhost:3000 browser and downloads a random file with characters such as !$&@.

If anyone knows the solution please comment and I’ll go ahead and give it a go.

Also I am using a Macbook

The app.js

random download after running the debugger

I just did more testing and I realize the downloads are my index.html file which I am not sure why it is happening.

I’ve uninstalling an redownloading my vscode as well as reinstalling my json packages. I tested some code with my friend who didn’t experience it and it wasn’t a problem with my code but maybe with IDE itself.

and I expected to just launch the website with a heading and thats all

One specific CSS style in JS won’t apply [duplicate]

I have what seems like a simple issue, but it’s got me stumped.
I’m trying to set a table border with Javascript inside a loop, so I can select specific rows via another function to add a style to.

If I set the style of an individual cell, it works fine:

td0 = document.createElement("td");
td0.style = "border-top: 3px solid"; 

I’m also able to add a border around the whole table via a similar method:

document.getElementById("IDaudittable").style.border = "1px solid";

Finally, within the loop that iterates over the array of selected row IDs, I’m even able to style the rows successfully:

rows[rID].style = "border-top: 20px solid; background-color: red;"

…But only the background color part applies. For some reason, the border gets ignored. I tried removing other border styles to see if there was a conflict but as far as I can tell, there is not.
Also, I did notice the semicolon placement between the code sampled here is different; I have tested and that isn’t affecting it either.

How to update multiple CSS properties at once

In a stylesheet I have the following custom properties defined

:root {
    color-scheme: dark;
    --white: #FFF;
    --zinc-50: #fafafa;
    --zinc-100: #f4f4f5;
    --zinc-200: #e4e4e7;
    --zinc-300: #d4d4d8;
    --zinc-400: #a1a1aa;
    --zinc-500: #71717a;
    --zinc-600: #52525b;
    --zinc-700: #3f3f46;
    --zinc-800: #27272a;
    --zinc-900: #18181b;
    
    --bg-color: #171617;
    --text-color: #a4a3a4;
    --pane-text-color: #c8c6c8;
    --body-scroll-bg: #171617;
    --body-scroll-thumb-bg: #373737;
    --track-cover-fade-color: rgba(23,22,23,1);
 }

I also have the following declaration

html.light {
    color-scheme: light; 
    --bg-color: #f5f6f8;
    --text-color: #7e7e7e;
    --pane-text-color: var(--zinc-500);
    --body-scroll-bg: #f5f6f8;
    --body-scroll-thumb-bg: var(--zinc-400);
    --track-cover-fade-color: rgba(245,246,248,1);
}

In a javascript function I was able to change one of the properties but surely there is a more elegant solution rather than having to manually write in every property that has to be updated?

    setTheme(theme){
        if (theme == "dark") {
            root.style.setProperty('--table-sticky-heading-bg-color', "rgba(0,0,0,1)");      
        }
        else {       
            root.style.setProperty('--table-sticky-heading-bg-color', "rgba(255,255,255,1)");   
        }
    }

Creating a multidimensional array with numerical keys

I’m creating a multidimensional array to represent music. The entire MDA represents the whole piece of music. Within the array, there are to be multiple voices (for example, 0-3 representing soprano, alto, tenor, bass). Each voice has its own array for each note in that part. The notes need to be assigned a numerical key by their sixteenth beats, skipping beats in-between where no new note will sound.

What is the correct syntax to assign the keys to the notes?

In the example below, we have the sample song. It has two voices. The treble voice has 11 different notes spread out over two measures (one half-measure per line). Each note is itself an array containing a pitch. In the first note, with key 0, we have pitch e4 and a duration 2 (for two sixteenth notes, which is one eighth note).

So in the first half-measure I’ve got four note-arrays with four keys, all on even numbers skipping the odds. But this won’t run because (I think) I’m defining the keys incorrectly. Can someone tell me how to do it correctly?

sampleSong1 = [
    [
        0=[p.e4,2],  2=[p.d4,2],  4=[p.c4,2],  6=[p.d4,2], 
        8=[p.e4,4],              12=[p.e4,2], 14=[p.d4,2], 
        16=[p.e4,4],             20=[p.e4,2], 22=[p.a4,2], 
        24=[p.g4,8] 
    ],
    [
        0=[p.c3,16],
        16=[p.c3,8],
        24=[p.g2,8]
    ]
];

Add Vibrant.js library to firefox web extension

I have a web extension for firefox based on manifest_version: 2. My extension interacts with the elements of a certain third-party site, sometimes modifying them or supplementing the interface with my own elements. Recently, I needed to add the Vibrant.js library to determine the color palette of an image. Here are the ways I tried to use it:

  1. I tried to add it to the header in my content_scripts via a link to cdnjs.com and got the error “ReferenceError: Vibrant is not defined” when trying to create the main element. It looks something like this:
    let script = document.createElement('script');
    script.src = 'https://cdnjs.cloudflare.com/ajax/libs/vibrant.js/1.0.0/Vibrant.min.js';
    document.head.appendChild(script);
  1. Also, I tried to download the release file and added it as content_scripts and got the error “SecurityError: The operation is insecure.”, I was able to do this with jszip.min.js before and it worked fine.

My problem is not only specific to vibrant, but also to most other libraries that I can’t use after following the same steps.