【问题标题】:How to avoid overlapping of random numbers?如何避免随机数重叠?
【发布时间】:2022-02-08 00:08:33
【问题描述】:

点击按钮点击我!如何避免随机数重叠? 它会生成随机数,但是有一些数字重叠如何避免这种情况......,这里我不是在谈论随机数的重复,我想避免随机数的重叠......

const circle = document.querySelector(".circle");
const addNumBtn = document.querySelector('#addNumBtn')


function randomValue() {
  let random = Math.floor(Math.random() * 50) + 1;
  return random;
}
function randomColor(){
  let r = Math.floor(Math.random() * 255) + 1;
  let g = Math.floor(Math.random() * 255) + 1;
  let b = Math.floor(Math.random() * 255) + 1;
  return `rgba(${r},${g},${b})`
}
function randomSize(){
  let size = Math.floor(Math.random() * 30) + 8;
  return `${size}px`
}
function randNum() {
  let randnum = document.createElement("p");
  randnum.classList.add('numStyle')
  randnum.style.color=randomColor();
  randnum.style.fontSize=randomSize();
  randnum.textContent = randomValue();
  randnum.style.position = 'absolute'
  randnum.style.top = `${randomValue()}px`
  randnum.style.left = `${randomValue()}px`
  randnum.style.bottom = `${randomValue()}px`
  randnum.style.right = `${randomValue()}px`
  circle.append(randnum);
}


addNumBtn.addEventListener('click',randNum)
.circle {
  aspect-ratio: 1;
  width: 300px;
  background-color: black;
  border-radius: 50%;
  position: relative;
  overflow:hidden;
}

#addNumBtn{
  position:absolute;
  top:0;
  left:0;
}

.numStyle{
  font-family:"roboto",sans-serif;
}
//On Clicking button Click Me! I want to place all the random numbers inside the circle 
//together not one by one, at a time all numbers should be placed inside the circle by 
//clicking 
the button Click Me!
<div id="container"></div>
    <div class="circle"></div>
</div>
    <button id="addNumBtn">Click Me!</button>

【问题讨论】:

  • 所有数字”有多少个数字?你尝试过什么,你在哪里卡住了?
  • 50 个数字,我试图将所有数字(50)放在整个圆圈内,但不知何故数字只出现在左上角。如何解决这个错误?请解释...
  • @DavidThomas ,正如您在个人资料中提到的对新项目的兴​​趣,我的项目面临很多问题,任何帮助将不胜感激......(我不是在谈论这个问题..)

标签: javascript html jquery css arrays


【解决方案1】:

您需要在随机数生成器上循环您希望在圆圈中显示创建的数字元素的次数。您可以在randomValue() 函数中创建并返回一个数组 值,然后在randNum() 函数中循环该数组。

另外,我假设您希望附加元素的输出分布在整个圆形元素上,是吗?如果是这样,您需要随机化元素相对于圆大小的位置,而不是 randomValue 函数的返回值。

编辑:

OP 在发布答案后询问:圆圈边框边有一些数字无法正常显示如何解决?

由于元素的盒子模型,圆形元素的边框是方形的,而不是圆形的,虽然圆形元素的可视内容是圆形的,因为它的border-radius css。

您可以使用辅助函数来确定随机生成的数字是 xy,还是 lefttop ,使用半径大小中心点在圆形元素的border-radius内>xy 坐标

辅助功能的功劳: Simon Sarris

function pointInCircle(x, y, cx, cy, rad) {
  const distancesquared = (x - cx) * (x - cx) + (y - cy) * (y - cy);
  return distancesquared <= rad * rad;
}

我们将所有内容包装在一个 while 循环中,该循环检查计数器是否达到 50。在循环中,我们运行创建随机生成位置的函数 -> randomPos()。然后我们运行一个条件,使用函数pointInCircle(x, y, cx, cy, rad) 检查随机生成的点是否在圆内。如果此条件返回 true,我们将创建数字元素、样式并将数字元素附加到圆圈并将我们的计数器值迭代 1。

const circle = document.querySelector(".circle");
const addNumBtn = document.querySelector('#addNumBtn');
// we set the width of the circle element in JS and pass
// it to CSS using a css variable and the root element
const circleWidth = 350;
document.documentElement.style.setProperty('--circleWidth', `${circleWidth}px`);

// NOTE: '~~' -> is quicker form of writing Math.floor() 
// runs faster on most browsers.

