Not displaying the webpage instead it display the script in the folder

I am working on Xampp localhost. Ihave my script installed but when i try to access the webpage for example http://localhost/myscripfolder inside htdocs, it display all the folders and files inside the project folder

Index of /mywebsite

I am expecting to be able to access the website through the url localhost/myscriptfolder.

but it doenot work.

Instead, It diplay all the folders and files inside the main project folder

Nginx on aapanel blocks CORS headers from PHP script

I am trying to make a cross-domain API request from https://andiamo.elenmorcreative.com to https://andiamo-backend.elenmorcreative.com.

I have configured Laravel and CORS correctly, but it always fails. To prove the problem is on the server, I created a simple public/test.php file that only contains the header(“Access-Control-Allow-Origin: https://andiamo.elenmorcreative.com”);.

However, when I called test.php from the frontend domain, I still got a CORS error, which means the header was not sent. This proves there is something in the Nginx/aapanel configuration that is blocking it.

Here is my current Nginx configuration. Please help to find which setting might be causing this.

server {
    listen 80;
    listen 443 ssl http2;
    server_name andiamo-backend.elenmorcreative.com;
    root /www/wwwroot/andiamo-backend.elenmorcreative.com/andiamo-backend/public;

    # Konfigurasi SSL (JANGAN DIUBAH)
    ssl_certificate /www/server/panel/vhost/cert/andiamo-backend.elenmorcreative.com/fullchain.pem;
    ssl_certificate_key /www/server/panel/vhost/cert/andiamo-backend.elenmorcreative.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;

    # Pengaturan Umum
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
    index index.php;
    charset utf-8;

    # Pengalihan ke HTTPS
    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    }
    
    # Aturan Rewrite Standar untuk Laravel
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # Penanganan Error Page
    error_page 404 /index.php;

    # Blok PHP yang Bersih dan Standar
    location ~ .php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+.php)(/.+)$;
        fastcgi_pass unix:/tmp/php-cgi-83.sock; # Sesuaikan dengan versi PHP Anda
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        internal;
    }
    
    # Blokir akses ke file sensitif
    location ~ /.(?!well-known).* {
        deny all;
    }

    # Logging
    access_log /www/wwwlogs/andiamo-backend.elenmorcreative.com.log;
    error_log /www/wwwlogs/andiamo-backend.elenmorcreative.com.error.log;
}

look for help on community forums that are more specific to aapanel and Nginx.

Laravel blade strange execution sequence [closed]

I came across a Laravel tutorial. It’s about authentication system and creating login interface.
There is some strange code that I don’t understand.

There is a login form submitting a post request to server to authenticate. Based on input data, it may fail with errors (Like invalid email or …). There is a field under the form to show those errors:

@if ($errors->any())
  <ul>
    @foreach ($errors->all() as $error)
      <li>{{ $error }}</li>
    @endforeach
  </ul>
@endif

PHP directives execute on server side (?), so how it shows errors after submitting the form? Page is already loaded. So how it works?

PHP web scraping – Why would cURL suddenly stop working? [closed]

I’ve been scraping a webpage with cURL for many years using this program, but it suddenly no longer works. Any suggestions on how to continue scaping this page?

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://www.example.com");

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);  

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

$data = curl_exec($ch);

curl_close($ch);

What is the tech stack, and how does JavaScript fit into it? [closed]

The specific technologies and tools used in the project or organization (tech stack)
How JavaScript is utilized within that tech stack (frontend, backend, or full-stack)The role JavaScript plays in the overall architecture and development of the project

In essence, the question aims to gain insight into the technical landscape and JavaScript’s position within it.

My while loop is not running smoothly, where did i go wrong?

//  NUMBER GUESSING GAME

// Html dom elements to work with

const rollBtn = document.getElementById("rollBtn");
let guess = document.getElementById("guess");
let display = document.getElementById("display");

// Other variables needed
let running = true;
let attempts = 0;
const minNum = 1;
const maxNum = 100;
const answer = Math.floor(Math.random() * (maxNum - minNum + 1)); 

