How to stop looping text animation - javascript

I am a student studying JavaScript.
I found the js code for the scrambled text animation, but I want to stop looping.
(Because I want to read the contents)
Anyone can explain to stop looping in the 'for or if' part?
Also, are there any unnecessary parts of the JavaScript code?
Thanks in advance for the answer.
html
// ——————————————————————————————————————————————————
// TextScramble
// ——————————————————————————————————————————————————
class TextScramble {
constructor(el) {
this.el = el
this.chars = 'かきくけこらりるれろ'
this.update = this.update.bind(this)
}
setText(newText) {
const oldText = this.el.innerText
const length = Math.max(oldText.length, newText.length)
const promise = new Promise((resolve) => this.resolve = resolve)
this.queue = []
for (let i = 0; i < length; i++) {
const from = oldText[i] || ''
const to = newText[i] || ''
const start = Math.floor(Math.random() * 40)
const end = start + Math.floor(Math.random() * 40)
this.queue.push({
from,
to,
start,
end
})
}
cancelAnimationFrame(this.frameRequest)
this.frame = 0
this.update()
return promise
}
update() {
let output = ''
let complete = 0
for (let i = 0, n = this.queue.length; i < n; i++) {
let {
from,
to,
start,
end,
char
} = this.queue[i]
if (this.frame >= end) {
complete++
output += to
} else if (this.frame >= start) {
if (!char || Math.random() < 0.28) {
char = this.randomChar()
this.queue[i].char = char
}
output += `<span class="dud">${char}</span>`
} else {
output += from
}
}
this.el.innerHTML = output
if (complete === this.queue.length) {
this.resolve()
} else {
this.frameRequest = requestAnimationFrame(this.update)
this.frame++
}
}
randomChar() {
return this.chars[Math.floor(Math.random() * this.chars.length)]
}
}
// ——————————————————————————————————————————————————
// Example
// ——————————————————————————————————————————————————
const phrases = [
'ロレム・イプサムの嘆き、トマト大好き学部のエリット、しかし時と活力、そのような労働と悲しみ、ブラインド行うにはいくつかの重要な事柄に座ります。長年にわたり、私は学区と長寿であれば、そのような刺激の取り組み、彼女のうち、運動の利点を分注を邪魔されたする人が来ます。クピダタットのつるの痛みになりたい宿題に、批判されてきたら痛み、マグナ逃亡しても結果の喜びを生成しません。先例クピダタットブラックは先例していない、つまり、彼らはあなたの悩みに責任がある人の、一般的な義務を捨て、魂を癒しています。'
]
const el = document.querySelector('.text')
const fx = new TextScramble(el)
let counter = 0
const next = () => {
fx.setText(phrases[counter]).then(() => {
setTimeout(next, 800)
})
counter = (counter + 1) % phrases.length
}
next()
<div id="main">
<div class="container">
<div class="glitch" data-text="About">About</div>
<div class="glow">About</div>
</div>
<div class="scanlines"></div>
<div class="text"></div>
</div>

I think you should try adding delay in your loop
see if this helps you
for (let i=0; i<10; i++) {
task(i);
}
function task(i) {
setTimeout(function() {
// Add tasks to do
}, 2000 * i);
}

Related

not able to make multiple work group working and causing freeze

