What steps should I take to make the code in jsfiddle functional on my Visual Studio Code platform?

const canvasEle = document.getElementById('drawing-container');
const canvasPad = document.getElementById('pad');
const toolbar = document.getElementById('toolbar');
const context = canvasEle.getContext('2d');
const padContext = canvasPad.getContext('2d');

const canvasOffsetX = canvas.offsetLeft;
const canvasOffsetY = canvas.offsetTop;

canvas.width = window.innerWidth - canvasOffsetX;
canvas.height = window.innerHeight - canvasOffsetY;

let startPosition = {
  x: 0,
  y: 0
};
let lineCoordinates = {
  x: 0,
  y: 0
};
let isDrawStart = false;

const getClientOffset = (event) => {
  const {
    pageX,
    pageY
  } = event.touches ? event.touches[0] : event;
  const x = pageX - canvasPad.offsetLeft;
  const y = pageY - canvasPad.offsetTop;

  return {
    x,
    y
  }
}

toolbar.addEventListener('click', e => {
    if (e.target.id === 'clear') {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
    }
});

toolbar.addEventListener('change', e => {
    if(e.target.id === 'stroke') {
        ctx.strokeStyle = e.target.value;
    }

    if(e.target.id === 'lineWidth') {
        lineWidth = e.target.value;
    }
    
});

const drawLine = (ctx) => {
  if (!isDrawStart) {
    return;
  }
  ctx.beginPath();
  ctx.moveTo(startPosition.x, startPosition.y);
  ctx.lineTo(lineCoordinates.x, lineCoordinates.y);
  ctx.stroke();
}

const mouseDownListener = (event) => {
  startPosition = getClientOffset(event);
  isDrawStart = true;
}

const mouseMoveListener = (event) => {
  if (!isDrawStart) return;

  lineCoordinates = getClientOffset(event);
  clearCanvas(padContext);
  drawLine(padContext);
}

const mouseupListener = (event) => {
  clearCanvas(padContext);
  drawLine(context);
  isDrawStart = false;
}

const clearCanvas = (ctx) => {
  ctx.clearRect(0, 0, canvasEle.width, canvasEle.height);
}

canvasPad.addEventListener('mousedown', mouseDownListener);
canvasPad.addEventListener('mousemove', mouseMoveListener);
canvasPad.addEventListener('mouseup', mouseupListener);
body {
    margin: 0;
    padding: 0;
    height: 100%;
    overflow: hidden;
    color: white;
}

h1 {
    background: #7F7FD5;
    background: -webkit-linear-gradient(to right, #91EAE4, #86A8E7, #7F7FD5);
    background: linear-gradient(to right, #91EAE4, #86A8E7, #7F7FD5);
    background-clip: text;
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
}
  
  .cnv-wrapper {
    height: 100%;
    display: flex;
  }
  
  .pad {
    height: 100%;
    display: flex;
    border: 4px solid #333;
  }

  .container {
    height: 100%;
    display: flex;
}

#toolbar {
    display: flex;
    flex-direction: column;
    padding: 5px;
    width: 70px;
    background-color: #202020;
}

#toolbar * {
    margin-bottom: 6px;
}

#toolbar label {
    font-size: 12px;
}

#toolbar input {
    width: 100%;
}

#toolbar button {
    background-color: #1565c0;
    border: none;
    border-radius: 4px;
    color:white;
    padding: 2px;
}
<!DOCTYPE html>
<html lang="en">
        <head>
            <meta charset="UTF-8" />
            <meta http-equiv="X-UA-Compatible" content = "IE = edge">
            <meta name = "viewport" content = "width = device - width, initial - scale = 0.1">
            <link rel = "stylesheet" href = "styles.css">
            <title> Pipe Illustrator </title>
        </head>

        <body>
            <section class  = "container">
                <div id = "toolbar">
                    <h1>Draw.</h1>
                    <label for="stroke">Stroke</label>
                    <input id="stroke" name='stroke' type="color">
                    <label for="lineWidth">Line With</label>
                    <input id="lineWidth" name='lineWidth' type="number" value="5">
                    <button id="clear">Clear</button>
                </div>
                <div class = "drawing-container">
                    <canvas id = "drawing-container"></canvas>
                </div>
                <div class = "cnv-wrapper">
                    <canvas id = "cnv-wrapper"></canvas>
                </div>
            </section>
            <script src = "./index.js"></script>
        </body>
</html>

The task at hand is to create a straight line drawing tool that allows fixed lines to be drawn without erasing the previous ones. The provided code below meets this requirement and was shared by another user before based on a question I asked about achieving this functionality.