rollBtn.onclick = function(){
    
    while(running){
        guess = Number(guess.value);
        if(isNaN(guess)){
            display.textContent = `Please, input a valid number between ${minNum} - ${maxNum}`;
        }
        else if(guess < minNum || guess > maxNum){
            display.textContent = `Please, input a number between ${minNum} - ${maxNum}`;
        }else{
            attempts++;

            if(guess < answer){
                display.textContent = "Too Low, Try again";
            }
            else if(guess > answer){
                display.textContent = "Too High, Try again";
            }
            else{
                display.textContent =`Correct! the answer is ${answer}, It took you ${attempts} attempt(s)`;

                running = false;
            }
            
        }
    }  
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Number Guessing Game</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <label for="guess">Enter a number:</label>
    <input type="text" id="guess">
    <button id="rollBtn">Roll</button>
    <h3 id="display"></h3>
    <script src="index.js"></script>
</body>
</html>

This is what the console shows me but can’t seem to resolve the issue:

Script terminated by timeout at:
rollBtn.onclick@http://127.0.0.1:5500/index.js:18:11
EventHandlerNonNull*@http://127.0.0.1:5500/index.js:16:1

How can I record a user’s screen on a mobile device in the browser?

I’m building a web application that needs to capture and save a user’s screen recording on their phone. On desktop browsers I can use:

if (navigator.mediaDevices && navigator.mediaDevices.getDisplayMedia) {
  const screenStream = await navigator.mediaDevices.getDisplayMedia({ video: true });
  const recorder = new MediaRecorder(screenStream);
  const chunks = [];

  recorder.ondataavailable = e => chunks.push(e.data);
  recorder.onstop = () => {
    const blob = new Blob(chunks, { type: 'video/webm' });
    // …upload or save “blob”…
  };

  recorder.start();
  // Stop after X seconds, or when user clicks “Stop”
}

But on mobile Safari (iOS 15+) and Chrome on Android, navigator.mediaDevices.getDisplayMedia is either undefined or prompts an error. I haven’t found any reliable documentation on capturing the entire screen (not just the camera) on mobile browsers.

•   **What APIs or polyfills** exist to enable screen capture on mobile browsers?
•   Are there any **workarounds** (e.g. WebRTC-based, Cordova/Capacitor plugins, user-driven screen-share intents) that allow me to record the screen without requiring a native app?
•   How do popular web apps (e.g. Loom, Zoom) achieve in-browser screen recording on smartphones?

Any guidance or examples would be greatly appreciated!

What I’ve tried:

1.  Using getDisplayMedia() on mobile — not supported.
2.  Fallback to getUserMedia({ video: { mediaSource: "screen" } }) — errors out.
3.  Investigated WebRTC screen-capture flags — no mobile support.

Counter not working when setInterval state in Reactjs

I am writing an automatic seconds counter and it should increment by 1 every second, but currently it is not working even though i have setInterval for it to repeat and setCount every 1000 ms (1 second). I just don’t got why it is.

My current code

import React, { useState, useEffect } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setCount(count + 1);
    }, 1000);

    return () => clearInterval(interval);
  }, []);

  return <div>Count: {count}</div>;
}

I expect someone to help me find out why.

The expected result is that the count will increase by 1 every second.

Use data from mapping fetch to feed a component

I have a React component fetching an API and returning a list of users and some data for each in cards (user.map). I would like to make those cards clickable and for each one to return a individual card with more informations about those users. So I’m trying to pass the data for one specific user to another component (idividualCard). How can I do that?
Here is my code on React:

import {useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { Card } from "react-bootstrap";
import { Rating } from "react-simple-star-rating";

export default function ArtisanAlimentation() {

  const [artisans, setArtisans] = useState([]);

  const getArtisan = async () => {
    const res = await fetch ("http://localhost:3000/artAlim");
    const json = await res.json();
    setArtisans (json);
  }

  
  useEffect (() => {
    getArtisan();
  },[])

return (

    <>
        <div className="mt-5 pt-5">
            <br></br>
            <h3 className="titreSections">Les artisans du secteur de l'alimentation</h3>
            <div className="container">
            {artisans.map(artisan => (
                <Link to='#'>
                <Card className="mb-3" style={{ width: '18rem' }}>
                <Card.Body>
                <p>Nom: {artisan.nom}</p>
                <p>Note: <Rating initialValue={artisan.note} allowFraction size={25}/></p>
                <p>Sapécialité: {artisan.specialite}</p>
                <p>Localisation: {artisan.ville}</p>
                </Card.Body>
                </Card>
                </Link>
            
            ))}
        </div>
        </div>
        

    </>

)
}

Chakra3 ui Select slot recipe – indicator color change on trigger state change (focused, hovered, expanded)

i am trying to compose my own chakra 3 ui slot recipe based on the reference slot recipe provided by chakra.

Currently i am trying to achieve the behavior whereby the indicator aka the down chervon icon color turns to “green” or any other color whenever the parent trigger is hovered across or expanded or focused ( i am using storybook to demo these states on render)

i am focusing on the primary variant, looks it the the indicator is not able to infer the parent trigger state. any idea about this? thank you.

heres the current implementation

  variants: {
    variant: {
      primary: {
        trigger: {
          _hover: {
            bg: '{colors.button.surface.secondary.hover}',
            borderColor: '{colors.button.border.secondary.hover}',
            color: '{colors.button.text.secondary.hover}',
      
          },
          _focus: {
            ring: '4px',
            ringColor: '{colors.gray.300}',
            bg: '{colors.button.surface.secondary.focused}',
            color: '{colors.button.text.secondary.focused}',
            borderColor: '{colors.button.border.secondary.focused}',
          },
          _disabled: {
            bg: '{colors.button.surface.secondary.disabled}',
            borderColor: '{colors.button.border.secondary.disabled}',
            color: '{colors.button.text.secondary.disabled}',
          },
          _expanded: {
            bg: '{colors.button.surface.secondary.hover}',
            color: '{colors.button.text.secondary.hover}',
            borderColor: '{colors.button.border.secondary.hover}',
          },
          '&:not([data-placeholder-shown])': {
            borderColor: '{colors.green.800}',
            color: '{colors.gray.800}',
            bg: '{colors.green.50}',
          },
          '&:is(:placeholder-shown, [data-placeholder-shown])': {
            color: '{colors.gray.600}',
          },
          bg: '{colors.button.surface.secondary.default}',
          borderWidth: '1px',
          borderWeight: '1',
          borderColor: '{colors.button.border.secondary.default}',
        },
        indicator: {
          color: '{colors.yellow.800}',
          '[data-hover] &': {
            color: '{colors.green.600}'
          },
        },
    },
      secondary: {
        trigger: {
          _hover: {
            bg: '{colors.button.surface.tertiary.hover}',
            borderColor: '{colors.button.border.tertiary.hover}',
            color: '{colors.button.text.tertiary.hover}',
          },
          _focus: {
            ring: '4px',
            ringColor: '{colors.gray.300}',
            dropShadow: '0 0 0 4px {colors.black}',
            bg: '{colors.button.surface.tertiary.focused}',
            borderColor: '{colors.button.border.tertiary.focused}',
            color: '{colors.button.text.tertiary.focused}',
          },
          _disabled: {
            bg: '{colors.button.surface.secondary.disabled}',
            borderColor: '{colors.button.border.tertiary.disabled}',
            color: '{colors.button.text.tertiary.disabled}',
          },
          _expanded: {
            bg: '{colors.button.surface.tertiary.hover}',
            borderColor: '{colors.button.border.tertiary.hover}',
            color: '{colors.button.text.tertiary.hover}',
          },
          '&:not([data-placeholder-shown])': {
            borderColor: '{colors.green.800}',
            color: '{colors.green.800}',
            bg: '{colors.green.50}',
          },
          '&:is(:placeholder-shown, [data-placeholder-shown])': {
            color: '{colors.gray.600}',
          },
          bg: '{colors.button.surface.tertiary.default}',
          borderWidth: '1px',
          borderWeight: '1',
          borderColor: '{colors.button.border.tertiary.default}',
        },
      },
    },
  },

I’m trying to make my first game in js but I have a problem with the animations that instead of starting the animation the chest just disappear [closed]

Labyrinth Game

*, *::before, *::after {

box-sizing: border-box;

}

/* GAME SCENES */

body {

background-color: #222;

display: flex;

justify-content: center;

align-items: center;

height: 100vh;

width: 100vw;

margin: 0;

font-family: sans-serif;

}

#HealthBar {

background-color: darkred;

height: 25px;

width: 150px;

font-size: 14px;

color: white;

position: absolute;

top: 20px;

left: 20px;

padding: 5px;

text-align: center;

border-radius: 5px;

}

