Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions src/data/mazeFilters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
class TileFilter
{
constructor(tiles)
{
this.tiles = new Set(tiles.map( ({r,g,b})=>(r<<16) + (g<<8) + b ) );
}
isMatch(r, g, b)
{
if(g == undefined || b == undefined) return this.tiles.has(r);
const hexCode = (r<<16) + (g<<8) + b;
return this.tiles.has(hexCode);
}
}

const mazeFilters = {
STONE : new TileFilter([
new Tile("Stone Wall", 73, 103, 125),
new Tile("Stone Ground", 103, 131, 151),
new Tile("Dark Stone Ground", 123, 140, 172),
new Tile("Iron Ore", 130, 155, 203),
new Tile("Stone Moss", 207, 241, 255)
]),
CLAY : new TileFilter([
new Tile("Clay Wall", 193, 100, 54),
new Tile("Clay Ground", 232, 139, 105),
new Tile("Tin Ore", 142, 122, 118),
new Tile("Chrysalis", 252, 166, 148),
new Tile("Clay Moss", 126, 87, 78)
]),
WILDERNESS : new TileFilter([
new Tile("Grass Wall", 22, 131, 27),
new Tile("Grass Ground", 61, 155, 65),
new Tile("Tilled Grass Ground", 12, 115, 43),
new Tile("Scarlet Ore", 206, 59, 59),
new Tile("Ground Poison Slime", 184, 86, 165),
new Tile("Lush Moss", 163, 206, 74)
]),
SEA : new TileFilter([
new Tile("Limestone Wall", 180, 147, 154),
new Tile("City Wall", 49, 77, 87),
new Tile("Beach Sand Ground", 235, 192, 190),
new Tile("City Floor", 87, 128, 132),
new Tile("Octarine Ore", 139, 82, 238),
new Tile("Sea Water", 52, 208, 255),
new Tile("Ground Slippery Slime", 47, 47, 255),
new Tile("Urban Moss", 42, 210, 62)
])
};
4 changes: 2 additions & 2 deletions src/data/pois.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ function toggleTile(tile) {
Alpine.store('tilecolormap').visible = Alpine.store('tilecolormap').visible.filter((e) => e.name != tile.name);

tile.disabled = true;
redrawMap();
redrawMapDirty();
tile.disabled = false;
}

Expand All @@ -133,6 +133,6 @@ function toggleCategoryTiles(tiles) {
Alpine.store('tilecolormap').visible = Alpine.store('tilecolormap').visible.filter((e) => e.name != tile.name);
}

redrawMap();
redrawMapDirty();
tiles.forEach(tile => { tile.disabled = false; });
}
1 change: 1 addition & 0 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<script src="js/pako-inflate-2.0.4.min.js"></script>
<script src="data/pois.js"></script>
<script src="data/tilecolormap.js"></script>
<script src="data/mazeFilters.js"></script>
<script src="js/maploader.js"></script>
<script src="js/canvastools.js"></script>
<script src="js/mapmonitor.js"></script>
Expand Down
195 changes: 76 additions & 119 deletions src/js/canvastools.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
// include { buildHighlightSelection } from "./menubuilder.js";

let currentZoom = 1
let MAX_ZOOM = 12;
let MIN_ZOOM = 0.1;
let _image_cache = undefined;
let cameraOffset = { x: 0, y: 0 }
let _image_pixelData = null;
let _decorated_pixelData = null;
let cameraOffset = { x: 0, y: 0 };
let previousCoreRelativeOffset = undefined;
let _global_ctx;
let coreLoc = { x: 0, y: 0 };
let pixelMap = {};
let panZoomElem;

function getCanvasPixelData()
{
if(!_image_pixelData)
{
_image_pixelData = _global_ctx.getImageData(0, 0, canvas.width, canvas.height);
return _image_pixelData;
}
const cloneData = new Uint8ClampedArray(_image_pixelData.data);
const clone = new ImageData(cloneData, _image_pixelData.width, _image_pixelData.height);
return clone;
}