I am doing create multiple worker threads, in my case, i am trying to create 2:
This is my code to create work thread
function createWorker(data1, data2) {
return new Promise((resolve) => {
let worker = new Worker();
worker.postMessage(data1, data2);
worker.onmessage = (event) => {
postMessageRes = event.data;
if (postMessageRes == 200) {
// loadCOPC();
} else {
workerCount += 1;
let position = postMessageRes[0];
let color = postMessageRes[1];
for (let i = 0; i < position.length; i++) {
positions.push(position[i]);
colors.push(colors[i]);
}
resolve(true);
}
};
});
}
and using it in my loop
for (let m = 0; m < keyCountMap.length; ) {
let remaining = totalNodes - doneCount;
let numbWorker = Math.min(chunk, remaining);
for (let i = 0; i < numbWorker; i++) {
promises.push(createWorker([keyCountMap[m], keyCountMap[m + 1]]));
m += 2;
}
Promise.all(promises).then((response) => {
console.log("one chunk finishes");
});
}
The code works fine if i instead of all these use one static work thread and call postMessage in the loop for only one but not while i am trying to make chunk like here in the code.
When i run the code, my browser freeze
This is my worker file:
import { Copc, Key } from "copc";
import * as THREE from "three";
const color = new THREE.Color();
const colors = [];
let firstTime = true;
var nodePages, pages, receivedData, copc;
let x_min, y_min, z_min, x_max, y_max, z_max, width;
let positions = [];
let filename = "https://s3.amazonaws.com/data.entwine.io/millsite.copc.laz";
const readPoints = (id, getters) => {
let returnPoint = getXyzi(id, getters);
positions.push(
returnPoint[0] - x_min - 0.5 * width,
returnPoint[1] - y_min - 0.5 * width,
returnPoint[2] - z_min - 0.5 * width
);
const vx = (returnPoint[3] / 65535) * 255;
color.setRGB(vx, vx, vx);
colors.push(color.r, color.g, color.b);
firstTime = false;
};
function getXyzi(index, getters) {
return getters.map((get) => get(index));
}
async function load() {
copc = await Copc.create(filename);
let scale = copc.header.scale[0];
[x_min, y_min, z_min, x_max, y_max, z_max] = copc.info.cube;
width = Math.abs(x_max - x_min);
// let center_x = (x_min + x_max) / 2;
// let center_y = (y_min + y_max) / 2;
// let center_z = (z_min + z_max) / 2;
receivedData = await Copc.loadHierarchyPage(
filename,
copc.info.rootHierarchyPage
);
nodePages = receivedData.nodes;
pages = receivedData.pages;
postMessage(200);
}
async function loadData(myRoot, pointCount) {
const view = await Copc.loadPointDataView(filename, copc, myRoot);
let getters = ["X", "Y", "Z", "Intensity"].map(view.getter);
for (let j = 0; j < pointCount; j += 1) {
readPoints(j, getters);
}
postMessage([positions, colors]);
}
load();
onmessage = function (message) {
let mapIndex = message.data[0];
let pointCount = message.data[1];
console.log(mapIndex);
let myRoot = nodePages[mapIndex];
loadData(myRoot, pointCount);
};
The issue might be due to creating multiple worker threads in a loop, which could lead to a large number of worker threads and result in high memory usage and ultimately lead to freezing of the browser.
One approach to resolve this issue is to limit the number of worker threads created at a time by setting a maximum number of workers, and creating new workers only when some workers have completed their tasks.
Here's an example of the code that implements this approach:
const MAX_WORKERS = 4;
let promises = [];
let workerCount = 0;
function createWorker(data1, data2) {
return new Promise((resolve) => {
let worker = new Worker();
worker.postMessage(data1, data2);
worker.onmessage = (event) => {
postMessageRes = event.data;
if (postMessageRes == 200) {
// loadCOPC();
} else {
workerCount += 1;
let position = postMessageRes[0];
let color = postMessageRes[1];
for (let i = 0; i < position.length; i++) {
positions.push(position[i]);
colors.push(colors[i]);
}
if (workerCount === MAX_WORKERS) {
workerCount = 0;
promises = [];
}
resolve(true);
}
};
});
}
for (let m = 0; m < keyCountMap.length; ) {
let remaining = totalNodes - doneCount;
let numbWorker = Math.min(chunk, remaining);
for (let i = 0; i < numbWorker; i++) {
promises.push(createWorker([keyCountMap[m], keyCountMap[m + 1]]));
m += 2;
}
if (workerCount === MAX_WORKERS) {
Promise.all(promises).then((response) => {
console.log("one chunk finishes");
});
}
}