function randomPos(min, max) {
  return ~~(Math.random() * (max - min + 1) + min)
}

// return a random value between 1 and 50
function randomValue(){
  return ~~(Math.random() * 50) + 1;
}

function randomColor() {
  let r = ~~(Math.random() * 255) + 1;
  let g = ~~(Math.random() * 255) + 1;
  let b = ~~(Math.random() * 255) + 1;
  return `rgba(${r},${g},${b})`
}

function randomSize() {
  let size = ~~(Math.random() * 30) + 8;
  return `${size}px`
}

// add a helper function to find the center of the 
// circle and calculate distance to the edge of circle
// x and y are the randomly generated points
// cx, cy are center of circle x and y repsectively
// rad is circle radius
function pointInCircle(x, y, cx, cy, rad) {
  const distancesquared = (x - cx) * (x - cx) + (y - cy) * (y - cy);
  return distancesquared <= rad * rad;
}

// you can remove valArray array if you do not want the 50 numbers to not be repeated
const valArray = [];

function randNum() {
  // add a counter
  let count = 1;
  // while loop to check if the counter has reached the target 50
  while (count <= 50) {
    // set the randomly generated val
    let val = randomValue();
    // random size = string with px added
    let randSize = randomSize();
    // random size = the exact number => typeof number 
    let posSize = randSize.split('px')[0];
    // an array to hold our randomly positioned number values
    // uses helper function randonPos
    // pass in the 1 and the circle width minus the font size
    let ran = [randomPos(1, circleWidth - posSize), randomPos(1, circleWidth - posSize)];
    // conditional to check bounds of circle using helper function
    // we pass in the ran array, center points and radius
    // we add buffers to accommodate for the font size
    // you can remove !valArray.includes(val) if you do not want the 50 numbers to not be repeated
    if (pointInCircle(ran[0], ran[1], circleWidth/2-posSize, circleWidth/2-posSize, circleWidth / 2 - posSize) && !valArray.includes(val)) {
      // you can remove valArray.push(val); if you do not want the 50 numbers to not be repeated
      valArray.push(val);
      // if the conditional returns true, 
      // create the element, style and append
      let randnum = document.createElement("p");
      randnum.classList.add('numStyle');
      randnum.style.color = randomColor();
      randnum.style.fontSize = randSize;
      randnum.textContent = val;
      randnum.style.position = 'absolute';
      randnum.style.top = `${ran[0]}px`;
      randnum.style.left = `${ran[1]}px`;
      circle.append(randnum);
      // iterate the counter
      count++;
    }
  }
}

addNumBtn.addEventListener('click', randNum)
html {
  --circle-width: 300px;
}

.circle {  
  aspect-ratio: 1;
  width: var(--circleWidth);
  background-color: black;
  border-radius: 50%;
  position: relative;
  overflow: hidden;
  padding: .5rem;
}


#addNumBtn {
  position: absolute;
  top: 0;
  left: 0;
}

.numStyle {
  font-family: "roboto", sans-serif;
}
//On Clicking button Click Me! I want to place all the random numbers inside the circle //together not one by one, at a time all numbers should be placed inside the circle by //clicking the button Click Me!
<div id="container"></div>
<div class="circle">
</div>
<button id="addNumBtn">Click Me!</button>

【讨论】:

  • 是的,正是我要找的……非常感谢……还有一件事,圆圈边界边有一些数字无法正确显示如何解决??
  • 因此,您要发布到的元素的border-radius 是 300 像素的 50%,即 150 像素。一些左/右/上/下是在边界半径之外的元素部分内创建的,因此如果您有一个顶部位置为 50 且左侧位置为 35 的数字元素,那么它将放置边界半径之外的那个元素。您需要逻辑来检查这些放置,然后将它们更正以放置在该元素边界半径的可见部分中。
  • 好的..,实际上我正在尝试制作一个游戏,其中用户必须从圆圈内的随机数中依次找到数字任何建议使其具有交互性...
  • @tpler 通过添加一个使用生成的点和圆心与半径来检查半径边界的函数,通过对代码进行一些调整来计算出边界半径,请参阅我的进一步的编辑和解释。
  • 您可以添加一个数组来保存 randomPos() x/y 坐标和随机大小,它可以用作您的缓冲区,每次迭代。然后是一个条件,检查每个新创建的 randomPos() 的位置与数组中的位置,看看你是否有冲突。
猜你喜欢
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 2019-06-15
  • 1970-01-01
  • 2020-10-11
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多