JSFiddle - React, Tailwind, and code Playground

HTML

<div id="d"></div>

CSS

#d {
    position: absolute;
    top: 0px;
    left: 0px;
    width: 300px;
    height: 300px;
    background-color: #4679BD;
}

JavaScript

var stage = new Kinetic.Stage({
    container: 'd',
    width: 300,
    height: 300
});

var layer = new Kinetic.Layer();
var isDragging = false;
var refRotation = null;

var messageLayer = new Kinetic.Layer();

var sprite = new Image();
var imgK = null;
sprite.onload = function () {
    imgK = new Kinetic.Image({
        x: 150,
        y: 150,
        width: 136,
        height: 24,
        offset: [78, 12],
        image: sprite,
        dragOnTop: true,
        draggable: true,
        dragBoundFunc: function (pos) {
            var mouse = stage.getMousePosition();
            var xd = 150 - mouse.x ;
            var yd = 150 - mouse.y ;
            var theta = Math.atan2(yd, xd);
            var degree = theta / (Math.PI / 180);
            
            if(!isDragging) {
                isDragging = true;
                refRotation = degree;
            } else {
                this.setRotationDeg(degree - refRotation);
                writeMessage(messageLayer, 'deg:' + (degree - refRotation));
            }

            return {
                x: this.getAbsolutePosition().x,
                y: this.getAbsolutePosition().y
            }
        }
    });

    imgK.on('dragend', function() {
        isDragging = false;
        imgK.setRotationDeg(0);
        layer.draw();
        writeMessage(messageLayer, 'dragend');
    });
    
    layer.add(imgK);
    stage.add(messageLayer);
    stage.add(layer);
};
sprite.src = '/img/logo.png';

function writeMessage(messageLayer, message) {
    var context = messageLayer.getContext();
    messageLayer.clear();
    context.font = '18pt Calibri';
    context.fillStyle = 'black';
    context.fillText(message, 10, 25);
}