canvas {

border: 40px solid;

border-image-source: url(“ASSETS/BorderWall.png”);

border-image-slice: 40;

border-image-repeat: repeat;

border-image-width: 40px;

background-color: #ddd;

}

/* GAME MENU */

#MenuButton {

position: absolute;

bottom: 50px;

left: 50px;

z-index: 10;

}

#PlayerMenu {

display: none;

grid-template-columns: 1fr 2fr;

grid-template-rows: 1fr 1fr;

position: absolute;

top: 50px;

right: 50px;

width: 300px;

background-color: #444;

color: white;

padding: 10px;

gap: 5px;

border: 2px solid white;

border-radius: 10px;

z-index: 10;

}

#PlayerDisplay {

grid-column: 1;

grid-row: 1;

background-color: #444;

padding: 10px;

border: 2px solid white;

border-radius: 10px;

}

#PlayerDisplay img {

width: 100%;

border: 2px solid;

border-radius: 10px;

}

#ArmourGrid {

grid-column: 1;

grid-row: 2;

display: grid;

grid-template-columns: repeat(2, 1fr);

padding: 5px;

gap: 5px;

border: 2px solid;

border-radius: 10px;

}

#ArmourGrid img {

width: 100%;

border: 2px solid white;

background-color: lightgrey;

border-radius: 10px;

}

#ItemGrid {

grid-column: 2;

grid-row: 1 / 3;

display: grid;

grid-template-columns: repeat(2, 1fr);

padding: 5px;

gap: 5px;

border: 2px solid;

border-radius: 10px;

}

#ItemGrid img {

width: 100%;

border: 2px solid white;

background-color: lightgrey;

border-radius: 10px;

}

/* GAME ELEMENTS */

/* CHEST POP UP */

#ChestOverlay {

position: fixed;

top: 0;

left: 0;

width: 100vw;

height: 100vh;

background: rgba(0, 0, 0, 0.8);

display: flex;

justify-content: center;

align-items: center;

z-index: 9999;

animation: fadeIn 0.5s ease-in-out;

}

#ChestContent {

width: 50vw;

height: 50vh;

background-color: #222;

color: white;

padding: 20px;

border: 4px solid gold;

border-radius: 15px;

text-align: center;

animation: popUp 0.4s ease-out;

}

#ChestContent img {

width: 100px;

margin-bottom: 10px;

}

@keyframes popUp {

0% {

transform: scale(0.2);

opacity: 0;

}

100% {

transform: scale(1);

opacity: 1;

}

}

