为什么 Canvas 元素在 clearReact 之后绘制我的旧函数?

Why Canvas element draw my old function after clearReact?

提问人:Grzegorz 提问时间:11/6/2023 最后编辑:Helder SepulvedaGrzegorz 更新时间:11/6/2023 访问量:36

问:

我不知道该怎么办。我清除了我的画布,但我的函数没有在图形上重绘,所以我找不到问题。我在调试器模式下看到clearReact()函数中发生了一些不好的事情。正是当我再次绘制Net()时。我的程序是否仍然记得我的函数并将其添加到图形中?如何?

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth - 30;
canvas.height = window.innerHeight;
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
let rangex = canvas.width / 40;
let rangey = canvas.height / 20
let number = -20;
truthTableRPN = {
  '(': 0,
  '+': 1,
  '-': 1,
  ')': 1,
  '*': 2,
  '/': 2,
  '%': 2,
  '^': 3
}
arrayFunction = []
stos = []

drawNet()
drawNumericalInterval()
drawAxes()
ctx.translate(centerX, centerY);

function drawAxes() {
  ctx.beginPath();
  ctx.strokeStyle = "black";
  ctx.moveTo(0, centerY);
  ctx.lineTo(canvas.width, centerY);
  ctx.moveTo(centerX, 0);
  ctx.lineTo(centerX, canvas.height);
  ctx.stroke();
  ctx.closePath()
}

function drawNumericalInterval() {
  for (i = 0; i <= canvas.width; i += rangex) {
    ctx.beginPath();
    ctx.fillText(number, i, centerY - 9)
    number++
    ctx.textAlign = "center"
    ctx.textBaseline = "middle"
    ctx.font = "10px Arial"
    ctx.strokeStyle = "black";
    ctx.moveTo(i, centerY - 5);
    ctx.lineTo(i, centerY + 5);
    ctx.stroke();
  }

  number = 10

  for (i = 0; i <= canvas.height; i += rangey) {
    ctx.beginPath();
    ctx.fillText(number, centerX - 9, i)
    number--
    ctx.textAlign = "center"
    ctx.textBaseline = "middle"
    ctx.font = "10px Arial"
    ctx.strokeStyle = "black";
    ctx.moveTo(centerX - 5, i);
    ctx.lineTo(centerX + 5, i);
    ctx.stroke();
  }
}

function drawNet() {
  for (i = 0; i <= canvas.width; i += rangex) {
    ctx.moveTo(i, 0);
    ctx.strokeStyle = "rgba(180, 180, 180, 0.2)";
    ctx.lineTo(i, canvas.height);
    ctx.stroke();
    ctx.closePath()
  }
  for (i = 0; i <= canvas.height; i += rangey) {
    ctx.moveTo(0, i);
    ctx.strokeStyle = "rgba(180, 180, 180, 0.2)";
    ctx.lineTo(canvas.width, i);
    ctx.stroke();
    ctx.closePath()
  }
}

function getValue(znak) {
  let returnvalue = truthTableRPN[znak] ?? -1
  return returnvalue
}

function createRPNUserFunction() {
  const myFunction = document.querySelector("#myFunction").value
  const check = document.querySelector(".siemka")
  myFunction.replace(/\s/g, '');
  charArray = myFunction.match(/([\w\d]+)|[-\+\*\/\^\(\)]/g)

  for (i = 0; i < charArray.length; i++) {
    console.log(stos)
    console.log(arrayFunction)

    char = charArray[i]
    if (/[a-z0-9]/.test(char)) {
      arrayFunction.push(char)
    } else if (i == 0 && char == '-') {
      stos.push(char)
      arrayFunction.push(0)
    } else if (stos[stos.length - 1] == '(' && char == '-') {
      stos.push(char)
      arrayFunction.push(0)
    } else if (char === ')') {
      while (stos[stos.length - 1] !== '(') {
        arrayFunction.push(stos[stos.length - 1])
        stos.pop()
      }
      stos.pop()
    } else if (char == '+' || char == '-' || char == '/' || char == '*' || char == '^' || char == '%') {
      while (getValue(char) <= getValue(stos[stos.length - 1])) {
        arrayFunction.push(stos[stos.length - 1])
        stos.pop()
      }
      stos.push(char)
    } else stos.push(char)
  }
  for (i = 0; i <= stos.length; i++) {
    arrayFunction.push(stos.pop())
  }
  stos = ''
  for (var i = 0; i < arrayFunction.length; i++) {
    if (arrayFunction[i] == '^') arrayFunction[i] = arrayFunction[i].replace('^', "**");
  }

  return arrayFunction

  // check.innerHTML += "pokaż stos: "+stos+'<br>'
  // check.innerHTML += "pokaż wyjście: "+arrayFunction+'<br>'
  // arrayFunction =[]
  // stos =[]
}