However, when I copy and paste the code into my Visual Studio Code editor, the output does not match what I see in jsfiddle. The canvas doesn't show up, and drawing is not possible. Am I overlooking something here?

The code snippet I have pasted here is an altered version of the original code aimed at integrating additional features such as a toolbar for selecting line color and width. Unfortunately, the implementation seems messy and conflicting due to mixing it with functions from a different project. As a coding beginner, these projects serve as learning experiences. Thanks in advance for any guidance or assistance.

const canvasEle = document.querySelector('.draw-container');
const canvasPad = document.querySelector('.pad');
const context = canvasEle.getContext('2d');
const padContext = canvasPad.getContext('2d');
let startPosition = {
  x: 0,
  y: 0
};
let lineCoordinates = {
  x: 0,
  y: 0
};
let isDrawStart = false;

const getClientOffset = (event) => {
  const {
    pageX,
    pageY
  } = event.touches ? event.touches[0] : event;
  const x = pageX - canvasPad.offsetLeft;
  const y = pageY - canvasPad.offsetTop;

  return {
    x,
    y
  }
}

const drawLine = (ctx) => {
  if (!isDrawStart) {
    return;
  }
  ctx.beginPath();
  ctx.moveTo(startPosition.x, startPosition.y);
  ctx.lineTo(lineCoordinates.x, lineCoordinates.y);
  ctx.stroke();
}

const mouseDownListener = (event) => {
  startPosition = getClientOffset(event);
  isDrawStart = true;
}

const mouseMoveListener = (event) => {
  if (!isDrawStart) return;

  lineCoordinates = getClientOffset(event);
  clearCanvas(padContext);
  drawLine(padContext);
}

const mouseupListener = (event) => {
  clearCanvas(padContext);
  drawLine(context);
  isDrawStart = false;
}

const clearCanvas = (ctx) => {
  ctx.clearRect(0, 0, canvasEle.width, canvasEle.height);
}

canvasPad.addEventListener('mousedown', mouseDownListener);
canvasPad.addEventListener('mousemove', mouseMoveListener);
canvasPad.addEventListener('mouseup', mouseupListener);
body {
  background-color: #ccc;
}

.cnv-wrapper {
  position: relative;
}

.pad {
  position: absolute;
  top: 0px;
  left: 0px;
  border: 1px solid #333;
}

.draw-container {
  border: 1px solid #333;
}
<div class="cnv-wrapper">
  <canvas class="draw-container" width="500" height="500"></canvas>
  <canvas class="pad" width="500" height="500"></canvas>
</div>

Answer №1

When offering advice in the comments:

It's important to remember that simply copying and pasting code from a fiddle won't work without incorporating the appropriate html tags. Your CSS should be enclosed within style tags, while your scripts belong within script tags. Elements such as "canvas" need to be nested in the body tag. Additionally, you may need to include the proper "doctype" declaration and ensure your scripts are executed upon document load.

To illustrate this point, I tested the provided code following the above guidelines on my personal system, and it performed as expected.

I will now present the complete source code followed by a functional version here on SO. Please note that the runnable version on SO utilizes the platform's utilities, so you may not see all the mentioned tags, but the functionality remains consistent with the original "fiddle".

The corrected code includes all necessary tags for reference:

<!doctype html> <!-- Include the appropriate doctype -->

<html>
<head>

<style>
/* Place the CSS within a style tag */

body {
  background-color: #ccc;
}

.cnv-wrapper {
  position: relative;
}

.pad {
  position: absolute;
  top: 0px;
  left: 0px;
  border: 1px solid #333;
}

.draw-container {
  border: 1px solid #333;
}
</style>

</head>

<body> 

<div class="cnv-wrapper">
  <canvas class="draw-container" width="500" height="500"></canvas>
  <canvas class="pad" width="500" height="500"></canvas>
</div>

<script>
// Insert your initialization scripts inside the onload event to ensure they run after the canvas creation