@keyframes fadeIn {

from {opacity: 0;}

to {opacity: 1;}

}

/* start test movement from mobile */

.MobileButton {

display: grid;

grid-template-columns: repeat(3, 1fr);

height: 100px;

width: 100px;

position: absolute;

bottom: 50px;

right: 50px;

}

.MobileButton Button {

height: 100%;

width: 100%;

background-color: lightgrey;

}

.invisible {

visibility: hidden;

}

/* end test movement from mobile */

  <!-- PRELOAD SPRITES -->

  <!-- GAME SCENES -->

  <!-- INVENTORY MENU -->
<div id="PlayerDisplay"></div>

<div id="ArmourGrid"></div>

<div id="ItemGrid"></div>
  <!-- start test movement from mobile -->

  <!-- end test movement from mobile -->

  

// GET ELEMENTS IN VARIABLE

const canvas = document.getElementById(“game”);

const healthBar = document.getElementById(“HealthBar”);

const menuButton = document.getElementById(“MenuButton”)

const playerMenu = document.getElementById(“PlayerMenu”);

const playerDisplay = document.getElementById(“PlayerDisplay”);

const armourGrid = document.getElementById(“ArmourGrid”);

const itemGrid = document.getElementById(“ItemGrid”);

const wallImg = document.getElementById(“wall”);

const floorImg = document.getElementById(“floor”);

const exitImg = document.getElementById(“exit”);

const playerImg = document.getElementById(“player”);

const itemImg = document.getElementById(“item”);

const trapImg = document.getElementById(“trap”);

const chestImg = document.getElementById(“chest”);

const overlay = document.getElementById(“ChestOverlay”);

// CREATE THE MAZE

const ctx = canvas.getContext(“2d”);

const tileSize = 40;