How to Visualize Quick Sort Algo while it is arranging the elements in HTML and JS

I have been working on this project for a while now and I would appreciate it if you guys could help me out.
The quick sort algorithm works but since it uses recursion I don't know how or where I should rearrange the HTML divs created.
I have tried rearranging the divs after each swap function is called but that does not seem to work any ideas on how I might solve this problem?
class Element{
constructor(value , id){
this.value = value;
this.id = id;
}
}
function generateElemenets(){
for(let i = 0 ; i < 10; i++ ){
let randomValue = generateRandomValue();
values[i] = new Element(randomValue , i);
const newDiv = document.createElement("div");
newDiv.classList.add("element");
newDiv.setAttribute("id", i);
container.appendChild(newDiv);
document.getElementById(i).style.height = `${randomValue}px`;
}
}
function generateRandomValue(){
let x = Math.floor((Math.random() * 100) + 20);
return x;
}
function quickSort(arr, start, end){
if(start >= end){
return;
}
let index = partition(arr,start, end);
quickSort(arr, start, index-1);
quickSort(arr, index + 1, end);
return arr;
}
function partition(arr, start, end){
let pivotIndex = start;
let pivotValue = arr[end].value;
for (let i = start; i < end ; i++){
if(arr[i].value < pivotValue){
swap(arr, i, pivotIndex);
pivotIndex ++;
}
}
swap(arr,pivotIndex, end);
return pivotIndex;
}
function swap(items, leftIndex, rightIndex){
var temp = items[leftIndex];
items[leftIndex] = items[rightIndex];
items[rightIndex] = temp;
}
You could:
give the div elements an absolute position style, and set a transition effect when their left-coordinate changes.
let the swap function return a promise that resolves when the transition effect is complete.
Make the quickSort, partition functions asynchronous so they can await the swap promises to resolve
Here is an implementation:
class Element{
constructor(container, value, i) {
this.value = value;
const div = document.createElement("div");
div.classList.add("element");
div.textContent = value;
container.appendChild(div);
div.style.height = `${value}px`;
div.style.left = `${30*i}px`;
div.style.top = `${120-value}px`;
this.div = div;
}
move(i) {
// Return promise that resolves when move is complete
return new Promise(resolve => {
this.div.addEventListener('transitionend', (e) => {
this.div.classList.toggle('highlight', false);
resolve();
}, { once: true });
this.div.classList.toggle('highlight', true);
this.div.style.left = `${30*i}px`; // trigger transition effect
});
}
}
const generateRandomValue = () => Math.floor((Math.random() * 100) + 20);
function generateElements(container, length=10) {
container.innerHTML = "";
return Array.from({length}, (_, i) =>
new Element(container, generateRandomValue(), i)
);
}
async function quickSort(arr, start, end){
if (start >= end) {
return;
}
const index = await partition(arr, start, end);
await quickSort(arr, start, index-1);
await quickSort(arr, index + 1, end);
return arr;
}
async function partition(arr, start, end) {
let pivotIndex = start;
const pivotValue = arr[end].value;
for (let i = start; i < end ; i++) {
if (arr[i].value < pivotValue) {
await swap(arr, i, pivotIndex);
pivotIndex++;
}
}
await swap(arr,pivotIndex, end);
return pivotIndex;
}
function swap(items, leftIndex, rightIndex) {
if (leftIndex === rightIndex) return; // Nothing to do
var temp = items[leftIndex];
items[leftIndex] = items[rightIndex];
items[rightIndex] = temp;
return Promise.all([items[leftIndex].move(leftIndex),
items[rightIndex].move(rightIndex)]);
}
const elements = generateElements(document.querySelector("#container"));
setTimeout(() =>
quickSort(elements, 0, elements.length - 1),
1000);
.element {
border: 1px solid;
width: 25px;
position: absolute;
transition: left 1s;
background: white;
}
#container {
margin: 10px;
position: relative;
}
.highlight {
background: yellow;
z-index: 1;
}
<div id="container"></div>