function changeValuesOfX(number, func) {
  let temparrayFunction = func.slice();
  for (i = 0; i < temparrayFunction.length; i++) {
    if (temparrayFunction[i] == 'x') temparrayFunction[i] = number;
  }
  return temparrayFunction
}

function countYParameterFunction(func) {
  stos = []

  for (i = 0; i < func.length; i++) {
    if (/[0-9]/.test(func[i])) {
      stos.push(func[i])
    } else {
      a = stos[stos.length - 1]
      stos.pop()
      b = stos[stos.length - 1]
      stos.pop()
      stos.push(mathCalc(Number(b), Number(a), func[i]))
    }
  }
  return stos.pop()
}

function mathCalc(firstVar, secondVar, operator) {
  switch (operator) {
    case '**':
      return result = firstVar ** secondVar
      break;
    case '%':
      return result = firstVar % secondVar
      break;
    case '*':
      return result = firstVar * secondVar
      break;
    case '/':
      return result = firstVar / secondVar
      break;
    case '+':
      return result = firstVar + secondVar
      break;
    case '-':
      return result = firstVar - secondVar
      break;
  }
}

function drawFunctionGraph(arrayFunction) {
  counter = 0
  let color = document.querySelector('#color').value;
  let rangex = canvas.width / 40;
  let rangey = canvas.height / 20
  let maxPlusX = centerX
  let maxMinusY = -centerY
  let maxMinusX = -centerX
  let maxPlusY = centerY
  for (let number = -20; number <= 20; number += 0.1) {
    array = changeValuesOfX(number, arrayFunction)
    y = (countYParameterFunction(array))
    x = number * rangex
    y *= -rangey
    console.log(x, y);

    if (counter == 0 && y >= maxMinusY && y <= maxPlusY && x > maxMinusX && x < maxPlusX) {
      ctx.beginPath()
      ctx.strokeStyle = color
      ctx.moveTo(tempX, tempY);
      ctx.lineTo(x, y)
      ctx.stroke()
      i++
      counter++
    } else if (counter > 0) {
      ctx.strokeStyle = color
      ctx.lineTo(x, y)
      ctx.stroke()
      ctx.moveTo(x, y);
      i++
      counter++
    } else {
      tempX = x
      tempY = y
      continue
    }

    ctx.closePath()
  }
}

function clearReact() {
  ctx.translate(-centerX, -centerY);
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  number = -20;
  drawNet()
  drawNumericalInterval()
  drawAxes()
  ctx.translate(centerX, centerY);
}

function createNewGraphFunction() {
  arrayFunction = createRPNUserFunction()
  drawFunctionGraph(arrayFunction)
  arrayFunction = []
  stos = []
}
<canvas id="canvas"></canvas>

JavaScript Math Canvas 图形

评论

0赞 Helder Sepulveda 11/6/2023
something bad happened in the clearReact() function请添加有关您在控制台中看到的内容的更多详细信息

答:

0赞 Helder Sepulveda 11/6/2023 #1

在您的代码中,没有任何东西在调用该函数,因此我添加了一个调用它的按钮。clearReact

我做了一些更改:

  • 删除不需要的(我们不需要到处翻译,那只是令人困惑)
    ctx.translate
  • 添加到 drawNet
    (这可能是您“仍然记得”问题的根本原因)
    ctx.beginPath
  • 添加了一个新函数来画一个圆圈,以确保一切都清除

您可以测试下面的代码,我没有看到任何错误

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth - 30;
canvas.height = window.innerHeight;
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
let rangex = canvas.width / 40;
let rangey = canvas.height / 20
let number = -20;
truthTableRPN = {
  '(': 0,
  '+': 1,
  '-': 1,
  ')': 1,
  '*': 2,
  '/': 2,
  '%': 2,
  '^': 3
}
arrayFunction = []
stos = []