window.onload = function() {
    
    const canvasEle = document.querySelector('.draw-container');
    const canvasPad = document.querySelector('.pad');
    const context = canvasEle.getContext('2d');
    const padContext = canvasPad.getContext('2d');
    let startPosition = {
      x: 0,
      y: 0
    };
    let lineCoordinates = {
      x: 0,
      y: 0
    };
    let isDrawStart = false;

    const getClientOffset = (event) => {
      const {
        pageX,
        pageY
      } = event.touches ? event.touches[0] : event;
      const x = pageX - canvasPad.offsetLeft;
      const y = pageY - canvasPad.offsetTop;

      return {
        x,
        y
      }
    }

    const drawLine = (ctx) => {
      if (!isDrawStart) {
        return;
      }
      ctx.beginPath();
      ctx.moveTo(startPosition.x, startPosition.y);
      ctx.lineTo(lineCoordinates.x, lineCoordinates.y);
      ctx.stroke();
    }

    const mouseDownListener = (event) => {
      startPosition = getClientOffset(event);
      isDrawStart = true;
    }

    const mouseMoveListener = (event) => {
      if (!isDrawStart) return;

      lineCoordinates = getClientOffset(event);
      clearCanvas(padContext);
      drawLine(padContext);
    }

    const mouseupListener = (event) => {
      clearCanvas(padContext);
      drawLine(context);
      isDrawStart = false;
    }

    const clearCanvas = (ctx) => {
      ctx.clearRect(0, 0, canvasEle.width, canvasEle.height);
    }

    canvasPad.addEventListener('mousedown', mouseDownListener);
    canvasPad.addEventListener('mousemove', mouseMoveListener);
    canvasPad.addEventListener('mouseup', mouseupListener); 
}
</script>

</body>
</html>

Now, let's demonstrate the functionality of this code on SO:

Please note that like a "fiddle", SO's code interpreter also does not require certain tags when pasting into your own editor. Hence, I reiterate where each part of the code should be placed within the comments.

// Your script content should go within a <script> tag

// Utilize an onload event handler to ensure execution after canvas creation

window.onload = function() {
    const canvasEle = document.querySelector('.draw-container');
    const canvasPad = document.querySelector('.pad');
    const context = canvasEle.getContext('2d');
    const padContext = canvasPad.getContext('2d');
    let startPosition = {
      x: 0,
      y: 0
    };
    let lineCoordinates = {
      x: 0,
      y: 0
    };
    let isDrawStart = false;

    const getClientOffset = (event) => {
      const {
        pageX,
        pageY
      } = event.touches ? event.touches[0] : event;
      const x = pageX - canvasPad.offsetLeft;
      const y = pageY - canvasPad.offsetTop;

      return {
        x,
        y
      }
    }

    const drawLine = (ctx) => {
      if (!isDrawStart) {
        return;
      }
      ctx.beginPath();
      ctx.moveTo(startPosition.x, startPosition.y);
      ctx.lineTo(lineCoordinates.x, lineCoordinates.y);
      ctx.stroke();
    }

    const mouseDownListener = (event) => {
      startPosition = getClientOffset(event);
      isDrawStart = true;
    }

    const mouseMoveListener = (event) => {
      if (!isDrawStart) return;

      lineCoordinates = getClientOffset(event);
      clearCanvas(padContext);
      drawLine(padContext);
    }

    const mouseupListener = (event) => {
      clearCanvas(padContext);
      drawLine(context);
      isDrawStart = false;
    }

    const clearCanvas = (ctx) => {
      ctx.clearRect(0, 0, canvasEle.width, canvasEle.height);
    }

    canvasPad.addEventListener('mousedown', mouseDownListener);
    canvasPad.addEventListener('mousemove', mouseMoveListener);
    canvasPad.addEventListener('mouseup', mouseupListener); 
}
/* Your CSS would go in a <style> tag */

body {
  background-color: #ccc;
}

.cnv-wrapper {
  position: relative;
}

.pad {
  position: absolute;
  top: 0px;
  left: 0px;
  border: 1px solid #333;
}

.draw-container {
  border: 1px solid #333;
}
<!-- Your HTML would go in the <body> tag -->

<div class="cnv-wrapper">
  <canvas class="draw-container" width="500" height="500"></canvas>
  <canvas class="pad" width="500" height="500"></canvas>
</div>

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

The state of the checked value remains unaffected when using the Angular Material Checkbox

I am currently working on a list of elements and implementing a filter using pipes. The filter allows for multi-selection, so users can filter the list by more than one value at a time. To ensure that the filter persists even when the window is closed or t ...

Having trouble starting the server? [Trying to launch a basic HTML application using npm install -g serve]

I am in the process of creating a PWA, but I haven't reached that stage yet. Currently, I have only created an index.html file and an empty app.js. To serve my project locally, I installed serve globally using npm install -g serve When I run the co ...

Different Zoom feature for JIT Graph

I'm currently working with the Java Infovis Toolkit and I'd like to use buttons for zooming in and out instead of using the mouse wheel. Can someone guide me on how I can implement two separate buttons for Zoom In and Zoom Out functions? ...

