How do I get the Mouseover Target's X&Y for a CreateJS Shape

82 Views Asked by At

I am trying to change the FILL COLOR of a SHAPE on Mouseover & Mouseout. Most examples I've seen use the events StageX and StageY coordinates. However, those coordinates are the X & Y positions of the mouse at the time of the event. This forces the object to suddently move when "redrawn".

Other examples ask you to call "GetBounds"...which is not available for Shape objects.

  • I don't want the object to move simply because I am changing the FillColor
  • I see nothing resembling the top/left in the EVENT.TARGET

Q: How do I calculate or retrieve the Shapes current X/Y (top/left) coordinates?

THE HTML & JAVASCRIPT:

<style>
    .dashboard { height:600px; }
    .dashboard header { }

    .dashboard aside { vertical-align:top; display:inline-block; }
    .dashboard aside.control-bar { border: solid 1px black; border-radius: 3px; padding: 5px; height: 100%; width:10%; margin-right: 5px; }

    .dashboard aside.control-bar {}
    .dashboard aside.control-bar .btn { width:95%; }

    .dashboard section { vertical-align:top; display:inline-block; }
    .dashboard section.desktop { height:100%; min-width:80%; border:solid 1px black; border-radius: 3px; }
    .dashboard section.desktop canvas { height:98%; width:99%; }

    .dashboard footer { margin-top:5px; padding:5px; }
</style>

<div class="row">
    <div class="col-md-12">
        <main role="main" class="dashboard pb-3">
            <header qwik-control="header">
                <h3>Dashboard</h3>
            </header>
            <aside class="control-bar">
                <center>
                    <h6>UI Controls</h6>
                    <a id="btnCreateNode" class="btn btn-sm btn-dark">Create Node</a>
                </center>
            </aside>
            <section class="desktop">
                <canvas id="demoCanvas"></canvas>
            </section>
            <footer>
                <center>
                    <h5 style="color:#C7C9CD;">Button Controls</h5>
                </center>
            </footer>
        </main>
    </div>
</div>

<script src="https://code.createjs.com/1.0.0/createjs.min.js"></script>
<script type="text/javascript">

    var stage = null,
        loader = null;

    // GLOBALS
    var _PROPERTIES = { node: { y: 100, x: 200, fillColor: '#F9FAFB', fillOverColor: '#FCFCC2', strokeColor: '#000' } };

    function node_create(){
        console.log('node_create');

        var top = Math.random() * 500;
        var left = Math.random() * 500;
        var width = _PROPERTIES.node.x;
        var height = _PROPERTIES.node.y;

        // Create
        var node = new createjs.Shape();
        node.graphics.beginStroke(_PROPERTIES.node.strokeColor);
        node.graphics.beginFill(_PROPERTIES.node.fillColor);
        node.graphics.setStrokeStyle(1);
        node.snapToPixel = true;
        node.graphics.drawRect(left, top, width, height);
        node.graphics.endFill();
        node.name = name;

        node.overColor = _PROPERTIES.node.fillOverColor;
        node.outColor = _PROPERTIES.node.fillColor;

        // Events
        node.on("mouseover", node_mouseover);
        node.on("mouseout", node_mouseout);

        // Display
        stage.addChild(node);
        stage.update();
    };

    function node_mouseover(evt) {
        console.log('node_mouseover');

        // COORDS is the events coordinates...not the targets Top/Left (e.g. cursor)
        // How do I get the X/Y of the target? (getBounds does not exist for Shapes)
        var target = evt.target;
        var coords = { x: evt.stageX, y: evt.stageY };

        target.graphics.clear();
        target.graphics.beginStroke(_PROPERTIES.node.strokeColor);
        target.graphics.beginFill(target.overColor);
        target.graphics.drawRect(coords.x, coords.y, _PROPERTIES.node.x, _PROPERTIES.node.y);
        target.graphics.endFill();
        stage.update();
    };

    function node_mouseout(evt) {
        console.log('node_mouseout');

        // COORDS is the events coordinates...not the targets Top/Left (e.g. cursor)
        // How do I get the X/Y of the target? (getBounds does not exist for Shapes)
        var target = evt.target;
        var coords = { x: evt.stageX, y: evt.stageY };

        target.graphics.clear();
        target.graphics.beginStroke(_PROPERTIES.node.strokeColor);
        target.graphics.beginFill(target.outColor);
        target.graphics.drawRect(coords.x, coords.y, _PROPERTIES.node.x, _PROPERTIES.node.y);
        target.graphics.endFill();
        stage.update();
    };

    $(document).ready(function () {

        // Stage
        stage = new createjs.Stage('demoCanvas');
        stage.canvas.width = window.innerWidth;
        stage.canvas.height = window.innerHeight;
        
        // Stage - Events
        stage.enableMouseOver(10);

        // Queue
        loader = new createjs.LoadQueue();

        // DOM - EVENTS
        $('#btnCreateNode').on('click', function(e){
            node_create();
        });
    });
</script>
1

There are 1 best solutions below

0
Prisoner ZERO On

The solution is to put your Shapes into a Container. Shapes don't have the same properties & methods useful in determining location that other objects do: like images or bitmaps etc.

As such...Containers are the "solution" to that.

THE JAVASCRIPT:

var _PROPERTIES = { node: { y: 100, x: 200, fillColor: '#F9FAFB', fillOverColor: '#FCFCC2', strokeColor: '#000' } };

function node_create(){
    console.log('node_create');

    var top = Math.random() * 500;
    var left = Math.random() * 500;
    var width = _PROPERTIES.node.x;
    var height = _PROPERTIES.node.y;

    // Create
    var node = new createjs.Shape();
    node.graphics.beginStroke(_PROPERTIES.node.strokeColor);
    node.graphics.beginFill(_PROPERTIES.node.fillColor);
    node.graphics.setStrokeStyle(1);
    node.snapToPixel = true;
    node.graphics.drawRect(0, 0, width, height); //<-- changed
    node.graphics.endFill();
    node.name = name;

    node.overColor = _PROPERTIES.node.fillOverColor; //<-- added
    node.outColor = _PROPERTIES.node.fillColor; //<-- added

    // Events
    node.on("mouseover", node_mouseover);
    node.on("mouseout", node_mouseout);

    // Container
    var container = new createjs.Container(); //<-- added
    container.x = top;
    container.y = left;
    container.addChild(node);

    // Display
    stage.addChild(container); //<-- changed
    stage.update();
};

function node_mouseover(evt) {
    console.log('node_mouseover');

    // Because of the container...you no longer need to calculate a TOP or LEFT
    var target = evt.target;
    target.graphics.clear();
    target.graphics.beginStroke(_PROPERTIES.node.strokeColor);
    target.graphics.beginFill(target.overColor);
    target.graphics.drawRect(0, 0, _PROPERTIES.node.x, _PROPERTIES.node.y); //<-- changed
    target.graphics.endFill();
    stage.update();
};

function node_mouseout(evt) {
    console.log('node_mouseout');

    // Because of the container...you no longer need to calculate a TOP or LEFT
    var target = evt.target;
    target.graphics.clear();
    target.graphics.beginStroke(_PROPERTIES.node.strokeColor);
    target.graphics.beginFill(target.outColor);
    target.graphics.drawRect(0, 0, _PROPERTIES.node.x, _PROPERTIES.node.y); //<-- changed
    target.graphics.endFill();
    stage.update();
};