When utilizing KineticJS on a canvas that has been rotated with css3, the functionality of the events appears to be malfunctioning

Currently, I'm working on a rotating pie-chart widget using Kineticjs. However, I have run into an issue where the events don't seem to function correctly when drawing on a rotated canvas element (with the parent node being rotated 60deg using CSS3). For instance, on a canvas rotated 15 deg clockwise, the hover event is consistently 15 deg off. Does anyone have any suggestions or ideas on how to address this problem?

Answer №1

Your query has a complex solution—here's why:

The issue lies in the transformed state of your DOM container.

While your Kinetic objects behave as though they are in their original, non-transformed state.

The misinterpretation by your kinetic objects is due to the browser providing them with transformed mouse coordinates.

An easy resolution: Keep your DOM container untransformed and handle all rotations within KineticJS

A more challenging fix: Convert the rotated DOM mouse points into unrotated points for Kinetic usage.

Here's how you can approach this problem:

CSS transforms typically rotate around the element's center (50%, 50%), so identify the center of your Kinetic stage

var cx = stage.getWidth() / 2;
var cy = stage.getHeight() / 2;

If you have mouse coordinates in the transformed space (DOM), you must convert them to untransformed points (KineticJS)

var unrotatedPoint = unrotatedXY(cx, cy, mouseX, mouseY, cssDegreeRotation);

Below is the function that accomplishes this task:

function unrotatedXY(cx, cy, mouseX, mouseY, cssDegreeRotation) {

    var dx = mouseX - cx;
    var dy = mouseY - cy;
    var r = Math.sqrt(dx * dx + dy * dy);
    var cssRadianAngle = cssDegreeRotation * Math.PI / 180;

    var rotatedAngle = Math.atan2(dy, dx);

    var unrotatedAngle = rotatedAngle -= cssRadianAngle;

    if (unrotatedAngle < 0) { unrotatedAngle += Math.PI * 2; }

    unrotatedX = cx + r * Math.cos(unrotatedAngle);
    unrotatedY = cy + r * Math.sin(unrotatedAngle);

    return({ x: unrotatedX, y: unrotatedY });
}

The mouseX/mouseY values are obtained from the document, not KineticJS.

Thus, you need to listen to mouse events on the document (or container element), rather than directly in KineticJS.

$(document).mousemove(function(e){handleMouseMove(e);});

function handleMouseMove(e){
  mouseX = parseInt(e.clientX - offsetX);
  mouseY = parseInt(e.clientY - offsetY);

  var unrotatedPoint = unrotatedXY(cx, cy, mouseX, mouseY, cssDegreeRotation);

  // Now, you can perform hover actions against your Kinetic nodes using these converted mouse coordinates…
}

To reconnect with KineticJS, consider utilizing node.fire to trigger events with custom event objects containing the adjusted mouse coordinates.

Answer №2

Important Update:

Following markE's recommendation, resolving the issue proved to be more challenging than anticipated. The detailed problem and its resolution can be found here. Fortunately, it has been successfully resolved in a recent update.

The root cause of the original error was traced back to jquery's event handling code. Thankfully, this issue has been rectified and no longer exists in the latest version.

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

What is the process for customizing the appearance of a prop within the <TextField> component?

Using my custom DatePicker.js component, I have two instances of <TextField>. When the user clicks on the <CalendarIcon> within the <TextField>, a small calendar pops up. However, I want to style the label in the <TextField> in a sp ...

The server's request is being processed through jQuery's ajax functionality

Recently, I've started working with jQuery and AJAX. Essentially, the webpage sends an HTTP post request, and the server-side DLL responds by writing a JSON-formatted response back to the page. I'm trying to understand how to handle this response ...

"Using the map function in Javascript to iterate through an array and then implementing

I am working on a script that involves an array of the alphabet along with two sets of values. The goal is to determine if a given value falls within the range specified by these two values and then print out the corresponding letter from the alphabet. H ...

Issue with Angular: Unable to properly sort data while modifying queryParams

