JavaScript Canvas: Using the lineTo() method in drawing lines

I am embarking on a journey to learn Javascript!

Can someone guide me on how to link a variable to the current xy coordinates in order to utilize relative positions for drawing lines? My goal is to create an etch-a-sketch using keyboard inputs - specifically the up, down, left, and right arrow keys - with a combination of JS, CSS, and HTML.

Appreciate any assistance!

window.addEventListener("keydown", keyd);
function keyd(event) {
  var etchMain = document.getElementById('etchMain');
  var etchContext = etchMain.getContext('2d');
  var key = event.keyCode;
  **var etchContextPositionX;
  var etchContextPositionY;**
  if (key == 37) {
    // left arrow
    if (etchMain.toDataURL() == document.getElementById('blank').toDataURL()) {
      etchContext.beginPath();
      etchContext.moveTo(etchMain.width / 2, etchMain.height / 2);
      // specific drawing logic for left arrow key goes here
    }
    else {

    }
  }
  if (key == 38) {
    // up arrow
    if (etchMain.toDataURL() == document.getElementById('blank').toDataURL()) {
      etchContext.beginPath();
      etchContext.moveTo(etchMain.width / 2, etchMain.height / 2);
      // specific drawing logic for up arrow key goes here
    }
    else {

    }
  }
  if (key == 39) {
    // right arrow
    if (etchMain.toDataURL() == document.getElementById('blank').toDataURL()) {
      etchContext.beginPath();
      etchContext.moveTo(etchMain.width / 2, etchMain.height / 2);
      // specific drawing logic for right arrow key goes here
    }
    else {

    }
  }
  if (key == 40) {
    // down arrow
    if (etchMain.toDataURL() == document.getElementById('blank').toDataURL()) {
      etchContext.beginPath();
      etchContext.moveTo(etchMain.width / 2, etchMain.height / 2);
      // specific drawing logic for down arrow key goes here

    }
    else {

    }
  }
}
function clearCanvas() {
  var etchMain = document.getElementById('etchMain');
  var etchContext = etchMain.getContext('2d');
  etchContext.clearRect(0, 0, etchMain.width, etchMain.height);
}

Answer №1

After finding your idea intriguing, I decided to implement a basic version of it for fun. Press "run snippet" and then click on the canvas box to focus that frame. The event handler will prevent window scrolling and instead use arrow inputs to increment or decrement the positions of x and y, allowing you to draw from there. You can also clear the canvas by hitting the space bar!

The key element you were missing was storing the positions of x and y outside of the event handler. By utilizing the difference between the previous state of these values, you can effectively draw lines on your canvas:

var pos = {
  x: 50,
  y: 50,
}

var etchMain = document.getElementById('etchMain');
var etchContext = etchMain.getContext('2d');

window.addEventListener('keydown', function(e) {
  e.preventDefault();
  
  if(e.keyCode === 32) {
    clearCanvas();
  } else {

    etchContext.beginPath();
    etchContext.moveTo(pos.x, pos.y);

    switch (e.keyCode) {
      case 37:
        pos.x--;
        break;
      case 38:
        pos.y--;
        break;
      case 39:
        pos.x++;
        break;
      case 40:
        pos.y++;
        break;
      default:
        break;
      }

      etchContext.lineTo(pos.x, pos.y);
      etchContext.stroke();
    }
});

function clearCanvas() {
  etchContext.clearRect(0, 0, etchMain.width, etchMain.height);
}
#etchMain {
  border: 1px solid black;
}
<canvas id="etchMain" height="100" width="100" />

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Setting the height of the Angular UI modal relative to the height of the window

I am currently working on a modal that contains a significant amount of text. My main goal is to limit the height of the modal to the size of the window, while also adding a scrollbar to the content area positioned above the OK button. Check out the Plunk ...

How to apply props conditionally in VueJS?

I have a component called blogPost (Component A) that is imported in another component named B. When a button in Component B is clicked, Component A opens in a modal. There are two different use cases for this scenario. 1. One case requires passing 2 prop ...

Next.js - Anticipated that the server HTML would include a corresponding <div> within <div> tag

For a live demonstration, please click here In my current project, I am experimenting with creating a simple layout that adjusts based on the user's screen size. Specifically, on mobile devices, only the latest posts should be displayed. On desktops, ...

Unable to utilize first-child CSS to establish the display