function panImage(dx, dy) {
cameraOffset.x += dx;
cameraOffset.y += dy;
Expand Down Expand Up @@ -106,10 +122,11 @@ function zoomWithMouseWheel(event) {


panZoomElem.zoomToPoint(targetScale, event, opts);
const mapCanvas = document.getElementById('mapcanvas');
if (panZoomElem.getScale() < 1.0) {
document.getElementById("mapcanvas").style.imageRendering = "auto";
mapCanvas.style.imageRendering = "auto";
} else {
document.getElementById("mapcanvas").style.imageRendering = "pixelated";
mapCanvas.style.imageRendering = "pixelated";
}
storeCoreRelativeOffset();
}
Expand All @@ -126,19 +143,25 @@ function setContext(ctx, width, height) {
}

function redrawMap() {
const canvas = document.getElementById("mapcanvas");
setContext(_global_ctx, canvas.width, canvas.height);
const mapCanvas = document.getElementById('mapcanvas');
setContext(_global_ctx, mapCanvas.width, mapCanvas.height);
_global_ctx.putImageData(_decorated_pixelData, 0, 0);
decorateMap(mapCanvas.width, mapCanvas.height);
}

function redrawMapDirty() {
const mapCanvas = document.getElementById('mapcanvas');
setContext(_global_ctx, mapCanvas.width, mapCanvas.height);
_global_ctx.drawImage(_image_cache, 0, 0);
decorateMap(canvas.width, canvas.height);
highlightSelected();
decorateMap(mapCanvas.width, mapCanvas.height);
}

function loop(val, min, max) {
return (val >= min && val <= max) ? val : ((val < max) ? max - Math.abs(val) % max + 1 : min + Math.abs(val) % 10 - 1);
}

function decorateMap(width, height) {
highlightSelected();

const showArcsCheckbox = document.getElementById("showArcs");

if (showArcsCheckbox.checked) {
Expand Down Expand Up @@ -327,7 +350,7 @@ function drawMap(tiles) {
}
coreLoc.x = -minx * TILE_SIZE;
coreLoc.y = (maxy + 1) * TILE_SIZE;
const canvas = document.getElementById("mapcanvas");
const canvas = document.getElementById('mapcanvas');
canvas.width = (maxx - minx + 1) * TILE_SIZE;
canvas.height = (maxy - miny + 1) * TILE_SIZE;
// const ctx = canvas.getContext('2d', { willReadFrequently: true });
Expand All @@ -342,8 +365,11 @@ function drawMap(tiles) {
_global_ctx.drawImage(tiles[i].image, px, py);
}
}
// cache original image
_image_cache = new Image();
_image_cache.src = canvas.toDataURL();
_image_pixelData = ctx.getImageData(0, 0, canvas.width, canvas.height);
_decorated_pixelData = _image_pixelData;

if (previousCoreRelativeOffset) {
panToPreviousCoreRelativeOffset();
Expand All @@ -354,138 +380,69 @@ function drawMap(tiles) {

Alpine.store('data').mapLoaded = true;
Alpine.store('data').firstTimeLoaded = true;
highlightSelected();
decorateMap(canvas.width, canvas.height);
}

function highlightSelected() {
let searchobj = { count: 0, boulders: {} };

buildHighlightSelection(searchobj);

const canvas = document.getElementById("mapcanvas");
const myImage = _global_ctx.getImageData(0, 0, canvas.width, canvas.height);
_decorated_pixelData = getCanvasPixelData();

if (searchobj.count > 0) {
highlightColors(myImage, searchobj);
}
const filters = buildHighlightSelection();
if(filters) highlightColors(_decorated_pixelData, filters);

if (Alpine.store('data').showMazeHoles) {
findStone(myImage.data, canvas.width);
findHole(_decorated_pixelData.data, _decorated_pixelData.width);
}
_global_ctx.putImageData(myImage, 0, 0);
_global_ctx.putImageData(_decorated_pixelData, 0, 0);
}

function recenterMap() {
panZoomElem.zoom(1, { animate: true });
panToCore();
}

function testPixel(width, myImageData, r, g, b, x, y) {
let i = (y * width + x) * 4;
let r1 = myImageData[i], g1 = myImageData[i + 1], b1 = myImageData[i + 2];

return (r == r1 && g == g1 && b == b1);
}

function highlightPixel(width, myImageData, x, y) {
let i = (y * width + x) * 4;
myImageData[i + 3] = 255;
}

function testBoulder(width, myImageData, r, g, b, x, y, x1, y1) {
let i = (y * width + x) * 4;
let count = 0;
if (testPixel(width, myImageData, r, g, b, x1, y1)) {
count++;
}
if (testPixel(width, myImageData, r, g, b, x, y1)) {
count++;
}
if (testPixel(width, myImageData, r, g, b, x1, y)) {
count++;
}
if (count == 3) {
highlightPixel(width, myImageData, x1, y1);
highlightPixel(width, myImageData, x, y1);
highlightPixel(width, myImageData, x1, y);
highlightPixel(width, myImageData, x, y);
} else if (myImageData[i + 3] != 255) {
let alpha = Alpine.store('data').tileTransparency / 100 * 255;
myImageData[i + 3] = alpha;
function highlightColors(imageData, {normal, boulders})
{
const {data:pixelArray, width} = imageData;
const alpha = Alpine.store('data').tileTransparency / 100 * 255;
const length = pixelArray.length;

for (let i = 0; i < length; i += 4) {
if (pixelArray[i + 3] === 0) continue;
const r = pixelArray[i], g = pixelArray[i+1], b = pixelArray[i+2];
pixelArray[i + 3] = normal.isMatch(r,g,b) ? 255 : alpha;
if(boulders.isMatch(r,g,b)) highlightBoulders(imageData, i);
}
}

function highlightBoulder(myImage, r, g, b, x, y) {
const myImageData = myImage.data;
let count = 0;

count = 0;
/*if (x > 0 && y > 0) {
testBoulder(myImage.width, myImageData, r, g, b, x, y, x - 1, y - 1);
function checkBoulders(imageData, x, y)
{
const {data:pixelArray, width, height} = imageData;
function getHexCode(x, y)
{
const i = (y*width + x)*4;
return pixelArray[i] << 16 + pixelArray[i+1] << 8 + pixelArray[i+2];
}
//test bottom left
if (x > 0 && y < myImage.height) {
testBoulder(myImage.width, myImageData, r, g, b, x, y, x - 1, y + 1);
}*/
//test bottom right
if (x < myImage.width && y < myImage.height) {
testBoulder(myImage.width, myImageData, r, g, b, x, y, x + 1, y + 1);
}/*
if (x < myImage.width && y > 0) {
testBoulder(myImage.width, myImageData, r, g, b, x, y, x + 1, y - 1);
}*/
}

function highlightColors(myImage, search) {
const myImageData = myImage.data;
let alpha = Alpine.store('data').tileTransparency / 100 * 255;

for (let i = 0; i < myImageData.length; i += 4) {
if (myImageData[i + 3] != 0) { //if not transparent
let r = myImageData[i], g = myImageData[i + 1], b = myImageData[i + 2];
if (search[r] && search[r][g] && search[r][g][b]) {
myImageData[i + 3] = 255;
} else {
myImageData[i + 3] = alpha;
}
}
}
for (let i = 0, p = 0; i < myImageData.length; i += 4, ++p) {
if (myImageData[i + 3] != 0) { //if not transparent

let x = parseInt(p % myImage.width);
let y = parseInt(p / myImage.width);
let r = myImageData[i], g = myImageData[i + 1], b = myImageData[i + 2];
if (search.boulders[r] && search.boulders[r][g] && search.boulders[r][g][b]) {
highlightBoulder(myImage, r, g, b, x, y);
}
}
}
if(x-1 >= width || y-1 >= height) return false;
const baseHex = getHexCode(x, y);
if(getHexCode(x+1, y) !== baseHex || getHexCode(x, y+1) !== baseHex || getHexCode(x+1, y+1) !== baseHex) return false;
return true;
}

function _highlightColors(myImage, search) {
const myImageData = myImage.data;
let alpha = Math.max(TileSliderInfo.transparency(), 1);

for (let i = 0; i < myImageData.length; i += 4) {
if (myImageData[i + 3] != 0) { //if not transparent
let r = myImageData[i], g = myImageData[i + 1], b = myImageData[i + 2];
if (search[r] && search[r][g] && search[r][g][b]) {
myImageData[i + 3] = 255;
} else {
myImageData[i + 3] = alpha;
}
}
}
for (let i = 0, p = 0; i < myImageData.length; i += 4, ++p) {
if (myImageData[i + 3] != 0) { //if not transparent

let x = parseInt(p % myImage.width);
let y = parseInt(p / myImage.width);
let r = myImageData[i], g = myImageData[i + 1], b = myImageData[i + 2];
if (search.boulders[r] && search.boulders[r][g] && search.boulders[r][g][b]) {
highlightBoulder(myImage, r, g, b, x, y);
}
function highlightBoulders(imageData, i)
{
const {data:pixelArray, width, height} = imageData;
const x = (i/4) % width;
const y = Math.floor((i/4) / width);

if(!checkBoulders(imageData, x, y)) return;
for(let dx=0; dx<2; dx++)
{
for(let dy=0; dy<2; dy++)
{
let index = ((y+dy)*width + x+dx)*4 + 3;
pixelArray[index] = 255
}
}
}
Loading