const maze = [

[‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’],

[‘#’, ‘P’, ‘ ‘, ‘T’, ‘#’, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘#’],

[‘#’, ‘C’, ‘#’, ‘I’, ‘#’, ‘ ‘, ‘#’, ‘#’, ‘ ‘, ‘#’],

[‘#’, ‘ ‘, ‘#’, ‘ ‘, ‘ ‘, ‘ ‘, ‘#’, ‘ ‘, ‘ ‘, ‘#’],

[‘#’, ‘ ‘, ‘#’, ‘#’, ‘#’, ‘ ‘, ‘#’, ‘ ‘, ‘#’, ‘#’],

[‘#’, ‘ ‘, ‘C’, ‘ ‘, ‘#’, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘#’],

[‘#’, ‘#’, ‘#’, ‘ ‘, ‘#’, ‘#’, ‘#’, ‘#’, ‘ ‘, ‘#’],

[‘#’, ‘ ‘, ‘#’, ‘ ‘, ‘S’, ‘ ‘, ‘ ‘, ‘#’, ‘ ‘, ‘#’],

[‘#’, ‘ ‘, ‘#’, ‘#’, ‘#’, ‘#’, ‘ ‘, ‘#’, ‘E’, ‘#’],

[‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’],

];

function drawMaze() {

for (let y = 0; y {playerMenu.style.display =

(playerMenu.style.display === “none”) ?

“grid” : “none”;

});

function updatePlayerMenu() {

playerDisplay.innerHTML = ` `;

armourGrid.innerHTML = “”;

currentPlayer.armour?.forEach(armour => { const armourElement = document.createElement(“img”);

armourElement.src = armour.img;

armourElement.alt = “armour”;

armourElement.title = armour.name;

armourGrid.appendChild(armourElement);});

itemGrid.innerHTML = “”;

currentPlayer.item?.forEach((item, index) => {

const itemElement = document.createElement(“img”);

itemElement.src = item.img;

itemElement.alt = “item”;

itemElement.title = item.name;

itemElement.addEventListener(“click”, () => {

if (confirm(`Use or remove “${item.name}”?`)) {removeItemFromInventory(index);

}

});

itemGrid.appendChild(itemElement);

});

// make a bestiary for encountered enemies

}

function addItemToInventory(item) {

currentPlayer.item.push(item);

updatePlayerMenu();

showChestPopup(item);

}

function removeItemFromInventory(index) {

if (index >= 0 && index = trapAnim.frameSpeed) {

trapAnim.totalTime = 0;

trapAnim.currentFrame = trapAnim.active ?

Math.min(trapAnim.currentFrame + 1, trapAnim.totalFrame – 1) :

Math.max(trapAnim.currentFrame – 1, 0);

}

}

//CHEST

const chestAnim = {

totalFrames: 3,

currentFrame: 0,

totalTime: 0,

frameSpeed: 150,

active: false

};

const openedChest = new Set();

function openChest() {

// check what chests have been opened

const openedChestPosition = `${currentPlayer.x},${currentPlayer.y}`;

if (maze[currentPlayer.y][currentPlayer.x] === ‘C’ && !openedChest.has(openedChestPosition)) {

openedChest.add(openedChestPosition);

// play the chest opening audio and animatiom

document.getElementById(“chestaudio”).play();

chestAnim.active = true;

// Pick a random item

const randomItem = allItems[Math.floor(Math.random() * allItems.length)];

alert(“you found me”);

// call fucntion when chest is opened

health(30);

addItemToInventory(randomItem);

// give item in inventory near health bar(later on game menu like botw) and get rid of item posiotion x:3 y:3

}

// if maze player x === S

}

function showChestPopup(item) {

// Clear any previous content instead of removing the entire element

overlay.innerHTML = “”;

overlay.style.display = “flex”;

const content = document.createElement(“div”);

content.id = “ChestContent”;

content.innerHTML = `

${item.name}

${item.description}

(Click anywhere to close)

`;

overlay.appendChild(content);

// Click anywhere to close

overlay.onclick = () => {

overlay.style.display = “none”;

overlay.innerHTML = “”;

};

// Auto-remove after 5 seconds

setTimeout(() => {

overlay.style.display = “none”;

overlay.innerHTML = “”;

}, 5000);

}

function AnimationChest(lastTimeChest) {

chestAnim.totalTime += lastTimeChest;

if (chestAnim.totalTime >= chestAnim.frameSpeed) {

chestAnim.totalTime = 0;

chestAnim.currentFrame = chestAnim.active ?

Math.min(chestAnim.currentFrame + 1, chestAnim.totalFrame – 1) :

Math.max(chestAnim.currentFrame – 1, 0);

}

}

// PLAYER

const basePlayer = {

maxHealth: 100,

health: 100,

armour: [],

item: []

};

let currentPlayer = {

x: 1,

y: 1,

…structuredClone(basePlayer)

};

healthBar.textContent = “HEALTH: ” + currentPlayer.health;

function health(number) {

currentPlayer.health += number;

healthBar.textContent = “HEALTH: ” + currentPlayer.health;

if (currentPlayer.health > currentPlayer.maxHealth) {

currentPlayer.health = currentPlayer.maxHealth;

}

if (currentPlayer.health alert(“You win!”), 100);

}

if (maze[newY][newX] === ‘T’) {

trapAnim.active= true;

health(-20);

alert(“You got hurt!”);

}

}

}

function resetPlayer() {

currentPlayer = {

x: 1,

y: 1,

…structuredClone(basePlayer)

};

}

/*player death

const totalFrameDeath = 3;

let currentFrameDeath = 0;

let totalTimeDeath = 0;

const frameSpeedDeath = 150;

let activeDeath = false;

function Death() {

alert(“YOU DIED”);

resetPlayer();

activeDeath = true;

– death animation

– stop movement

– lose display

}

*/

// ITEMS

const allItems = [

{

name: “Golden Fleece”,

description: “Argonaut’s story”,

img: “ASSETS/SPRITES/GoldenFleece.png”

//give 1 extra life

//if health = 0 then health = maxHealth (only once)

},

{

name: “Potion of Healing”,

description: “Restores 50 health.”,

img: “ASSETS/SPRITES/HealingPotion.png”

}

]

/* {skull = gain 1 throwable skull from skeleton chest and throw it in an arch( use THE trick to make items or enemies jump in 2d games simulating the arch – youtube link with explanations : https://youtu.be/46TL8AEL4yY?si=yqMJ9-BDJeMvc-_G)

– randomize between skull, bones or rocks when looting a skeleton chest }, */

/* { door = {make a closed door and find keys in chest or when defeating enemies. if key then activeDoor = true

},*/

// KEY AND BUTTON

document.addEventListener(“keydown”, (e) => {

switch (e.key) {

case “ArrowUp”: move(0, -1); break;

case “ArrowDown”: move(0, 1); break;

case “ArrowLeft”: move(-1, 0); break;

case “ArrowRight”: move(1, 0); break;

case “e”: case “E”: openChest(); break}

});

/*start test (movement from mobile)*/

document.getElementById(“topcenter”).addEventListener(“click”, () => move(0, -1));

document.getElementById(“bottomcenter”).addEventListener(“click”, () => move(0, 1));

document.getElementById(“centerleft”).addEventListener(“click”, () => move(-1, 0));

document.getElementById(“centerright”).addEventListener(“click”, () => move(1, 0));

/*end test (movement from mobile)*/

document.getElementById(“centercenter”).addEventListener(“click”, () =>

openChest());

// ANIMATIONS LOOP

let startTimeChest= performance.now(); let startTimeTrap = performance.now();

function AnimationLoop(time) {

const lastTimeTrap = time – startTimeTrap; startTimeTrap = time;

AnimationTrap(lastTimeTrap);

const lastTimeChest = time – startTimeChest; startTimeChest = time;

AnimationChest(lastTimeChest);

updatePlayerMenu();

drawMaze();

requestAnimationFrame(AnimationLoop);}

requestAnimationFrame(AnimationLoop);

// TO DO LIST

// gain god’s favour through challenges and sacrifice (example : kill 1000 enemies and Ares will make you stronger, solve 1000 puzzles and will gain Athena’s favour, Hermes will make you faster, Apollo will make your bow stronger) (level up favours)

I was expecting the chest to animate with the frameshhet but it only disappear. I tried to block test but nothing. I’m posting the entire script because I don’t know if the problem is in the CSS, html or JavaScript.

I’m trying to make my first game but I have a problem with the animations that instead of starting the animation the chest just disappear

Labyrinth Game

*, *::before, *::after {

box-sizing: border-box;

}

/* GAME SCENES */

body {

background-color: #222;

display: flex;

justify-content: center;

align-items: center;

height: 100vh;

width: 100vw;

margin: 0;

font-family: sans-serif;

}

#HealthBar {

background-color: darkred;

height: 25px;

width: 150px;

font-size: 14px;

color: white;

position: absolute;

top: 20px;

left: 20px;

padding: 5px;

text-align: center;

border-radius: 5px;

}

canvas {

border: 40px solid;

border-image-source: url(“ASSETS/BorderWall.png”);

border-image-slice: 40;

border-image-repeat: repeat;

border-image-width: 40px;

background-color: #ddd;

}

/* GAME MENU */

#MenuButton {

position: absolute;

bottom: 50px;

left: 50px;

z-index: 10;

}

#PlayerMenu {

display: none;

grid-template-columns: 1fr 2fr;

grid-template-rows: 1fr 1fr;

position: absolute;

top: 50px;

right: 50px;

width: 300px;

background-color: #444;

color: white;

padding: 10px;

gap: 5px;

border: 2px solid white;

border-radius: 10px;

z-index: 10;

}

#PlayerDisplay {

grid-column: 1;

grid-row: 1;

background-color: #444;

padding: 10px;

border: 2px solid white;

border-radius: 10px;

}

#PlayerDisplay img {

width: 100%;

border: 2px solid;

border-radius: 10px;

}

#ArmourGrid {

grid-column: 1;

grid-row: 2;

display: grid;

grid-template-columns: repeat(2, 1fr);

padding: 5px;

gap: 5px;

border: 2px solid;

border-radius: 10px;

}

#ArmourGrid img {

width: 100%;

border: 2px solid white;

background-color: lightgrey;

border-radius: 10px;

}

