Sketch on canvas using vue framework

I am trying to modify a selection tool using rectangles that was created with JS and HTML in Vue.js. Here is the original version: https://codepen.io/sebastiancz/pen/mdJVJRw

initDraw(document.getElementById('canvas'));

function initDraw(canvas) {

    function setMousePosition(e) {
        var ev = e || window.event; //Moz || IE
        if (ev.pageX) { //Moz
            mouse.x = ev.pageX + window.pageXOffset;
            mouse.y = ev.pageY + window.pageYOffset;
        } else if (ev.clientX) { //IE
            mouse.x = ev.clientX + document.body.scrollLeft;
            mouse.y = ev.clientY + document.body.scrollTop;
        }
    };

    var mouse = {
        x: 0,
        y: 0,
        startX: 0,
        startY: 0
    };
    var element = null;

    canvas.onmousemove = function (e) {
        setMousePosition(e);
        if (element !== null) {
            element.style.width = Math.abs(mouse.x - mouse.startX) + 'px';
            element.style.height = Math.abs(mouse.y - mouse.startY) + 'px';
            element.style.left = (mouse.x - mouse.startX < 0) ? mouse.x + 'px' : mouse.startX + 'px';
          console.log(mouse.x, mouse.y)
            element.style.top = (mouse.y - mouse.startY < 0) ? mouse.y + 'px' : mouse.startY + 'px';
        }
    }

    canvas.onmousedown = function (e) {

            console.log("Start.");
            mouse.startX = mouse.x;
            mouse.startY = mouse.y;
            element = document.createElement('div');
            element.className = 'rectangle'
            element.style.left = mouse.x + 'px';
            element.style.top = mouse.y + 'px';
            canvas.appendChild(element)
        }
  canvas.onmouseup = function (e) {
            element = null;
    // canvas.ctx.clearRect();
            console.log("finished.");

  }

}

This is my attempt at implementing it in Vue.js, but it's not working properly: https://codepen.io/sebastiancz/pen/mdJPvOP?editors=0011

Any suggestions on how I can fix this issue?

Answer №1

You can utilize Vue.js and HTML5 Canvas to create an interactive feature where users can make selections. By storing the start and end positions of each selection in an array, you can enhance this functionality to display previous user selections.

Vue.component("selection", {
  template: `<canvas id='canvas' ref='select' @mousedown='startSelect' @mousemove='drawRect' @mouseup='stopSelect'></canvas>`,
  data() {
    return {
      ctx: null,
      selectionMode: false,
      startPosition: {
        x: null,
        y: null
      }
    };
  },
  
  methods: {
  
    startSelect(e) {
      this.selectionMode = true;
      this.startPosition.x = e.clientX;
      this.startPosition.y = e.clientY;
    },
    
    drawRect(e) {
      if (this.selectionMode) {
        console.log(this.startPosition);
        this.ctx.beginPath();
        this.ctx.rect(
          this.startPosition.x,
          this.startPosition.y,
          e.clientX - this.startPosition.x,
          e.clientY - this.startPosition.y
        );
        this.ctx.closePath();
        this.ctx.fillRect(0, 0, window.innerWidth, window.innerHeight);
        this.ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
        this.ctx.strokeStyle = "#f00";
        this.ctx.stroke();
      }
    },
    
    stopSelect(e) {
      this.ctx.fillStyle = "#fff";

      this.selectionMode = false;
      this.startPosition.x = null;
      this.startPosition.y = null;
    }
    
  },
  mounted() {
    this.$refs.select.height = window.innerHeight;
    this.$refs.select.width = window.innerWidth;
    this.ctx = this.$refs.select.getContext("2d");
    // this.ctx.fillRect(0,0,500,500);
  }
});

new Vue({
  el: "#app",
  data: {
    hello: "world"
  }
});
body {
  margin: 2rem;
  background: #eee;
}

#canvas {
  background: white;
  box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.2);
}
<div id="app">
  <selection></selection>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

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

Error message occurs when creating a pie chart with invalid values for the <path> element in Plottable/D3.js

For those who need the code snippets, you can find them for download here: index.html <!doctype html> <html> <head> <meta charset="UTF-8"> <!-- CSS placement for legend and fold change --> </head> <body ...

Transform the date to match the user's preferred timezone abbreviation

I am currently utilizing the momentJS library for timezone conversion logic within my JavaScript code. I retrieve the User Preference Timezone abbreviation from a web service response, but when attempting to convert the date using the Timezone abbreviation ...

Unable to locate properties "offsetHeight" or "clientHeight" within a React/Next.js project developed in TypeScript