I'm currently using WordPress and it's generating the following code: <aside class="left-hand-column"> <div class="textwidget"> <p></p> ...1 <div class="pdf-download"> <p> ... 2 <a href="http ...

Leveraging $http in Angular without the need for $scope

When using the syntax <div ng-controller="BuildingsCtrl as bc"> to avoid using $scope (as mentioned here), how should I incorporate $http? In other words, how can I refactor the following code without relying on $scope? angular.module('atlasAn ...

A continuous loop of text is displayed in a slideshow format, with different image files used for the navigation buttons "back", "stop", and "forward"

I am in need of a unique slide show that displays text exclusively attached to CSS, with image files for the navigation buttons. I have been searching for days without success, as most options available are for image slideshows and not suitable for my text ...

Is it mandatory for the npm install command to only be compatible with Node.js for the script

I've encountered an API that provides a JS SDK, and the instructions on its GitHub page suggest using npm install. My question is whether I need to have Node.js in order to use this SDK since it seems to be designed for it, or if I can simply work wit ...

Retrieve a specific nested key using its name

I am working with the following structure: const config = { modules: [ { debug: true }, { test: false } ] } My goal is to create a function that can provide the status of a specific module. For example: getStatus("debug") While I can access the array ...

Exclude a specific tag from a div in JavaScript

I need help selecting the text within an alert in JavaScript, excluding the <a> tag... <div id="addCompaniesModal" > <div class="alertBox costumAlertBox" style="display:inline-block;"> <div class="alert alert-block alert- ...

Having trouble with running npm start on the command prompt? An error message is popping up as displayed in the image?

When I try to type npm-start, an error related to the image appears. It seems to be occurring in my react-app that was created with create-react-app. Interestingly, I created another app with the same process, yet the error persists and causes localhost: ...

Incorporating navigation controls into a modal window

I have successfully created a sign-in modal, but now I'm looking to include buttons at the top. One button should redirect users to register/sign up, and the other button should lead them back to the sign-in modal, as shown in the image I've link ...

Issue with fluid layout in CSS - Unable to specify height in pixels and minimum height property not functioning as expected

While working on a liquid layout, I have set all my width and height values in percentages. However, during the design process, I needed to check how my CSS was rendering so I temporarily set the height in pixels. Eventually, the height in percentage wil ...

Is it possible to add a timer to a fade effect?

Is it possible to create a fade effect timer without using jQuery? I want text1 to fade out after 5 seconds, then have text2 appear, followed by text3 fading in. Unfortunately, my expertise does not extend to jQuery. For the task at hand, let's assum ...

Issues with a top navigation bar

I'm currently working on customizing a header menu to my liking but have limited experience with CSS. The header menu consists of two main items, each with a dropdown. I envision the first menu item to look like this upon hover: https://i.sstatic.net ...

I'm looking to customize my d3.js Bar Graph by changing the color of each bar individually and adding a Scale for them. How can I

I am currently working on constructing a graph that illustrates the data for the Amount of Resources utilized Per Project by creating a bar graph. I am aiming to customize the colors of the bars so that each one has its own unique color. Currently, the col ...

Centering an item within a dropdown navigation bar

Hey there, I'm currently facing a challenge with centering an image within my dropdown bar. My goal is to have it float to the right and be centered, but it's not cooperating. Here's the code snippet I'm working with: <!DOCTYPE htm ...

Transform the object into an array of JSON with specified keys

Here is a sample object: { labels: ["city A", "city B"], data: ["Abc", "Bcd"] }; I am looking to transform the above object into an array of JSON like this: [ { labels: "city A", data: "Abc" }, { labels: "city B", data: "Bcd" }, ]; ...

How to vertically align content using Zurb Foundation's equalizer feature?

I am currently utilizing Zurb Foundation 5 along with the equalizer component. In a scenario where I have three columns of equal width, I am aiming to achieve vertical center alignment for the content (text) in the middle column and vertical bottom alignme ...

What is the best way to display the user login in the center of a page with all necessary controls

Challenge How can the user login be displayed in the center of the page? Additional Information The current layout displays user login data on the left-hand side. I am looking to have the user login data centralized on the page, which includes labels f ...

I'm having trouble getting my application to output to the console. What could be the issue?

In my cr-route.js file, I have a function that ensures the user is authenticated before displaying their name. module.exports = function (app, passport) { // ===================================== // HOME PAGE (with login links) ======== // == ...