#ItemGrid {

grid-column: 2;

grid-row: 1 / 3;

display: grid;

grid-template-columns: repeat(2, 1fr);

padding: 5px;

gap: 5px;

border: 2px solid;

border-radius: 10px;

}

#ItemGrid img {

width: 100%;

border: 2px solid white;

background-color: lightgrey;

border-radius: 10px;

}

/* GAME ELEMENTS */

/* CHEST POP UP */

#ChestOverlay {

position: fixed;

top: 0;

left: 0;

width: 100vw;

height: 100vh;

background: rgba(0, 0, 0, 0.8);

display: flex;

justify-content: center;

align-items: center;

z-index: 9999;

animation: fadeIn 0.5s ease-in-out;

}

#ChestContent {

width: 50vw;

height: 50vh;

background-color: #222;

color: white;

padding: 20px;

border: 4px solid gold;

border-radius: 15px;

text-align: center;

animation: popUp 0.4s ease-out;

}

#ChestContent img {

width: 100px;

margin-bottom: 10px;

}

@keyframes popUp {

0% {

transform: scale(0.2);

opacity: 0;

}

100% {

transform: scale(1);

opacity: 1;

}

}

@keyframes fadeIn {

from {opacity: 0;}

to {opacity: 1;}

}

/* start test movement from mobile */

.MobileButton {

display: grid;

grid-template-columns: repeat(3, 1fr);

height: 100px;

width: 100px;

position: absolute;

bottom: 50px;

right: 50px;

}

.MobileButton Button {

height: 100%;

width: 100%;

background-color: lightgrey;

}

.invisible {

visibility: hidden;

}

/* end test movement from mobile */

  <!-- PRELOAD SPRITES -->

  <!-- GAME SCENES -->

  <!-- INVENTORY MENU -->
<div id="PlayerDisplay"></div>

<div id="ArmourGrid"></div>

<div id="ItemGrid"></div>
  <!-- start test movement from mobile -->

  <!-- end test movement from mobile -->

  

// GET ELEMENTS IN VARIABLE

const canvas = document.getElementById(“game”);

const healthBar = document.getElementById(“HealthBar”);

const menuButton = document.getElementById(“MenuButton”)

const playerMenu = document.getElementById(“PlayerMenu”);

const playerDisplay = document.getElementById(“PlayerDisplay”);

const armourGrid = document.getElementById(“ArmourGrid”);

const itemGrid = document.getElementById(“ItemGrid”);

const wallImg = document.getElementById(“wall”);

const floorImg = document.getElementById(“floor”);

const exitImg = document.getElementById(“exit”);

const playerImg = document.getElementById(“player”);

const itemImg = document.getElementById(“item”);

const trapImg = document.getElementById(“trap”);

const chestImg = document.getElementById(“chest”);

const overlay = document.getElementById(“ChestOverlay”);

// CREATE THE MAZE

const ctx = canvas.getContext(“2d”);

const tileSize = 40;