I have a unique customized collapsible FAQ feature that adjusts its height based on whether it's expanded or collapsed. import { useState, useRef, useEffect } from "react"; export default FAQItem({title, description}: FAQItemProps) { cons ...

Unlawful use of the return statement

Can you identify the issue with this code? The browser reports: "Uncaught SyntaxError: Illegal return statement" I'm looking for an explanation in this format: 1 2 3fool 4 5bar 6fool 7 8 9bar... let arr = []; for (i = 0; i <= 100; i++) { if ( ...

display of information with v-element

How do I properly load the v-component and v-component2? 1) Within the Vue component 1: watch: { loader () { axios.post("/laravel_route", { param: value }) .then (response => { $("#section").html(re ...

Execute a specialized function with imported modules and specified parameters

Within an npm project, I am looking to execute a custom function with arguments, or ideally provide it as a script in the package.json file like this: npm run custom-function "Hello, World". Currently, I have a file called src/myFunction.ts: import * as e ...

Using jQuery to store the name of a Div in a variable and subsequently invoking it in a function

Recently, I've been grappling with a task involving storing a div name in a variable for easier editing and incorporating it into standard actions like show/hide. My code functions perfectly without the variables, but introducing them causes the div ...

Opacity error with jQuery slider specifically affecting Google Chrome browser

My Magento site features a custom-built slider that is both responsive and has unique touch behavior. The desired behavior for the slider is as follows: A three-image slider where the middle image has an opacity of 1.0, while the other two images have an ...

What is the best way to position the list element to align with the top of a div container?

To see a live example, visit this link. My goal is to create a line that separates two li elements within a nested ul. However, the line ends up taking the width of the container ul instead of the div containing the entire structure. In the provided examp ...

Forwarding refs in React FC allows you to easily pass down

I have encountered an issue with references - I am trying to reference a function component and pass props to it. Currently, I have my Parent component and Child Component set up. In the parent component, I need to use a ref to access my child component. S ...

Utilize the native HTML attribute to capture the mouse wheel event

I'm interested in utilizing the mousewheel event in my project, but all the information I've found online relies on addEventListener(). I want to detect it using native HTML and CSS. In simpler terms, I'm hoping for something along the lines ...

Is Babel necessary for a Node.js server application, and what are the benefits of using it?

My fondness for ES6 syntax and its new object-oriented style makes coding much easier for me. However, as a newcomer to JavaScript, I am curious about the advantages and disadvantages of using Babel in terms of performance, maintenance, readability, and ...

What advantages does leveraging GraphQL with React offer compared to using GraphQL with Vue, Ember, or Angular?

Curious if there are any advantages to combining GraphQL, created by Facebook, with React? Or is it better to use a different JavaScript framework like Vue, Angular, or Ember instead? ...

Utilizing the power of Koa.js in conjunction with MongoDb for seamless development

Having an issue, or maybe just lacking some knowledge here. The question is pretty straightforward - I have this code: router.get('/', (ctx, next) => { MongoClient.connect(url, {useNewUrlParser: true}, function (err, db) { if (err) th ...

Error occurred while making a request in React using Axios: TypeError - Unable to retrieve the 'token' property as it is undefined

After successfully receiving a token from logging in with React Redux, I attempted to authorize it using the token. However, an error occurred stating Axios request failed: TypeError: Cannot read property 'token' of undefined. The token is stored ...

Why is my v-model not being updated when using a radio button in Vue.js?

After reviewing the documentation, I attempted to implement the code provided. While I am able to successfully retrieve data for enquiryDesc, I am consistently getting a value of 5 for the rating field. I even experimented with changing the radio group to ...

Get the excel file from the assets using vue.js

I need some help figuring out how to download an excel file from my vue.js project. I tried the following code: <template> <div class="row mt-5"> <a href="./assets/template.xlsx" target="_blank">Downloa ...

It appears that the use of "window.location" is causing the ajax post

I'm facing an issue with sending data to PHP using AJAX and redirecting to the PHP file. It seems that when I redirect to the PHP file, the data sent through AJAX is not being received. My goal is to have a button click trigger the sending of data to ...

Is it possible to use the .focus() event on an entire form in JQuery? If so, how

Take a look at this HTML snippet: <form ....> <textarea>....</textarea <input .... /> </form> I'm trying to set up a help section that appears when the user focuses on any form element, and disappears when they lose ...

Utilize HTML search input to invoke a JavaScript function

I am currently facing an issue with a navbar form that I have created. The goal is to allow users to input either a 3 digit number or a 5 digit number, which should then trigger a function to open a specific link based on the input. However, I am strugglin ...