drawNet()
drawNumericalInterval()
drawAxes()

function drawAxes() {
  ctx.beginPath();
  ctx.strokeStyle = "black";
  ctx.moveTo(0, centerY);
  ctx.lineTo(canvas.width, centerY);
  ctx.moveTo(centerX, 0);
  ctx.lineTo(centerX, canvas.height);
  ctx.stroke();
  ctx.closePath()
}

function drawNumericalInterval() {
  for (i = 0; i <= canvas.width; i += rangex) {
    ctx.beginPath();
    ctx.fillText(number, i, centerY - 9)
    number++
    ctx.textAlign = "center"
    ctx.textBaseline = "middle"
    ctx.font = "10px Arial"
    ctx.strokeStyle = "black";
    ctx.moveTo(i, centerY - 5);
    ctx.lineTo(i, centerY + 5);
    ctx.stroke();
  }

  number = 10

  for (i = 0; i <= canvas.height; i += rangey) {
    ctx.beginPath();
    ctx.fillText(number, centerX - 9, i)
    number--
    ctx.textAlign = "center"
    ctx.textBaseline = "middle"
    ctx.font = "10px Arial"
    ctx.strokeStyle = "black";
    ctx.moveTo(centerX - 5, i);
    ctx.lineTo(centerX + 5, i);
    ctx.stroke();
  }
}

function drawNet() {
  ctx.beginPath()
  for (i = 0; i <= canvas.width; i += rangex) {
    ctx.moveTo(i, 0);
    ctx.strokeStyle = "rgba(180, 180, 180, 0.2)";
    ctx.lineTo(i, canvas.height);
    ctx.stroke();
    ctx.closePath()
  }
  for (i = 0; i <= canvas.height; i += rangey) {
    ctx.moveTo(0, i);
    ctx.strokeStyle = "rgba(180, 180, 180, 0.2)";
    ctx.lineTo(canvas.width, i);
    ctx.stroke();
    ctx.closePath()
  }
}

function getValue(znak) {
  let returnvalue = truthTableRPN[znak] ?? -1
  return returnvalue
}

function createRPNUserFunction() {
  const myFunction = document.querySelector("#myFunction").value
  const check = document.querySelector(".siemka")
  myFunction.replace(/\s/g, '');
  charArray = myFunction.match(/([\w\d]+)|[-\+\*\/\^\(\)]/g)

  for (i = 0; i < charArray.length; i++) {
    console.log(stos)
    console.log(arrayFunction)

    char = charArray[i]
    if (/[a-z0-9]/.test(char)) {
      arrayFunction.push(char)
    } else if (i == 0 && char == '-') {
      stos.push(char)
      arrayFunction.push(0)
    } else if (stos[stos.length - 1] == '(' && char == '-') {
      stos.push(char)
      arrayFunction.push(0)
    } else if (char === ')') {
      while (stos[stos.length - 1] !== '(') {
        arrayFunction.push(stos[stos.length - 1])
        stos.pop()
      }
      stos.pop()
    } else if (char == '+' || char == '-' || char == '/' || char == '*' || char == '^' || char == '%') {
      while (getValue(char) <= getValue(stos[stos.length - 1])) {
        arrayFunction.push(stos[stos.length - 1])
        stos.pop()
      }
      stos.push(char)
    } else stos.push(char)
  }
  for (i = 0; i <= stos.length; i++) {
    arrayFunction.push(stos.pop())
  }
  stos = ''
  for (var i = 0; i < arrayFunction.length; i++) {
    if (arrayFunction[i] == '^') arrayFunction[i] = arrayFunction[i].replace('^', "**");
  }

  return arrayFunction

  // check.innerHTML += "pokaż stos: "+stos+'<br>'
  // check.innerHTML += "pokaż wyjście: "+arrayFunction+'<br>'
  // arrayFunction =[]
  // stos =[]
}

function changeValuesOfX(number, func) {
  let temparrayFunction = func.slice();
  for (i = 0; i < temparrayFunction.length; i++) {
    if (temparrayFunction[i] == 'x') temparrayFunction[i] = number;
  }
  return temparrayFunction
}

