如何在鼠标结束时更改画布图块的颜色?

时间:2017-10-24 17:12:34

标签: javascript jquery canvas

当用户将鼠标悬停在图块上时,我正在尝试更改图块的颜色。喜欢美白瓷砖。我正在使用32x32瓷砖的瓷砖组。这是脚本。

MAP.JS

    function Map(nom) {
    var xhr = getXMLHttpRequest();

    xhr.open("GET", '/maps/' + nom + '.json', false);
    xhr.send(null);
    if(xhr.readyState != 4 || (xhr.status != 200 && xhr.status != 0)) // Code == 0 en local
        throw new Error("Impossible de charger la carte nommée \"" + nom + "\" (code HTTP : " + xhr.status + ").");
    var mapJsonData = xhr.responseText;

    var mapData = JSON.parse(mapJsonData);
    this.tileset = new Tileset(mapData.tileset);
    this.terrain = mapData.terrain;
}

Map.prototype.getHauteur = function() {
    return this.terrain.length;
}
Map.prototype.getLargeur = function() {
    return this.terrain[0].length;
}

Map.prototype.dessinerMap = function(context) {
    for(var i = 0, l = this.terrain.length ; i < l ; i++) {
        var ligne = this.terrain[i];
        var y = i * 32;
        for(var j = 0, k = ligne.length ; j < k ; j++) {
            this.tileset.dessinerTile(ligne[j], context, j * 32, y);
        }
    }
}

TILESET.JS

function Tileset(url) {
    this.image = new Image();
    this.image.referenceDuTileset = this;
    this.image.onload = function() {
        if(!this.complete) 
            throw new Error("Erreur de chargement du tileset nommé \"" + url + "\".");

        this.referenceDuTileset.largeur = this.width / 32;
    }
    this.image.src = "/tilesets/" + url;
}


Tileset.prototype.dessinerTile = function(numero, context, xDestination, yDestination) {
    var xSourceEnTiles = numero % this.largeur;
    if(xSourceEnTiles == 0) xSourceEnTiles = this.largeur;
    var ySourceEnTiles = Math.ceil(numero / this.largeur);

    var xSource = (xSourceEnTiles - 1) * 32;
    var ySource = (ySourceEnTiles - 1) * 32;

    context.drawImage(this.image, xSource, ySource, 32, 32, xDestination, yDestination, 32, 32);
}

MAPDRAW.JS

    var canvas = document.getElementById('canvas');
var map = new Map(canvas.className);

window.onload = function() {
    var ctx = canvas.getContext('2d');

    canvas.width  = map.getLargeur() * 32;
    canvas.height = map.getHauteur() * 32;

    map.dessinerMap(ctx);

}

使用CANVAS的PHP PAGE

<canvas class="deuxieme" id="canvas"></canvas>
<!--[if lt IE 9]><script type="text/javascript" src="/js/excanvas.compiled.js"></script><![endif]-->
<script type="text/javascript" src="/js/oXHR.js"></script>
<script type="text/javascript" src="/js/classes/Tileset.js"></script>
<script type="text/javascript" src="/js/classes/Map.js"></script>
<script type="text/javascript" src="/js/mapdraw.js"></script>

如果你也有时间,我想知道是否有办法知道用户正在使用鼠标的磁贴数量。 (例如,如果那是瓷砖3(32x32 n°3),我希望瓷砖在用户指向时为黑色,如果是另一个瓷砖则为白色。

至于现在,我只是试过这个:

    canvas.onmousemove = function(e) {

    var rects = [
        {x: 0, y: 0, w: 32, h: 32},

    ], i = 0, r;

    // important: correct mouse position:
    var rect = this.getBoundingClientRect(),
        x = e.clientX - rect.left,
        y = e.clientY - rect.top;

    while(r = rects[i++]) {

        // add a single rect to path:
        ctx.beginPath();
        ctx.rect(r.x, r.y, 32, 32);

        // check if we hover it, fill red, if not fill it blue
        if (ctx.isPointInPath(x, y)) {
            ctx.fillStyle = "red";
            ctx.fill();
        }
        else {
            ctx.fillStyle = "blue";
            ctx.fill();
        }
    }
    };

这主要来自教程,所以它根本不适合我的代码。 我现在正在寻找的是一种让图像返回而不是填充的方法:蓝色和一种定位每个瓷砖的方法,而不必编写每个瓷砖。

1 个答案:

答案 0 :(得分:0)

这种实验性技术addHitRegion可以为您提供帮助,但不幸的是并不适用于所有浏览器:

https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/addHitRegion

如果不使用它,那么你需要自己计算命中率。首先,您需要在画布中为mousemove添加一个事件侦听器,然后您需要手动检查命中。

您将需要学习相对于画布的鼠标事件位置(尝试搜索相对于元素的鼠标位置)。

之后,您需要自己进行计算。如果你有一个顶部,左边,宽度和高度的矩形,看看是否有一个点(x,y),你需要检查:

if (x >= left && x < left + width && y >= top && y < top + height) {
   // hit
}