const maze = [

[‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’],

[‘#’, ‘P’, ‘ ‘, ‘T’, ‘#’, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘#’],

[‘#’, ‘C’, ‘#’, ‘I’, ‘#’, ‘ ‘, ‘#’, ‘#’, ‘ ‘, ‘#’],

[‘#’, ‘ ‘, ‘#’, ‘ ‘, ‘ ‘, ‘ ‘, ‘#’, ‘ ‘, ‘ ‘, ‘#’],

[‘#’, ‘ ‘, ‘#’, ‘#’, ‘#’, ‘ ‘, ‘#’, ‘ ‘, ‘#’, ‘#’],

[‘#’, ‘ ‘, ‘C’, ‘ ‘, ‘#’, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘#’],

[‘#’, ‘#’, ‘#’, ‘ ‘, ‘#’, ‘#’, ‘#’, ‘#’, ‘ ‘, ‘#’],

[‘#’, ‘ ‘, ‘#’, ‘ ‘, ‘S’, ‘ ‘, ‘ ‘, ‘#’, ‘ ‘, ‘#’],

[‘#’, ‘ ‘, ‘#’, ‘#’, ‘#’, ‘#’, ‘ ‘, ‘#’, ‘E’, ‘#’],

[‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’, ‘#’],

];

function drawMaze() {

for (let y = 0; y {playerMenu.style.display =

(playerMenu.style.display === “none”) ?

“grid” : “none”;

});

function updatePlayerMenu() {

playerDisplay.innerHTML = ` `;

armourGrid.innerHTML = “”;

currentPlayer.armour?.forEach(armour => { const armourElement = document.createElement(“img”);

armourElement.src = armour.img;

armourElement.alt = “armour”;

armourElement.title = armour.name;

armourGrid.appendChild(armourElement);});

itemGrid.innerHTML = “”;

currentPlayer.item?.forEach((item, index) => {

const itemElement = document.createElement(“img”);

itemElement.src = item.img;

itemElement.alt = “item”;

itemElement.title = item.name;

itemElement.addEventListener(“click”, () => {

if (confirm(`Use or remove “${item.name}”?`)) {removeItemFromInventory(index);

}

});

itemGrid.appendChild(itemElement);

});

// make a bestiary for encountered enemies

}

function addItemToInventory(item) {

currentPlayer.item.push(item);

updatePlayerMenu();

showChestPopup(item);

}

function removeItemFromInventory(index) {

if (index >= 0 && index = trapAnim.frameSpeed) {

trapAnim.totalTime = 0;

trapAnim.currentFrame = trapAnim.active ?

Math.min(trapAnim.currentFrame + 1, trapAnim.totalFrame – 1) :

Math.max(trapAnim.currentFrame – 1, 0);

}

}

//CHEST

const chestAnim = {

totalFrames: 3,

currentFrame: 0,

totalTime: 0,

frameSpeed: 150,

active: false

};

const openedChest = new Set();

function openChest() {

// check what chests have been opened

const openedChestPosition = `${currentPlayer.x},${currentPlayer.y}`;

if (maze[currentPlayer.y][currentPlayer.x] === ‘C’ && !openedChest.has(openedChestPosition)) {

openedChest.add(openedChestPosition);

// play the chest opening audio and animatiom

document.getElementById(“chestaudio”).play();

chestAnim.active = true;

// Pick a random item

const randomItem = allItems[Math.floor(Math.random() * allItems.length)];

alert(“you found me”);

// call fucntion when chest is opened

health(30);

addItemToInventory(randomItem);

// give item in inventory near health bar(later on game menu like botw) and get rid of item posiotion x:3 y:3

}

// if maze player x === S

}

function showChestPopup(item) {

// Clear any previous content instead of removing the entire element

overlay.innerHTML = “”;

overlay.style.display = “flex”;

const content = document.createElement(“div”);

content.id = “ChestContent”;

content.innerHTML = `

${item.name}

${item.description}

(Click anywhere to close)

`;

overlay.appendChild(content);

// Click anywhere to close

overlay.onclick = () => {

overlay.style.display = “none”;

overlay.innerHTML = “”;

};

// Auto-remove after 5 seconds

setTimeout(() => {

overlay.style.display = “none”;

overlay.innerHTML = “”;

}, 5000);

}

function AnimationChest(lastTimeChest) {

chestAnim.totalTime += lastTimeChest;

if (chestAnim.totalTime >= chestAnim.frameSpeed) {

chestAnim.totalTime = 0;

chestAnim.currentFrame = chestAnim.active ?

Math.min(chestAnim.currentFrame + 1, chestAnim.totalFrame – 1) :

Math.max(chestAnim.currentFrame – 1, 0);

}

}

// PLAYER

const basePlayer = {

maxHealth: 100,

health: 100,

armour: [],

item: []

};

let currentPlayer = {

x: 1,

y: 1,

…structuredClone(basePlayer)

};

healthBar.textContent = “HEALTH: ” + currentPlayer.health;

function health(number) {

currentPlayer.health += number;

healthBar.textContent = “HEALTH: ” + currentPlayer.health;

if (currentPlayer.health > currentPlayer.maxHealth) {

currentPlayer.health = currentPlayer.maxHealth;

}

if (currentPlayer.health alert(“You win!”), 100);

}

if (maze[newY][newX] === ‘T’) {

trapAnim.active= true;

health(-20);

alert(“You got hurt!”);

}

}

}

function resetPlayer() {

currentPlayer = {

x: 1,

y: 1,

…structuredClone(basePlayer)

};

}

/*player death

const totalFrameDeath = 3;

let currentFrameDeath = 0;

let totalTimeDeath = 0;

const frameSpeedDeath = 150;

let activeDeath = false;

function Death() {

alert(“YOU DIED”);

resetPlayer();

activeDeath = true;

– death animation

– stop movement

– lose display

}

*/

// ITEMS

const allItems = [

{

name: “Golden Fleece”,

description: “Argonaut’s story”,

img: “ASSETS/SPRITES/GoldenFleece.png”

//give 1 extra life

//if health = 0 then health = maxHealth (only once)

},

{

name: “Potion of Healing”,

description: “Restores 50 health.”,

img: “ASSETS/SPRITES/HealingPotion.png”

}

]

/* {skull = gain 1 throwable skull from skeleton chest and throw it in an arch( use THE trick to make items or enemies jump in 2d games simulating the arch – youtube link with explanations : https://youtu.be/46TL8AEL4yY?si=yqMJ9-BDJeMvc-_G)

– randomize between skull, bones or rocks when looting a skeleton chest }, */

/* { door = {make a closed door and find keys in chest or when defeating enemies. if key then activeDoor = true

},*/

// KEY AND BUTTON

document.addEventListener(“keydown”, (e) => {

switch (e.key) {

case “ArrowUp”: move(0, -1); break;

case “ArrowDown”: move(0, 1); break;

case “ArrowLeft”: move(-1, 0); break;

case “ArrowRight”: move(1, 0); break;

case “e”: case “E”: openChest(); break}

});

/*start test (movement from mobile)*/

document.getElementById(“topcenter”).addEventListener(“click”, () => move(0, -1));

document.getElementById(“bottomcenter”).addEventListener(“click”, () => move(0, 1));

document.getElementById(“centerleft”).addEventListener(“click”, () => move(-1, 0));

document.getElementById(“centerright”).addEventListener(“click”, () => move(1, 0));

/*end test (movement from mobile)*/

document.getElementById(“centercenter”).addEventListener(“click”, () =>

openChest());

// ANIMATIONS LOOP

let startTimeChest= performance.now(); let startTimeTrap = performance.now();

function AnimationLoop(time) {

const lastTimeTrap = time – startTimeTrap; startTimeTrap = time;

AnimationTrap(lastTimeTrap);

const lastTimeChest = time – startTimeChest; startTimeChest = time;

AnimationChest(lastTimeChest);

updatePlayerMenu();

drawMaze();

requestAnimationFrame(AnimationLoop);}

requestAnimationFrame(AnimationLoop);

// TO DO LIST

// gain god’s favour through challenges and sacrifice (example : kill 1000 enemies and Ares will make you stronger, solve 1000 puzzles and will gain Athena’s favour, Hermes will make you faster, Apollo will make your bow stronger) (level up favours)

I was expecting the chest to animate with the frameshhet but it only disappear.

How to perform TTS operations with JavaScript?

I was following this demo: https://codepen.io/matt-west/pen/DpmMgE

And it worked with a button to select a voice, but I need the specific voice to be set all the time.


var firstText = "Starch";

var defaultVoiceName = "Microsoft Hazel - English (United Kingdom)";

if (speechSynthesis) {
} else {
    alert("Bad news! Your browser doesn't have the Speech Synthesis API this project requires. Try opening this webpage using the newest version of Google Chrome.");
}

// Create a new instance of SpeechSynthesisUtterance.
var msg = new SpeechSynthesisUtterance();

// Set voice. I'm trying to set needed voice ("Microsoft Hazel - English (United Kingdom)") // here, but it doesn't work. This voice is installed on my machine.
msg.voice = speechSynthesis.getVoices().filter(function(voice) { return voice.name == defaultVoiceName })[0];

// Create a new utterance for the specified text and add it to
// the queue.
function speak(text) {
    // Stop the previous tts
    window.speechSynthesis.cancel();

    // Set the text.
    msg.text = text;

    // Queue this utterance.
    window.speechSynthesis.speak(msg);
}

speak(firstText);

What am I doing wrong here? Maybe there is a better way to tts something? I tried the “ResponsiveVoice” library, but it works with a delay.

About calling multiple APIs while catching user input events in React

I am developing a React application as a beginner, when the user types in the search box, I need to send a request (API call) to get suggested results. However, if I call the API immediately every time the user types each character, it will be resource-consuming and have a bad experience and have to load many times.

I tried delaying it by 500ms, but the result still calls many APIs

function bindInputWithDelay(selector, callback) {
  const inputEl = document.querySelector(selector);
  if (!inputEl) return;

  inputEl.addEventListener('input', (event) => {
    const value = event.target.value;
    setTimeout(() => {
      callback(value);
    }, 500);
  });
}

Please help me write a function that will wait for the user to finish typing and then send the API only once, the waiting time can be 500ms.

If it’s a custom React Hook, that’s even better.

Thanks.