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

Tips for successfully including a positive sign character in string values within JSON in the URL's hash fragment

I am facing an issue with my JS (Angular) app where I load parameters from the URL fragment after the # sign. These parameters contain JSON objects, like this example: ...#filters={"Course":["ST_12.+13.12.2016 [Basel]"]} The aim is to open a data-grid an ...

Filtering elements in a table using jQuery

Can anyone provide a solution to display students without a class and hide the rest (where td Class-name is empty) using only jQuery or JS? I tried looking in the documentation but got lost. Any help would be appreciated. Example: table image The table ...

utilizing Typescript object within an array of objects

How can I optimize typing this nested array of objects? const myItem: Items[] = [{ id: 1, text: 'hello', items: [{ id: 1, text: 'world' }] }] One way to approach this is by using interfaces: interface It ...

Arrangement of 'const' variables within React Stateless Components

Consider a scenario where I have a straightforward React stateless component: const myComponent = () => { const doStuff = () => { let number = 4; return doubleNumber(number); }; const doubleNumber = number => { ...

Is nested testing the key to an elegant JQuery/AJAX form validation solution?

As I implement form validation with JQuery/AJAX, my goal is to provide a seamless experience for users. When an entry is missing or incorrect, I aim to display a single alert message and return the user to the form so they can make adjustments and resubmit ...

Is there a more optimal way to choose lines than the Bresenham algorithm?

In my HTML canvas project, I am currently drawing lines using a 2d-array that represents blocks of 10x10 pixels. I use Bresenham's algorithm to store line-ids in this array so that I can determine which line is selected. While this method works, I fi ...

divide an array into two separate arrays depending on whether the index position is odd or even

Here is an example array: Arr1 = [1,1,2,2,3,8,4,6]. I'm trying to divide this array into two new arrays based on the odd or even position of elements. Can anyone provide a solution? New Array 1 (odd positions): [1,2,3,4] New Array 2 (even positions) ...

I'm curious about the potential vulnerabilities that could arise from using a Secret key as configuration in an express-session

Our code involves passing an object with a secret key's value directly in the following manner --> app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: true, cookie: { secure: true } }) I am pondering wheth ...

Guidance on sharing an image on Twitter using Node.js

Every time I attempt to upload a PNG image to the Twit library in Node, an error arises. My objective is to develop a Twitter bot in Node.js that generates a random RGB colour, creates an image of this colour, and tweets it. Thanks to some assistance prov ...

Utilize Javascript/Jquery to categorize JSON data based on the days of the week (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday)

A function is provided below that retrieves data for a chart. The output produced by this function is structured as follows: [Object { date=Date, value=112, volume=1469}, Object { date=Date, value=124, volume=539}, Object { date=Date, value=114, vo ...

Adding an image to a jQuery class name on the fly

I am attempting to add an image before a div by using its className with jQuery. function insertImage(obj) { var dynamicClass = $(obj).prop("className"); After retrieving the classname, I now encapsulate it in single quotes and add a dot to access t ...

Tips for incorporating JSON data into an HTML table

https://i.sstatic.net/WEdge.jpgIn an attempt to showcase JSON data in an HTML table, I want the schoolClassName value to be displayed as a header (th) and the first names of students belonging to that specific schoolClass to appear in a column beneath the ...

Creating multiple asynchronous calls within a loop in JavaScript

I am currently working on a task in my gulpfile.js that involves uploading an app using Gulp and SharePoint. 'use strict'; const gulp = require('gulp'); const build = require('@microsoft/sp-build-web'); const spsync = require ...

Comparing defaultProps with the logical OR operator

Being relatively new to react, I’ve adopted a method of defining default values which looks like this: class TextInput extends Component { render() { return ( <input type="text" name={ this.pr ...

What are the steps to accessing validation errors using express-validator?

Recently, I delved into the world of express-validator to enhance my skills. Despite going through the documentation thoroughly, there's a query lingering in my mind that might have already been addressed in the docs. My confusion arises from needing ...

Leverage Pinia store in Vue helper functions

I have been working on my Vue.js application and I am looking to implement some helper functions that will utilize a Pinia store within the app. These functions need to be accessible by multiple components. Should I define these helper functions directly ...

I am attempting to create a form in NodeJs to search for a user in MongoDB by their telephone number using query routing. However, I am puzzled as to why this is not functioning properly

Can you identify the issue in this code? I am able to retrieve the correct mobile number on the console, but it is not being passed to the query routing on /search_user?mob. <input type="tel" name="message" id="mobile_input&qu ...

Get a Blob as a PNG File

Hope you had a wonderful Christmas holiday! Just to clarify, I am new to JS and may make some unconventional attempts in trying to download my Blob in PNG format. I am facing an issue with exporting all the visual content of a DIV in either PDF or image ...

Discover the Practical Utility of Maps beyond Hash Tables in Everyday Life

I am currently attempting to explain the concept of Maps (also known as hash tables or dictionaries) to someone who is a beginner in programming. While most people are familiar with the concepts of Arrays (a list of things) and Sets (a bag of things), I ...

I am having trouble figuring out the issue with the state and how to properly implement it in Typescript

I am having difficulties sending emails using Nodemailer, TypeScript, and NextJS. The contact.tsx file within the state component is causing errors when using setform. As a beginner in TypeScript, I have been unable to find a solution to this issue. Any he ...