最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - my canvas drawing app won't work on mobile - Stack Overflow

programmeradmin0浏览0评论

I've been learning about HTML canvas lately and made a simple drawing app that works perfect on desktop. But on mobile I can't get a continuous line to draw, only single dots. any idea what I'm doing wrong? link to my codepen build

let color = "black";
let strokeSize = 10;

function changeColorAndSize(data, width) {
  color = data;
  strokeSize = width;
}
window.addEventListener("load", () => {
  const canvas = document.querySelector("#canvas");
  const ctx = canvas.getContext("2d");

  //resizing
  canvas.height = window.innerHeight;
  canvas.width = window.innerWidth;

  //variables
  let painting = false;

  //functions
  function startPosition(e) {
    painting = true;
    draw(e);
  }

  function endPosition() {
    painting = false;
    ctx.beginPath();
  }

  function draw(e) {
    if (!painting) {
      return;
    }
    e.preventDefault();
    ctx.lineWidth = strokeSize;
    ctx.lineCap = "round";
    ctx.lineTo(e.clientX, e.clientY);
    ctx.stroke();
    ctx.strokeStyle = color;
    ctx.beginPath();
    ctx.moveTo(e.clientX, e.clientY);
  }

  //event listeners
  canvas.addEventListener("mousedown", startPosition);
  canvas.addEventListener("touchstart", startPosition);
  canvas.addEventListener("mouseup", endPosition);
  canvas.addEventListener("touchend", endPosition);
  canvas.addEventListener("mousemove", draw);
  canvas.addEventListener("touchmove", draw);
});

I've been learning about HTML canvas lately and made a simple drawing app that works perfect on desktop. But on mobile I can't get a continuous line to draw, only single dots. any idea what I'm doing wrong? link to my codepen build

https://codepen.io/ryan-rigley/pen/oNXEvwm?fbclid=IwAR0rekoc1wcT2d4of0vCW32F0bzQDX1kW8DsJKiDq8t0ymLky1IkHyu8ozc

let color = "black";
let strokeSize = 10;

function changeColorAndSize(data, width) {
  color = data;
  strokeSize = width;
}
window.addEventListener("load", () => {
  const canvas = document.querySelector("#canvas");
  const ctx = canvas.getContext("2d");

  //resizing
  canvas.height = window.innerHeight;
  canvas.width = window.innerWidth;

  //variables
  let painting = false;

  //functions
  function startPosition(e) {
    painting = true;
    draw(e);
  }

  function endPosition() {
    painting = false;
    ctx.beginPath();
  }

  function draw(e) {
    if (!painting) {
      return;
    }
    e.preventDefault();
    ctx.lineWidth = strokeSize;
    ctx.lineCap = "round";
    ctx.lineTo(e.clientX, e.clientY);
    ctx.stroke();
    ctx.strokeStyle = color;
    ctx.beginPath();
    ctx.moveTo(e.clientX, e.clientY);
  }

  //event listeners
  canvas.addEventListener("mousedown", startPosition);
  canvas.addEventListener("touchstart", startPosition);
  canvas.addEventListener("mouseup", endPosition);
  canvas.addEventListener("touchend", endPosition);
  canvas.addEventListener("mousemove", draw);
  canvas.addEventListener("touchmove", draw);
});

Share Improve this question asked Mar 15, 2020 at 1:33 Ryan RigleyRyan Rigley 751 silver badge5 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 8

mousemove and touchmove events have clientX and clientY differently. For mousemove event (e):

X = e.clientX and Y = e.clientY

And for touchmove event:

X = e.touches[0].clientX and Y = e.touches[0].clientY

Thus, you need to use conditional statement to find the type of event and use find X and Y accordingly. The updated code can be found below and on codepen

let color = "black";
let strokeSize = 10;

function changeColorAndSize(data, width) {
  color = data;
  strokeSize = width;
}
window.addEventListener("load", () => {
  const canvas = document.querySelector("#canvas");
  const ctx = canvas.getContext("2d");

  //resizing
  canvas.height = window.innerHeight;
  canvas.width = window.innerWidth;

  //variables
  let painting = false;

  //functions
  function startPosition(e) {
    painting = true;
    draw(e);
  }

  function endPosition() {
    painting = false;
    ctx.beginPath();
  }

  function draw(e) {
    if (!painting) {
      return;
    }
    
    e.preventDefault();
    ctx.lineWidth = strokeSize;
    ctx.lineCap = "round";
 
    // ctx.lineTo(e.clientX, e.clientY);
    if (e.type == 'touchmove'){
      ctx.lineTo(e.touches[0].clientX, e.touches[0].clientY);
    } else if (e.type == 'mousemove'){
      ctx.lineTo(e.clientX, e.clientY);
    }
      
    ctx.stroke();
    ctx.strokeStyle = color;
    ctx.beginPath();
    
    // ctx.moveTo(e.clientX, e.clientY);
    if (e.type == 'touchmove'){
      ctx.moveTo(e.touches[0].clientX, e.touches[0].clientY);
    } else if (e.type == 'mousemove'){
      ctx.moveTo(e.clientX, e.clientY);
    }
  }

  //event listeners
  canvas.addEventListener("mousedown", startPosition);
  canvas.addEventListener("touchstart", startPosition);
  canvas.addEventListener("mouseup", endPosition);
  canvas.addEventListener("touchend", endPosition);
  canvas.addEventListener("mousemove", draw);
  canvas.addEventListener("touchmove", draw);
});
body{
  margin:0;
  padding:0;
}
#colorButtonBox{
  position:absolute;
  background:rgb(210,210,210);
  padding:5px;
  margin:5px;
  border-radius:10px;
  bottom:0;
}
#colorButton {
  transition: .1s linear;
  position: relative;
  float:left;
  margin:5px;
  border-radius:5px;
  width: 40px;
  height: 40px;
  z-index: 3;
}
#eraserButton {
  transition: .1s linear;
  position: relative;
  float:left;
  margin:5px;
  border-radius:50%;
  width: 40px;
  height: 40px;
  z-index: 3;
  background:white;
}
#eraserButton:hover {
  width:30px;
  height:30px;
  margin:10px;
}
#colorButton:hover {
  transition: .1s linear;
  width:45px;
  height:45px;
  margin:2.5px;
}

