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

How to hide the header on a specific page using Angular

Currently, I am working on an Angular project and my requirement is to hide the header block specifically on the login page. Despite attempting to hide the header on the login page, it seems that my efforts have been unsuccessful so far. Is there anyone wh ...

AngularJS allows for the creation of 2D arrays using the $Index

Currently, I am working on a project using AngularJS that involves creating a spreadsheet from a 2D array generated by the ng-repeat function. As part of this project, I am developing a function to update the initial values of the array when users input ne ...

Revamp the Twitter button parameters or alter its settings

I'm working on a web page that includes a Twitter button. Before the button, there is an input field and a form where users can easily add relevant hashtags for the page. The goal is to take the text from the input field and populate it in the Twitter ...

AngularJS controller encounters a scoping problem within a callback function

I have created an angular application with a simple login form that can be viewed on this JSFiddle. HTML Code: <form data-ng-app="jsApDemo" data-ng-controller="loginCtrl"> <label for="username">Username:</label> <input type=" ...

Retrieve JSON data using AngularJS

Can someone guide me on how to make a GET request to my API endpoint and handle the JSON response in my code? Sample Controller.js Code: oknok.controller('listagemController', function ($scope, $http) { $scope.init = function () { ...

tips for accessing a PHP variable within an AJAX success function and setting it as a JavaScript variable

How can I access a PHP back end variable in a front-end AJAX success callback function? Here is my PHP code: if($_POST["action"] == 'check_ot_count') { $totaltime = 0; $ot_hours = $_POST["test"]; $month = $_P ...

Store the output of a mysql query in a variable for future reference

As I work on developing a backend API for a private message system, I have encountered a challenge with one of my functions. The issue arises when I attempt to store the result of an asynchronous call in a variable for future use. Here is the code snippet ...

Tips for successfully retrieving a variable from a function triggered by onreadystatechange=function()

Combining the ajax technique with php, I'm looking to extract the return variable from the function called by onreadystatechange. A java function triggers a call to a php script upon submission, which then validates certain data in the database and r ...

The updates made to a form selection using Ajax do not reflect in jQuery's .serialize or .val functions

When using the .load jQuery function to retrieve a form and place it in the document body, I encounter an issue. After loading the form, I manually change the select value and attempt to save the form using an ajax .post request. However, when trying to ...

Clean coding techniques for toggling the visibility of elements in AngularJS

Hey everyone, I'm struggling with a common issue in my Angular projects: app.controller('indexController', function ($scope) { scope.hideWinkelContainer = true; scope.hideWinkelPaneel = true; scope.headerCart = false; scope. ...

Using fancybox to send an ajax post request to an iframe

Can you send a variable to the iframe when using fancybox? This is my current setup: function fancyBoxLoad(element) { var elementToEdit = $("#" + $(element).attr("class")); var content = encodeURIComponent($(elementToEdit).oute ...

Is it possible to dynamically change a form's input value using a JavaScript keyup function based on input from other form elements?

My form utilizes the keyup function to calculate the total value of 3 input fields by multiplying them and displaying the result. Below is a fiddle showcasing this functionality: $(document).ready(function () { $(".txtMult1 input").keyup(multInp ...

ng-grid defines different cellClass based on the value of the field

I am currently using the ng-grid and I want the column to display in a different color based on different values. I have tried, but not succeeded so far... $scope.gridOptions = { ........ columnDefs: [ { field: "status", displayName: "St ...

Tips for closing a popup without exiting the entire webpage

I'm facing an issue while trying to create a video playlist using two HTML files (index.html and video.html). In my video.html file, I have set up a popup for playing videos. However, whenever I close the popup or click anywhere on the page, it redire ...

Can LocalStorage be deleted when the application is not running?

Can a specific key in an application's LocalStorage be deleted without having to open the app? I'm considering creating a batch file script for removing a particular key from the app's LocalStorage while the app is not running. The challeng ...

Ways to display and conceal menu depending on initial view and scrolling

On my website, I have implemented two menus - one to be displayed when the page loads and another to show up when a scroll occurs. You can view my page here. The goal is to have the white part visible when the position is at the top, and switch to the blu ...

The issue of the highlighted row not disappearing persists even after clicking on the adjacent table row

When selecting the gear icon for the menu option in a table row, I would like the background to turn yellow. I attempted the following code to highlight the table row: var view = Core.view.Menu.create({ model: model, menuContext: { ibmm: ibmm }, ...

Applying a consistent script with varying inputs on the same HTML page

Is it possible to create a JavaScript code that can be used across different sections of an HTML document? The goal is for the script to fetch data such as title, runtime, and plot from a specific URL request and insert this information into the appropriat ...

Feed information into a Select element from the Material UI version 1 beta

Having trouble populating data from a < Select > component in Material UI version 1.0.0.0 beta. Snippet of my code: This section is located inside the render() method. <Select value={this.state.DivisionState} onChange={this.handleChangeDi ...

Please insert a decimal point and thousand separator into the text field

I'm trying to incorporate thousand separators and decimal points into my text box. Additionally, I have implemented the following directive: .directive('format', function ($filter) { 'use strict'; return { requir ...