Within the component.ts file: export class TabsComponent implements OnInit { constructor( private store$: Store<UsersState>, private router: ActivatedRoute ) {} ngOnInit(): void { this.onFilterByIncome(); this.router.queryParam ...

Choose the option in real-time with Jquery

I'm currently developing a dynamic HTML for Select Option as seen below: item += "<td class='ddl' style='width:40%;'>"; item += "<select>" item += " <option id='list' name='selector' value=" + se ...

My Express server is having trouble loading the Static JS

I'm feeling frustrated about this particular issue. The problem seems to be well-solved, and my code looks fine, but I can't figure out what's wrong . . . I have a JavaScript file connecting to my survey page, which I've added at the b ...

Dealing with models in Vue.js is proving to be quite a challenge

Why isn't myGame showing as 超級馬力歐 initially and changing when the button is pressed? It just displays {{myGame}} instead. I'm not sure how to fix it, thank you! let myApp = new vue({ el:'myApp', data:{ myGame:&a ...

Having issues with clicking on a row in the table while using AJAX functionality

Experiencing a puzzling issue while attempting to add click functionality to table rows with AJAX, here is the JavaScript code used: //for tabs $(document).ready(function () { $("#tabs").tabs(); }); $(window).load(function() { jsf.ajax.addOnEven ...

Whenever I execute the 'ng serve' command, I encounter an issue with ineffective mark-compacts close to the heap limit, resulting in an allocation failure and a JavaScript

I'm currently using Angular 9 and Node.js 12. When I input ng serve, I encounter the following problem: C:\Users\homz\my-app>ng serve 93% after chunk asset optimization SourceMapDevToolPlugin vendor.js generate SourceMap <--- ...

Puppeteer - Issue with Opening Calendar Widget

Problem: Unable to interact with the calendar widget on a hotel website (). Error Message: Node is either not clickable or not an Element Steps Taken (code snippet below): const puppeteer = require('puppeteer') const fs = require('fs/promi ...

Clicking the set button in Jquery mobile datebox resets the time

I am experimenting with the jquery mobile datebox (courtesy of Jtsage) to select time and date. Unfortunately, every time I reset the time by clicking the set button, I am unable to retrieve the correct time. Below are my code snippets: $.extend($.jtsag ...

Subscribe on Footer triggers automatic scrolling to the bottom of the page

Whenever I fill out the form in the footer and hit submit, it directs me to a different page while automatically scrolling back down to the footer. I'm looking for a solution that prevents this automatic scrolling. I've attempted using window.sc ...

How can I edit this code in JSPDF to print two pages instead of just one?

Currently, I have a script that can generate a PDF from one DIV, but now I need to create a two-page PDF from two separate DIVs. How can I modify the existing code to achieve this? The first DIV is identified as #pdf-one and the second DIV is #pdf-two. p ...

looping through a linked data object with ng-repeat

I am working with a Node object in my Angular controller. Each Node contains a next property which points to the next item: $scope.Stack = function () { this.top = null; this.rear = null; this.size = 0; this.max_size = 15; ...

Is there an issue with MVC5 in passing JSON data to Controller using Ajax?

I am working on implementing duplication checking in my MVC5/EF Code-First application. In the Asset View's Create() method, I use JavaScript to show/hide textboxes for adding a new location_dept/location_room: <div class="form-group"> ...

Utilize Postman to send a JSON body in a POST request to trigger a stored procedure on Microsoft SQL Server

I need to send a JSON request using the Postman app, utilizing the POST method to retrieve data. My boss, who is overseeing my training, assigned me this task. I've scoured the web for a week but haven't found a solution yet. Initially, I sugges ...

In the provided Javascript snippet, how would you classify `word` - a function, variable, or object?

Understanding that an object is a variable and a function is a type of object, I find myself confused about the proper way to reference word in the following code snippet: var word; exports.setWord = function(c, ch){ word = c.get('chats')[ch]; ...

What is the purpose of assigning controller variables to "this" in AngularJS?

Currently, I am analyzing an example in CodeSchool's "Staying Sharp with Angular" course in section 1.5. Here is the code snippet: angular.module('NoteWrangler') .controller('NotesIndexController', function($http) { var contro ...

Utilize Angular2's input type number without the option for decimal values

Is there a way to prevent decimals from being entered in number inputs for Angular 2? Instead of using patterns or constraints that only invalidate the field but still allow typing, what is the proper approach? Would manually checking keystrokes with the ...

Converting data into a multidimensional array in AngularJS: A comprehensive guide

Struggling to convert a JSON array into a multidimensional array, looking for some guidance. I attempted using _.groupBy in underscore.js, but it's not proving successful with the nested array. If there is any way to convert from the given data [{ ...