.black {
  background:black;
}
.blue {
  background:blue;
}
.red {
  background:red;
}
.green {
  background:green;
}
.yellow {
  background:yellow;
}
<META name="viewport" content="initial-scale=0.66, user-scalable=no">
<body>
  <div id="colorButtonBox">
    <div id="colorButton" class="black" onclick='changeColorAndSize("black",10)'></div>
    <div id="colorButton" class="red" onclick="changeColorAndSize('red',10)"></div>
    <div id="colorButton" class="green" onclick="changeColorAndSize('green',10)"></div>
    <div id="colorButton" class="blue" onclick="changeColorAndSize('blue',10)"></div>
    <div id="colorButton" class="yellow" onclick="changeColorAndSize('yellow',10)"></div>
    <div id="eraserButton" onclick="changeColorAndSize('white',100)"></div>
  </div>
  
  <canvas id="canvas"></canvas>

</body>

I'm not sure what you mean by your app isn't working on mobile apps, so I'm going to make the assumption that you mean it isn't drawing.

My answer is based on a question answered here. It takes the touchmove event and manually creates a mousemove event with a clientX based on the touch clientX and a clientY the same way.

Here is the new code pen

Below is the altered code:

let color = "black";
let strokeSize = 10;

function changeColorAndSize(data, width) {
  color = data;
  strokeSize = width;
}
window.addEventListener("load", () => {
  const canvas = document.querySelector("#canvas");
  const ctx = canvas.getContext("2d");

  //resizing
  canvas.height = window.innerHeight;
  canvas.width = window.innerWidth;

  //variables
  let painting = false;

  //functions
  function startPosition(e) {
    painting = true;
    draw(e);
  }

  function endPosition() {
    painting = false;
    ctx.beginPath();
  }

  function draw(e) {
    if (!painting) {
      return;
    }
    e.preventDefault();
    e.stopPropagation();
    ctx.lineWidth = strokeSize;
    ctx.lineCap = "round";
    ctx.lineTo(e.clientX, e.clientY);
    ctx.stroke();
    ctx.strokeStyle = color;
    ctx.beginPath();
    ctx.moveTo(e.clientX, e.clientY);
  }

  //event listeners
  canvas.addEventListener("mousedown", startPosition);
  canvas.addEventListener("touchstart", startPosition);
  canvas.addEventListener("mouseup", endPosition);
  canvas.addEventListener("touchend", endPosition);
  canvas.addEventListener("mousemove", draw);
  canvas.addEventListener("touchmove", function (e) {
  var touch = e.touches[0];
  var mouseEvent = new MouseEvent("mousemove", {
    clientX: touch.clientX,
    clientY: touch.clientY
  });
  draw(mouseEvent);
}, false);
});
body{
  margin:0;
  padding:0;
}
#colorButtonBox{
  position:absolute;
  background:rgb(210,210,210);
  padding:5px;
  margin:5px;
  border-radius:10px;
  bottom:0;
}
#colorButton {
  transition: .1s linear;
  position: relative;
  float:left;
  margin:5px;
  border-radius:5px;
  width: 40px;
  height: 40px;
  z-index: 3;
}
#eraserButton {
  transition: .1s linear;
  position: relative;
  float:left;
  margin:5px;
  border-radius:50%;
  width: 40px;
  height: 40px;
  z-index: 3;
  background:white;
}
#eraserButton:hover {
  width:30px;
  height:30px;
  margin:10px;
}
#colorButton:hover {
  transition: .1s linear;
  width:45px;
  height:45px;
  margin:2.5px;
}

.black {
  background:black;
}
.blue {
  background:blue;
}
.red {
  background:red;
}
.green {
  background:green;
}
.yellow {
  background:yellow;
}
<META name="viewport" content="initial-scale=0.66, user-scalable=no">
<body>
  <div id="colorButtonBox">
    <div id="colorButton" class="black" onclick='changeColorAndSize("black",10)'></div>
    <div id="colorButton" class="red" onclick="changeColorAndSize('red',10)"></div>
    <div id="colorButton" class="green" onclick="changeColorAndSize('green',10)"></div>
    <div id="colorButton" class="blue" onclick="changeColorAndSize('blue',10)"></div>
    <div id="colorButton" class="yellow" onclick="changeColorAndSize('yellow',10)"></div>
    <div id="eraserButton" onclick="changeColorAndSize('white',100)"></div>
  </div>
  
  <canvas id="canvas"></canvas>

</body>

I hope this helps, if you have any more questions please don't hesitate to ask : )

发布评论

评论列表(0)

  1. 暂无评论