Элементы зависания в Canvas - PullRequest
0 голосов
/ 01 сентября 2018

У меня довольно простая задача. Но я застрял. Смысл в том, чтобы сделать два элемента одинаковыми по цвету, например «салатовый», когда один элемент находится над другим, и вернуться к своему собственному, когда зависание выполнено.

Вот код CodePen .

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>Document</title>
    <style>
        body {
            margin: 0;padding: 20px;
            height: 100vh;
            box-sizing: border-box;

        }

        canvas {
            margin: 0px;
        }
    </style>
</head>
<body>
    <canvas id="canvas"></canvas>
    <script defer src="./app.js"></script>
</body>
</html>

var cnv = document.getElementById("canvas");
var ctx = cnv.getContext("2d");
var width = document.body.clientWidth - 40;
var height = document.body.clientHeight - 40;
cnv.width = width
cnv.height = height;
cnv.style.backgroundColor = '#ffa500';

// Draw Figure Method
var drawFigure = function(objectList, color) { 

    for ( var i = 0; i<objectList.length; i++) {

        if ( objectList[i].type === "rect") {
            ctx.fillRect(objectList[i].x,objectList[i].y,objectList[i].w,objectList[i].h);
            ctx.strokeRect(objectList[i].x,objectList[i].y,objectList[i].w,objectList[i].h);
            ctx.fillStyle = objects[i].fillColor;

        }
    }
}


// Objects
var objects = [
    {
        type: "rect",
        name: "One",
        w: 100,
        h: 100,
        x: 50,
        y: 50,
        fillColor: "#FF0000"
    },
    {
        type: "rect",
        w: 100,
        name: "Two",
        h: 100,
        x: 50,
        y: 160,
        fillColor: "#0000ff"
    },
    {
        type: "rect",
        name: "Two-Two",
        w: 100,
        h: 100,
        x: 50,
        y: 270,
        fillColor: "#8a2be2"
    },
]


window.onload = function () {
    drawFigure(objects);
}


cnv.addEventListener("mousedown", onDown, false);

var selectedItem;
function onDown(e) {
    cx = e.pageX;
    cy = e.pageY;

    for ( var i = 0; i<objects.length; i++) {
        if ( cx > objects[i].x && cy > objects[i].y && cx < (objects[i].x + objects[i].w) && cy < (objects[i].y + objects[i].h) ) {
            selectedItem = objects[i];
        }
    }
    console.log (selectedItem)
    cnv.addEventListener("mousemove", onMove, false);
}

function onMove(e) {
    cx = e.pageX;
    cy = e.pageY;
    selectedItem.x = cx - (selectedItem.w / 2) -15;
    selectedItem.y = cy - (selectedItem.h / 2) -15;

    if ( selectedItem.x == 0 || selectedItem.x < 0 ) {
        console.log("EDGE");
        selectedItem.x = 0;
        return
    }

    else if ( (selectedItem.x + selectedItem.w) == (cnv.height) || (selectedItem.x + selectedItem.w) > (cnv.width) ) {
        console.log("EDGE");
        selectedItem.y = cnv.w;
        return
    }

    else if ( selectedItem.y == 0 || selectedItem.y < 0 ) {
        console.log("EDGE");
        selectedItem.y = 0;
        return
    }

    else if ( (selectedItem.y + selectedItem.h) == (cnv.height) || (selectedItem.y + selectedItem.h) > (cnv.height) ) {
        console.log("EDGE");
        selectedItem.y = cnv.height;
        return
    }


    for ( var i = 0; i<objects.length; i++) {
        if( selectedItem == objects[i]) {
            continue
        }
         if ((selectedItem.x + selectedItem.w) > objects[i].x && selectedItem.x > objects[i].x && selectedItem.x < (objects[i].x + objects[i].w)) {
            console.log( "Hovering");

           // Here is the spot. While it is hovering both need to be changed to same color, and back to it's own when hovering is gone.
        }

    }

    ctx.clearRect(0, 0, cnv.width, cnv.height);
    drawFigure(objects);
}

cnv.addEventListener("mouseup", onUp, false);

function onUp(e) {
    cnv.removeEventListener("mousemove", onMove);
}

1 Ответ

0 голосов
/ 01 сентября 2018

Посмотрите на фрагмент ниже ...
это ваш код, но я удалил все, что не нужно для вашей проблемы.

Я подталкиваю вас в правильном направлении, теперь квадраты меняют цвет при наведении, но условие смотрит только на X, вам нужно добавить Y и проверить на потенциальные ошибки

<style> * { margin: 0px; } </style>
<canvas id="canvas"></canvas>

<script>
var cnv = document.getElementById("canvas");
var ctx = cnv.getContext("2d");
cnv.width = cnv.height = 500;

var objects = [
    { w: 60, h: 60, x: 10,   y: 20, fillColor: "black" },
    { w: 60, h: 60, x: 120,  y: 20, fillColor: "blue" },
    { w: 60, h: 60, x: 240,  y: 20, fillColor: "red" },
]

var selectedItem;
function onMove(e) {
  if (selectedItem) {
    cx = e.pageX;  cy = e.pageY;
    selectedItem.x = cx - (selectedItem.w / 2) -15;
    selectedItem.y = cy - (selectedItem.h / 2) -15;
    var hovering = false
    objects.forEach(function(o) {
      if (o != selectedItem) {
        if ((selectedItem.x + selectedItem.w) >o.x && selectedItem.x >o.x && selectedItem.x < (o.x +o.w)) {
          hovering = true
        }
      }
    })
    if (hovering) {
      if (selectedItem.fillColor != "lime") {
        selectedItem.color = selectedItem.fillColor
        selectedItem.fillColor = "lime"
      }      
    } else if (selectedItem.color) {
      selectedItem.fillColor = selectedItem.color
    }
    ctx.clearRect(0, 0, cnv.width, cnv.height);
    drawFigure();
  }
}

function onDown(e) {
    cx = e.pageX; cy = e.pageY;    
    objects.forEach(function(o) {
        if ( cx >o.x && cy >o.y && cx < (o.x +o.w) && cy < (o.y +o.h) ) {
            selectedItem =o;
        }
    });
}

function drawFigure() { 
  objects.forEach(function(o) {
    ctx.fillStyle = o.fillColor;
    ctx.fillRect(o.x,o.y,o.w,o.h);
    ctx.strokeRect(o.x,o.y,o.w,o.h);
  });
}

window.onload = drawFigure
cnv.addEventListener("mousemove", onMove, false);
cnv.addEventListener("mousedown", onDown, false);
cnv.addEventListener("mouseup", function () { selectedItem = null });

</script>
...