Exploring the functionality of CSS class selectors (.class-name) when used alongside CSS tag selectors (div, etc...)

I have designed my website with three distinct tables, each requiring unique styling. The general approach I take to apply styling to these tables is as follows: import './gameview.css' <div className="game-results"> <h ...

I'm encountering CORS issues while attempting to log in using guacamole from my React app. Can anyone advise on what might be causing this problem

Having trouble logging into the Guacamole form through a React JS web application. The Guacamole server is hosted on Tomcat server, while the React app is on Node.js; both operating on separate domains. Despite using Nginx proxy on the server, encounteri ...

Issues with displaying ngAnimate animations

For the past 10 hours, I've been attempting to get my animations to function properly. It seems that they only work when I include the animate.css stylesheet and use the "animated classname". However, when I try to create custom entrance and exit anim ...

What's the best way to implement a conditional header in React?

I am looking to create a conditional display of the Header based on different pages. Specifically, I want the Header to be hidden on the Home page and shown on other pages like posts page, projects page, etc. I have been brainstorming possible solutions f ...

Generate a responsive list with a pop-up feature under each item (using Vue.js)

Currently, I believe that Vue may not be necessary since most tasks can be done using JavaScript and CSS. I am attempting to design a list layout as follows: [A] [B] [C] [D] When an item is clicked, the information about that specific item should ...

Pass user input values to PHP via AJAX and display the outcome on a designated div

I am currently working on a project where I need to send an input value to a PHP script and display the returned value in a div using AJAX. However, I seem to be struggling with getting it to work properly. Any assistance or suggestions would be greatly ap ...

Handling an HTTP Get request by utilizing Server-Sent Events (SSE)

Exploring the possibilities of HTML5 and node.js has led me to test out Server Sent Events successfully using this example. My experiment then involved responding to a button press with an SSE. Upon clicking the "Increment" button, I extracted a number fr ...

"Accessing your account only requires a simple two-click login process

Why do I need to click the log in button twice for data validation on my forum website? While designing a forum website, I noticed that users have to click the log-in button twice before the system validates and processes the input data. Below is the code ...

What is the process for animating classes instead of ids in CSS?

My webpage currently features a setup similar to this. function wiggle(){ var parent = document.getElementById("wiggle"); var string = parent.innerHTML; parent.innerHTML = ""; string.split(""); var i = 0, length = string.length; for (i; i ...

What techniques can be used to optimize the SEO of HTML generated by JavaScript? How does React.js go about achieving this

Is my webpage optimized for SEO if it was created using appendChild and innerHTML with JavaScript? Can react.js improve the SEO of a webpage? ...

Is there a way to conditionally redirect to a specific page using NextAuth?

My website has 2 points of user login: one is through my app and the other is via a link on a third-party site. If a user comes from the third-party site, they should be redirected back to it. The only method I can come up with to distinguish if a user is ...

What in the world is going on with this code snippet? I'm completely stumped on how to fix this problem

Attempting to generate a custom element with unique properties function y(){ var g=document.createElement("div"); this.label="elephant"; return g; } y.prototype.customFunction=function(){ alert(arguments[0]+this.label); }; var b=new y(); b ...

Can someone please share the steps on how to insert a new row into a PrimeNg DataTable component

I am currently working on enhancing a table by adding a new row underneath the existing data list. This new row will contain a save button and allow users to insert information, such as saving a phone number. While I have indicated where the new row should ...

Sit tight as we prepare all static assets for loading on the screen

Currently, I am developing a vuejs application that will incorporate video elements. To enhance user experience, we are interested in preloading these videos upon the initial loading of the web application. I am considering using a listener like, documen ...

Arrange the JSON object according to the date value

I am working on a JavaScript project that involves objects. Object {HIDDEN ID: "06/03/2014", HIDDEN ID: "21/01/2014"} My goal is to create a new object where the dates are sorted in descending order. Here's an example of what I want: SortedObject ...

The lifecycle of XMLHTTPRequest objects in JavaScript - from creation to destruction

After years of working with traditional compiled object-oriented languages like C++ and .NET programming, I decided to dip my toes into JavaScript for a new project. As I was experimenting with AJAX, I stumbled upon a perplexing aspect related to how objec ...

The CSS legend for a FLOT plot chart is being unexpectedly replaced

I am currently exploring the FLOT plot tool and facing difficulty with the legend display. It seems that the CSS styling for the legend is somehow being overridden in my code, resulting in an undesirable appearance of the legend: Even when I try to specif ...