function countYParameterFunction(func) {
  stos = []

  for (i = 0; i < func.length; i++) {
    if (/[0-9]/.test(func[i])) {
      stos.push(func[i])
    } else {
      a = stos[stos.length - 1]
      stos.pop()
      b = stos[stos.length - 1]
      stos.pop()
      stos.push(mathCalc(Number(b), Number(a), func[i]))
    }
  }
  return stos.pop()
}

function mathCalc(firstVar, secondVar, operator) {
  switch (operator) {
    case '**':
      return result = firstVar ** secondVar
      break;
    case '%':
      return result = firstVar % secondVar
      break;
    case '*':
      return result = firstVar * secondVar
      break;
    case '/':
      return result = firstVar / secondVar
      break;
    case '+':
      return result = firstVar + secondVar
      break;
    case '-':
      return result = firstVar - secondVar
      break;
  }
}

function drawFunctionGraph(arrayFunction) {
  counter = 0
  let color = document.querySelector('#color').value;
  let rangex = canvas.width / 40;
  let rangey = canvas.height / 20
  let maxPlusX = centerX
  let maxMinusY = -centerY
  let maxMinusX = -centerX
  let maxPlusY = centerY
  for (let number = -20; number <= 20; number += 0.1) {
    array = changeValuesOfX(number, arrayFunction)
    y = (countYParameterFunction(array))
    x = number * rangex
    y *= -rangey
    console.log(x, y);

    if (counter == 0 && y >= maxMinusY && y <= maxPlusY && x > maxMinusX && x < maxPlusX) {
      ctx.beginPath()
      ctx.strokeStyle = color
      ctx.moveTo(tempX, tempY);
      ctx.lineTo(x, y)
      ctx.stroke()
      i++
      counter++
    } else if (counter > 0) {
      ctx.strokeStyle = color
      ctx.lineTo(x, y)
      ctx.stroke()
      ctx.moveTo(x, y);
      i++
      counter++
    } else {
      tempX = x
      tempY = y
      continue
    }

    ctx.closePath()
  }
}

function clearReact() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  number = -20;
  drawNet()
  drawNumericalInterval()
  drawAxes()
}

function createNewGraphFunction() {
  arrayFunction = createRPNUserFunction()
  drawFunctionGraph(arrayFunction)
  arrayFunction = []
  stos = []
}

function drawCircle() {
  let x = (Math.random()- 0.5) * 100
  let y = (Math.random()- 0.5) * 100
  ctx.moveTo(centerX + x + 40, centerY + y);
  ctx.arc(centerX + x, centerY + y, 40, 0, 2 * Math.PI)
  ctx.stroke()
}
<button onclick="clearReact()">clearReact</button>
<button onclick="drawCircle()">drawCircle</button>
<br/>
<canvas id="canvas"></canvas>

评论

0赞 Grzegorz 11/6/2023
我的代码中有这个 HTML: 所以我有 smh 什么调用我的 func<form class=“menu” onsubmit=“return false”> <label> Podaj wartość funkcji: </label> <input type=“text” placeholder=“Przykładowy format: x^2+4*x+4” id=“myFunction”> <label>Wybierz kolor Funkcji:</label> <input type=“color” id=“color”><br> <div class=“buttons”> <button class=“bttn”onclick=“createNewGraphFunction()”>Narysuj</button> <button class=“bttn” onclick=“clearReact()”>Zmarz</button> </div> </form>
0赞 Helder Sepulveda 11/6/2023
@Grzegorz您应该在问题中而不是在评论中添加它
0赞 Helder Sepulveda 11/6/2023
@Grzegorz 您是否尝试过我建议的更正,添加?beginPath
0赞 Grzegorz 11/7/2023
是的,我试过了,在调用函数 clearReact() 后,Canvas 清除了除一个函数之外的所有函数。它仍然停留在屏幕上,但它们像石网一样是灰色的。顺便说一句,我不知道把我的答案放在哪里,因为我第一次😅使用堆栈
0赞 Grzegorz 11/7/2023
没关系!它有效,我必须重新加载我的页面。更改未加载。drawNet 函数中的 ctx.beginPath() 是必需的