Creating Coin Flip using Vanilla Javascript and decrement and this

I need to make a coin flip 20x and display the coin, and the results x times each. I am trying to use decrement to determine the coin flip. And then need to display the flip x number of times. I am running into an issue of how to write it using this. and decrement.
const coin = {
state: 0,
flip: function () {
this.state = Math.floor(Math.random() * 2) == 0 ? "tails" : "heads";
// 0 or 1: use "this.state" to access the "state" property on this object.
},
toString: function () {
if (this.state === 0) {
sides = "heads";
} else if (this.state === 1) {
sides = "tails";
}
return sides;
},
toHTML: function () {
const image = document.createElement("img");
let h1 = document.querySelector("h1");
h1.append(image);
if (this.state === 0) {
image.src = "images/tails.png";
} else if (this.state === 1) {
image.src = "image/heads.png";
}
return image;
},
};
function display20Flips() {
const results = [];
for (let i = 0; i < 20; i++) {
coin.flip();
h3.innerHTML += coin.state;
results.push(coin.state++);
}
You can also approach it functionally. This will help you focus on one problem at a time:
// Store the coin flip state as a boolean (true or false)
function randomBoolean () {
return Boolean(Math.floor(Math.random() * 2));
}
// Convert the boolean state to a "side" string
// heads is false, tails is true
function asCoinSide (bool) {
return bool ? 'tails' : 'heads';
}
function createCoinImage (bool) {
const side = asCoinSide(bool);
const image = document.createElement('img');
image.alt = side;
// StackOverflow doesn't have access to your local images,
// so this will show an error in the code snippet demo
// when the URL is loaded, but will work if the images exist:
image.src = `images/${side}.png`;
return image;
}
function displayCoinFlips (count = 20) {
const div = document.querySelector('div.coins');
const results = [];
for (let i = 0; i < count; i += 1) {
// Get a state
const state = randomBoolean();
results.push(state);
// Use the state to create the image
const image = createCoinImage(state);
// And append it to the container div
div.appendChild(image);
}
return results;
}
function displaySummary (states) {
const div = document.querySelector('div.summary');
let headsCount = 0;
let tailsCount = 0;
// Count the heads vs. tails results
// Remember: heads is false, tails is true
for (const state of states) {
if (state) tailsCount += 1;
else headsCount += 1;
}
div.textContent = `Heads: ${headsCount}, Tails: ${tailsCount}`;
}
const states = displayCoinFlips();
displaySummary(states);
<div class="coins"></div>
<div class="summary"></div>
You had some issues with your code. I fixed them. Still, the code needs to be a little redesigned to have a class Coin and then coin = new Coin().
const coin = {
state: 0,
flip: function() {
this.state = Math.floor(Math.random() * 2) == 0 ? "tails" : "heads";
},
toString: function() {
if (this.state === 0) {
sides = "heads";
} else if (this.state === 1) {
sides = "tails";
}
return sides;
},
toHTML: function() {
let h1 = document.querySelector(".container");
const div = document.createElement("div");
if (this.state === "tails") {
div.innerText = "images/tails.png";
} else {
div.innerText = "image/heads.png";
}
h1.append(div);
return div;
},
};
function displayFlips(n) {
const results = [];
for (let i = 0; i < n; i++) {
coin.flip();
coin.toHTML();
results.push(coin.state);
}
return results;
}
console.log(displayFlips(20));
<div class="container">
</div>

How do I go through random item from DropDownList with JavaScript?

I want to automatic go through random items from the DropDownList1.
It's working, but it's going by the order first to last, and I want to go through items randomly.
/* function to automatic select DropDownList1 items */
function selectFromDropdown(selector, text) {
$(selector).find('option').each(function() {
if ($(this).text() == text) {
$(selector).val($(this).val());
return false;
}
})
}
$(document).ready(function() {
let numberOfTimes = 0;
const time = 1000 //3s
let values = [];
$('#DropDownList1').find('option').each(function() {
values.push($(this).text())
});
console.log(values);
const interval = setInterval(function() {
selectFromDropdown('#DropDownList1', values[numberOfTimes])
if (numberOfTimes == values.length - 1) {
clearInterval(interval);
} else {
numberOfTimes = numberOfTimes + 1;
}
},
time);
});
Here the snnipet: https://jsfiddle.net/lucasangelo_/17Lgr0kc/6/
If you want to get random values from a select, then you can use the next function:
function getRandomValuesFromSelect(selector, numberOfItemsWanted)
{
var valuesSelected = [];
var childrenSelect = document.getElementById(selector).children;
for (var i = 0; i < numberOfItemsWanted; i++) {
var randomValue = Math.floor(Math.random() * childrenSelect.length);
var randomOption = childrenSelect[randomValue];
if (valuesSelected.indexOf(randomOption.value) < 0) {
valuesSelected.push(randomOption.value);
} else {
i--;
}
}
return valuesSelected;
}
Then you could call it like so:
getRandomValuesFromSelect("DropDownList1", 3);
The answer is:
/* function to automatic select DropDownList1 items */
function selectFromDropdown(selector, text) {
$(selector).find('option').each(function() {
if ($(this).text() == text) {
$(selector).val($(this).val());
return false;
}
})
}
function getRandomNumber(min, max) {
return (Math.random() * (max - min) + min).toFixed(0);
}
$(document).ready(function() {
let numeroDeVezes = 0;
const tempoEntreCadaChamada = 1000 //3s
let valores = [];
$('#DropDownList1').find('option').each(function() {
valores.push($(this).text())
});
console.log(valores);
const interval = setInterval(function() {
const randomNumber = getRandomNumber(0, valores.length - 1);
const randomItem = valores[randomNumber];
//console.log(randomItem);
selectFromDropdown('#DropDownList1', randomItem),
console.log(`${numeroDeVezes} - Chamou do PostBack para ${randomItem}`);
//__doPostBack('LButton3', 'OnClick');
if (numeroDeVezes == valores.length - 1) {
console.log("Percorreu todos, mata o setInterval");
clearInterval(interval);
} else {
numeroDeVezes = numeroDeVezes + 1;
}
},
tempoEntreCadaChamada);
});
Thank you boys!

How to make regular javascript work in a react app

Hi I was trying to implement this text scrable
https://codepen.io/soulwire/pen/mErPAK/?editors=1010
in my react app, but I'm receiving an error TypeError: Cannot read property 'innerText' of null.
9 | this.update = this.update.bind(this)
10 | }
11 | setText(newText) {
> 12 | const oldText = this.el.innerText
13 | const length = Math.max(oldText.length, newText.length)
14 | const promise = new Promise(resolve => (this.resolve = resolve))
15 | this.queue = []
so far this is what I did
https://codesandbox.io/s/oxm38v7x9y
Created new component scrable.js
Moved the code from codepen
Imported to index.js
you don't need to fix the codesandbox, just a little clue is enough :)
import React, { Component } from "react"
export default class Scrable extends Component {
render() {
const phrases = [
"Neo,",
"sooner or later",
"you're going to realize",
"just as I did",
"that there's a difference",
"between knowing the path",
"and walking the path",
]
const el = document.querySelector(".text")
const fx = new TextScramble(el)
console.log(el)
let counter = 0
const next = () => {
fx.setText(phrases[counter]).then(() => {
setTimeout(next, 800)
})
counter = (counter + 1) % phrases.length
}
next()
return (
<TextScramble>
<div className="text" />
</TextScramble>
)
}
}
export class TextScramble extends Component {
constructor(el) {
super()
this.el = el
this.chars = "!<>-_\\/[]{}—=+*^?#________"
this.update = this.update.bind(this)
}
setText(newText) {
const oldText = this.el.innerText
const length = Math.max(oldText.length, newText.length)
const promise = new Promise(resolve => (this.resolve = resolve))
this.queue = []
for (let i = 0; i < length; i++) {
const from = oldText[i] || ""
const to = newText[i] || ""
const start = Math.floor(Math.random() * 40)
const end = start + Math.floor(Math.random() * 40)
this.queue.push({ from, to, start, end })
}
cancelAnimationFrame(this.frameRequest)
this.frame = 0
this.update()
return promise
}
update() {
let output = ""
let complete = 0
for (let i = 0, n = this.queue.length; i < n; i++) {
let { from, to, start, end, char } = this.queue[i]
if (this.frame >= end) {
complete++
output += to
} else if (this.frame >= start) {
if (!char || Math.random() < 0.28) {
char = this.randomChar()
this.queue[i].char = char
}
output += `<span class="dud">${char}</span>`
} else {
output += from
}
}
this.el.innerHTML = output
if (complete === this.queue.length) {
this.resolve()
} else {
this.frameRequest = requestAnimationFrame(this.update)
this.frame++
}
}
randomChar() {
return this.chars[Math.floor(Math.random() * this.chars.length)]
}
render() {
return <div />
}
}
Hi all thank you for the comments,
I was able to make it work. here's my code below. any suggestions is welcome
I'm not entirely sure it's the right way but it works
import React, { Component } from 'react'
export default class Scrable extends Component {
constructor(el) {
super(el)
this.el = el
this.chars = "!<>-_\\/[]{}—=+*^?#________"
// this.update = this.update.bind(this)
}
componentDidMount(){
const phrases = [
'Neo,',
'sooner or later',
'you\'re going to realize',
'just as I did',
'that there\'s a difference',
'between knowing the path',
'and walking the path'
]
const el = document.querySelector('.text')
const fx = new TextScramble(el)
let counter = 0
const next = () => {
fx.setText(phrases[counter]).then(() => {
setTimeout(next, 800)
})
counter = (counter + 1) % phrases.length
}
next()
console.log(el)
}
render() {
const phrases = [
"Neo,",
"sooner or later",
"you're going to realize",
"just as I did",
"that there's a difference",
"between knowing the path",
"and walking the path",
]
return (
<div>
<div className="text">text</div>
</div>
)
}
}
class TextScramble {
constructor(el) {
this.el = el
this.chars = '!<>-_\\/[]{}—=+*^?#________'
this.update = this.update.bind(this)
console.log(this)
}
setText(newText) {
const oldText = this.el.innerText
const length = Math.max(oldText.length, newText.length)
const promise = new Promise((resolve) => this.resolve = resolve)
this.queue = []
for (let i = 0; i < length; i++) {
const from = oldText[i] || ''
const to = newText[i] || ''
const start = Math.floor(Math.random() * 40)
const end = start + Math.floor(Math.random() * 40)
this.queue.push({ from, to, start, end })
}
cancelAnimationFrame(this.frameRequest)
this.frame = 0
this.update()
return promise
}
update() {
let output = ''
let complete = 0
for (let i = 0, n = this.queue.length; i < n; i++) {
let { from, to, start, end, char } = this.queue[i]
if (this.frame >= end) {
complete++
output += to
} else if (this.frame >= start) {
if (!char || Math.random() < 0.28) {
char = this.randomChar()
this.queue[i].char = char
}
output += `<span class="dud">${char}</span>`
} else {
output += from
}
}
this.el.innerHTML = output
if (complete === this.queue.length) {
this.resolve()
} else {
this.frameRequest = requestAnimationFrame(this.update)
this.frame++
}
}
randomChar() {
return this.chars[Math.floor(Math.random() * this.chars.length)]
}
}

Categories