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

Using ajax to submit variables may not function properly

I have a set of data that has been processed using JavaScript and I am looking to save it to a database. I have been attempting to code something with AJAX, but so far, I have had no success... What I require: Two variables (id, name) need to be sent to a ...

What causes the component to remount with every update to its state?

PLEASE NOTE: Before posting this question, I realized that there were some errors in my code. I understand now that this question may not be helpful to others as it contains misleading information. I apologize and appreciate those who took the time to res ...

Guide to rendering a div class conditionally in a Razor page depending on a variable?

How can I dynamically render a div with different classes in Angular based on a condition? <div class="@(myArray.length>0 ? "col-md-8" : "col-md-12" )"> I'm trying to achieve that if the length of myArray is greater than 0, then it should h ...

Guide to pre-populate a text field within a WKWebView on a website with the use of Swift

I am a beginner in the world of coding, specifically with Swift. My goal is to allow users to input their username and password in the settings section, which will then automatically populate the login page on a WKWebView that I have created. Currently, I ...

React Select feature fails to show suggestions after asynchronous debounced call

I am currently utilizing react-select to load results from an API while debouncing queries using lodash.debounce: import React, {useState} from 'react'; import AsyncSelect from 'react-select/lib/Async'; import debounce from 'lodas ...

The list in Jquery UI Autocomplete is not updating correctly

Currently, I am using jQuery UI Autocomplete in conjunction with WebSockets to fetch and display a list of options. Each time a keystroke is detected on the input field (.keyup()), a call is made to retrieve the list. However, I have encountered an issue w ...

Improving the App() function in React and Typescipt

When working on my React/Typescript app, I encountered a challenge with the length of the code in one of the sections. Despite watching tutorials and searching for solutions, I couldn't find a clear way to refactor it. The specific issue is with refa ...

Angular dynamically changes the placeholder text in an input based on a selection made in a mat select dropdown

Trying to change the placeholder text in a mat-input based on selection in mat-select, but struggling to bind it to the selected option. <mat-form-field appearance="outline" class="search-field" style="width:40vw"> ...

Changing the host in every URL within a string using node.js

I am working with a string that contains URLs with IP addresses: { "auth" : { "login" : "http://123.123.11.22:85/auth/signin", "resetpass" : "http://123.123.22.33:85/auth/resetpass", "profile" : "http://123.123.33.44:85/auth/profile" ...

The functionality of Jquery and JS lies in working on DOM elements as opposed to

Just to start off, I want to mention that my knowledge of JavaScript and specifically jQuery is quite limited. I've encountered an issue with some JavaScript and jQuery loading on my webpage. 1) I have written some code on JSFiddle http://jsfiddle.n ...

Unusual Happenings with jQuery Draggable

Currently, I am experimenting with jQuery draggable to move individual letters of the word "Hello" around on the page. However, I have come across a frustrating issue. When I drag the letter H towards the right and it gets near the letters E, L, L, or O, ...

What is the best way to use Shadcn to incorporate a calendar that takes up half of my website?

Currently, I am in the process of developing a scheduling appointment system. My main challenge is getting the calendar to take up half of my page's space. Despite my attempts to adjust its height and width, I have not been successful in seeing any ch ...

Conditionally Add Columns to jQuery Datatables

I am working with a jQuery datatable to showcase data retrieved through an AJAX request. However, I am interested in adding a third column to the table specifically for administrators, allowing them to delete entries. Can someone guide me on how to incorpo ...

Is the next function triggered only after the iframe has finished loading?

First and foremost, I understand the importance of running things asynchronously whenever possible. In my code, there exists a function known as wrap: This function essentially loads the current page within an iframe. This is necessary to ensure that Jav ...

Collections of both letters and non-letter characters that are aligned

I am attempting to identify sets of characters that contain a mix of letters and non-letter characters, with many of them being just one or two letters. const match = 'tɕ\'i mɑ mɑ ku ʂ ɪɛ'.match(/\b(p|p\'|m|f|t|t ...

Incorporate text onto an image using Semantic UI

Currently, I am utilizing Semantic UI to display images. While it is functioning well for me in terms of adding text near the image, I desire to have the text positioned on top of the image. Ideally, I would like it to be located on the lower half of the i ...

Problem with Ionic 2 local storage: struggling to store retrieved value in a variable

Struggling to assign the retrieved value from a .get function to a variable declared outside of it. var dt; //fetching data this.local.get('didTutorial').then((value) => { alert(value); dt = value; }) console.log("Local Storage value: " ...

The complexity surrounding various versions of jQuery, the .noConflict method, and the jQuery migrate feature

I was tasked with making a large-scale website responsive, and decided to utilize Bootstrap as the framework. However, I encountered issues due to the jQuery version (v1.8.2) being used. In my development environment, I resolved this by including the follo ...

What is the best method for designing a filtering menu with a "Narrow By" option?

Looking to create a sidebar menu similar to the functionality on mcmaster.com. This specific feature allows users to efficiently filter products and toggle through different options dynamically. Upon selecting the "metric" option, the entire page adjusts t ...

The behavior of TypeScript class inheritance differs from that of its ES6 equivalent

I'm currently developing a custom error handling middleware for my node.js project using express and TypeScript. One key component of this middleware is the AppError class, which extends the built-in Error class. The code for this class is as follows: ...