The following code below is what is needed to make a simple triangle. I want to keep the triangle in that exact position and add this to my canvas.

can = document.getElementById("gameCanvas");
var ctx = can.getContext("2d");
ctx.beginPath();
ctx.moveTo(1, 20);
ctx.lineTo(20, 100);
ctx.lineTo(70, 100);
ctx.closePath();
ctx.stroke();

If you run the code below, the triangle is there for a split second and then disappears. I need it to stay there along with the three equations. I created the function path(); in effort to keep the triangle positioned in the upper left corner. I am not sure how to keep the triangle there and do all of this.

<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript" src="//code.createjs.com/createjs-2013.09.25.combined.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>
#gameCanvas {
  background-color: lightyellow;
}
</style>
<div class="canvasHolder1">
  <div id="eqn1"> 3+3=<input type="text" id="q1" />
    </div>
  <div id="eqn2"> 3+2=<input type="text" id="q2" />
    </div>
  <div id="eqn3"> 5+2=<input type="text" id="q3" />
    </div>
  <canvas id="gameCanvas" width="600" height="600">Not supported</canvas>
<script type="text/javascript">

var m=1;

  var stage = new createjs.Stage("gameCanvas");
  var obj=[];
 
can = document.getElementById("gameCanvas");
var ctx = can.getContext("2d");
ctx.beginPath();
ctx.moveTo(1, 20);
ctx.lineTo(20, 100);
ctx.lineTo(70, 100);
ctx.closePath();
ctx.stroke();
function startGame() {
   
    obj[1] = new createjs.DOMElement(document.getElementById(`eqn${1}`));
    obj[2] = new createjs.DOMElement(document.getElementById(`eqn${2}`));
    stage.addChild(obj[1]);
    stage.addChild(obj[2]);
    createjs.Ticker.addEventListener("tick", handleTick);
    createjs.Ticker.setFPS(60);
    function handleTick(event){
    drop(1);
    drop(2);
    path();
    stage.update();
    }
}
 function drop(i){
      obj[1].x =40;
      obj[1].y =50;
      obj[2].x =300;
      obj[2].y =50;
 }
function path(){
ctx.x=1;
ctx.y=1;
}
</script>
<body onload="startGame();">
    <div >
  <canvas>This browser or document mode doesn't support canvas object.</canvas>
    </div>
</body>
</html>

Solution 1:

Take a look at this:

<!DOCTYPE html>
<html lang="en">

<head>
  <title>Math Game</title>
  <script src="//code.createjs.com/createjs-2013.09.25.combined.js"></script>
</head>

<body onload="startGame();">
  <div class="canvasHolder1">
    <div id="eqn1"> 3+3=<input type="text" id="q1" /></div>
    <div id="eqn2"> 3+2=<input type="text" id="q2" /></div>
    <div id="eqn3"> 5+2=<input type="text" id="q3" /></div>
    <canvas id="gameCanvas" width="600" height="200">Not supported</canvas>
  </div>

  <script>
    var stage = new createjs.Stage("gameCanvas");
    var can = document.getElementById("gameCanvas");
    var ctx = can.getContext("2d");
    var obj = [];

    function drawTriangle() {
      ctx.beginPath();
      ctx.moveTo(1, 20);
      ctx.lineTo(20, 100);
      ctx.lineTo(70, 100);
      ctx.closePath();
      ctx.stroke();
    }

    function startGame() {
      obj[1] = new createjs.DOMElement(document.getElementById("eqn1"));
      obj[1].x = 40;
      obj[1].y = 50;
      stage.addChild(obj[1]);

      obj[2] = new createjs.DOMElement(document.getElementById("eqn2"));
      obj[2].x = 300;
      obj[2].y = 50;
      stage.addChild(obj[2]);

      stage.update();
      drawTriangle();
    }
  </script>
</body>

</html>

You can see I created a new function drawTriangle it will be called at the end of your startGame that way the triangle is the last item drawn in the canvas.

I'm not sure why you needed the Ticker so I remove it, same with the other functions, they did not make much sense to me, no need for what you are trying to accomplish at the moment.


Now to your problem... in my implementation I have the drawTriangle as the last action in the startGame, but if we change the order, to something like this:

      drawTriangle();
      stage.update();

The triangle disappears!

My educated guess is that stage.update() clears the entire canvas and draws what it "knows" the triangle drawing is happening outside the stage so we need to always draw it after.

Looking at the code documentation for update:
https://www.createjs.com/docs/easeljs/files/easeljs_display_Stage.js.html#l349
there is an if statement if (this.autoClear) { that does exactly what we are seeing in your sample, and the default value of autoClear is true:
https://www.createjs.com/docs/easeljs/classes/Stage.html#property_autoClear


Also worth pointing out... there is a native createjs way to draw lines:

  • https://createjs.com/docs/easeljs/classes/Graphics.html#method_moveTo
  • https://createjs.com/docs/easeljs/classes/Graphics.html#method_lineTo

There is nothing wrong with your approach, you are using both createjs and directly drawing in the canvas via getContext("2d") you just have to plan accordingly, but my recommendation, if there is a native approach I would stick with that, here is a sample code:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Math Game</title>
  <script src="//code.createjs.com/createjs-2013.09.25.combined.js"></script>
</head>

<body onload="startGame();">
  <div class="canvasHolder1">
    <div id="eqn1"> 3+3=<input type="text" id="q1" /></div>
    <canvas id="gameCanvas" width="600" height="160">Not supported</canvas>
  </div>

  <script>
    function startGame() {
      var stage = new createjs.Stage("gameCanvas");
      var eqn1 = new createjs.DOMElement(document.getElementById("eqn1"));
      eqn1.x = eqn1.y = 50;
      stage.addChild(eqn1);
      
      var triangle = new createjs.Shape();
      triangle.graphics.beginStroke("black")
      triangle.graphics.moveTo(1, 20);
      triangle.graphics.lineTo(20, 100);
      triangle.graphics.lineTo(70, 100);
      triangle.graphics.lineTo(1, 20);
      stage.addChild(triangle);

      stage.update();
    }
  </script>
</body>
</html>