src/plugins/NavCubePlugin/CubeTextureCanvas.js
import {math} from "../../viewer/scene/math/math.js";
/**
* @private
*/
function CubeTextureCanvas(viewer, navCubeScene, cfg = {}) {
const cubeColor = "lightgrey";
const cubeHighlightColor = cfg.hoverColor || "rgba(0,0,0,0.4)";
const textColor = cfg.textColor || "black";
const height = 500;
const width = height + (height / 3);
const scale = width / 24;
const facesZUp = [
{boundary: [6, 6, 6, 6], color: cfg.frontColor || cfg.color || "#55FF55"},
{boundary: [18, 6, 6, 6], color: cfg.backColor || cfg.color || "#55FF55"},
{boundary: [12, 6, 6, 6], color: cfg.rightColor || cfg.color || "#FF5555"},
{boundary: [0, 6, 6, 6], color: cfg.leftColor || cfg.color || "#FF5555"},
{boundary: [6, 0, 6, 6], color: cfg.topColor || cfg.color || "#7777FF"},
{boundary: [6, 12, 6, 6], color: cfg.bottomColor || cfg.color || "#7777FF"}
];
const areasZUp = [
{label: "NavCube.front", boundaries: [[7, 7, 4, 4]], dir: [0, 1, 0], up: [0, 0, 1]},
{label: "NavCube.back", boundaries: [[19, 7, 4, 4]], dir: [0, -1, 0], up: [0, 0, 1]},
{label: "NavCube.right", boundaries: [[13, 7, 4, 4]], dir: [-1, 0, 0], up: [0, 0, 1]},
{label: "NavCube.left", boundaries: [[1, 7, 4, 4]], dir: [1, 0, 0], up: [0, 0, 1]},
{label: "NavCube.top", boundaries: [[7, 1, 4, 4]], dir: [0, 0, -1], up: [0, 1, 0]},
{label: "NavCube.bottom", boundaries: [[7, 13, 4, 4]], dir: [0, 0, 1], up: [0, -1, 0]},
{boundaries: [[7, 5, 4, 2]], dir: [0, 1, -1], up: [0, 1, 1]},
{boundaries: [[1, 6, 4, 1], [6, 1, 1, 4]], dir: [1, 0, -1], up: [1, 0, 1]},
{boundaries: [[7, 0, 4, 1], [19, 6, 4, 1]], dir: [0, -1, -1], up: [0, -1, 1]},
{boundaries: [[13, 6, 4, 1], [11, 1, 1, 4]], dir: [-1, 0, -1], up: [-1, 0, 1]},
{boundaries: [[7, 11, 4, 2]], dir: [0, 1, 1], up: [0, -1, 1]},
{boundaries: [[1, 11, 4, 1], [6, 13, 1, 4]], dir: [1, 0, 1], up: [-1, 0, 1]},
{boundaries: [[7, 17, 4, 1], [19, 11, 4, 1]], dir: [0, -1, 1], up: [0, 1, 1]},
{boundaries: [[13, 11, 4, 1], [11, 13, 1, 4]], dir: [-1, 0, 1], up: [1, 0, 1]},
{boundaries: [[5, 7, 2, 4]], dir: [1, 1, 0], up: [0, 0, 1]},
{boundaries: [[11, 7, 2, 4]], dir: [-1, 1, 0], up: [0, 0, 1]},
{boundaries: [[17, 7, 2, 4]], dir: [-1, -1, 0], up: [0, 0, 1]},
{boundaries: [[0, 7, 1, 4], [23, 7, 1, 4]], dir: [1, -1, 0], up: [0, 0, 1]},
{boundaries: [[5, 11, 2, 2]], dir: [1, 1, 1], up: [-1, -1, 1]},
{boundaries: [[23, 11, 1, 1], [6, 17, 1, 1], [0, 11, 1, 1]], dir: [1, -1, 1], up: [-1, 1, 1]},
{boundaries: [[5, 5, 2, 2]], dir: [1, 1, -1], up: [1, 1, 1]},
{boundaries: [[11, 17, 1, 1], [17, 11, 2, 1]], dir: [-1, -1, 1], up: [1, 1, 1]},
{boundaries: [[17, 6, 2, 1], [11, 0, 1, 1]], dir: [-1, -1, -1], up: [-1, -1, 1]},
{boundaries: [[11, 11, 2, 2]], dir: [-1, 1, 1], up: [1, -1, 1]},
{boundaries: [[0, 6, 1, 1], [6, 0, 1, 1], [23, 6, 1, 1]], dir: [1, -1, -1], up: [1, -1, 1]},
{boundaries: [[11, 5, 2, 2]], dir: [-1, 1, -1], up: [-1, 1, 1]}
];
const facesYUp = [
{boundary: [6, 6, 6, 6], color: cfg.frontColor || cfg.color || "#55FF55"},
{boundary: [18, 6, 6, 6], color: cfg.backColor || cfg.color || "#55FF55"},
{boundary: [12, 6, 6, 6], color: cfg.rightColor || cfg.color || "#FF5555"},
{boundary: [0, 6, 6, 6], color: cfg.leftColor || cfg.color || "#FF5555"},
{boundary: [6, 0, 6, 6], color: cfg.topColor || cfg.color || "#7777FF"},
{boundary: [6, 12, 6, 6], color: cfg.bottomColor || cfg.color || "#7777FF"}
];
const areasYUp = [
// Faces
{yUp: "", label: "NavCube.front", boundaries: [[7, 7, 4, 4]], dir: [0, 0, -1], up: [0, 1, 0]},
{label: "NavCube.back", boundaries: [[19, 7, 4, 4]], dir: [0, 0, 1], up: [0, 1, 0]},
{label: "NavCube.right", boundaries: [[13, 7, 4, 4]], dir: [-1, 0, 0], up: [0, 1, 0]},
{label: "NavCube.left", boundaries: [[1, 7, 4, 4]], dir: [1, 0, 0], up: [0, 1, 0]},
{label: "NavCube.top", boundaries: [[7, 1, 4, 4]], dir: [0, -1, 0], up: [0, 0, -1]},
{label: "NavCube.bottom", boundaries: [[7, 13, 4, 4]], dir: [0, 1, 0], up: [0, 0, 1]},
{boundaries: [[7, 5, 4, 2]], dir: [0, -0.7071, -0.7071], up: [0, 0.7071, -0.7071]}, // Top-front edge
{boundaries: [[1, 6, 4, 1], [6, 1, 1, 4]], dir: [1, -1, 0], up: [1, 1, 0]}, // Top-left edge
{boundaries: [[7, 0, 4, 1], [19, 6, 4, 1]], dir: [0, -0.7071, 0.7071], up: [0, 0.7071, 0.7071]}, // Top-back edge
{boundaries: [[13, 6, 4, 1], [11, 1, 1, 4]], dir: [-1, -1, 0], up: [-1, 1, 0]}, // Top-right edge
{boundaries: [[7, 11, 4, 2]], dir: [0, 1, -1], up: [0, 1, 1]}, // Bottom-front edge
{boundaries: [[1, 11, 4, 1], [6, 13, 1, 4]], dir: [1, 1, 0], up: [-1, 1, 0]}, // Bottom-left edge
{boundaries: [[7, 17, 4, 1], [19, 11, 4, 1]], dir: [0, 1, 1], up: [0, 1, -1]}, // Bottom-back edge
{boundaries: [[13, 11, 4, 1], [11, 13, 1, 4]], dir: [-1, 1, 0], up: [1, 1, 0]}, // Bottom-right edge
{boundaries: [[5, 7, 2, 4]], dir: [1, 0, -1], up: [0, 1, 0]},// Front-left edge
{boundaries: [[11, 7, 2, 4]], dir: [-1, 0, -1], up: [0, 1, 0]}, // Front-right edge
{boundaries: [[17, 7, 2, 4]], dir: [-1, 0, 1], up: [0, 1, 0]},// Back-right edge
{boundaries: [[0, 7, 1, 4], [23, 7, 1, 4]], dir: [1, 0, 1], up: [0, 1, 0]},// Back-left edge
{boundaries: [[5, 11, 2, 2]], "dir": [0.5, 0.7071, -0.5], "up": [-0.5, 0.7071, 0.5]}, // Bottom-left-front corner
{boundaries: [[23, 11, 1, 1], [6, 17, 1, 1], [0, 11, 1, 1]],"dir": [0.5, 0.7071, 0.5],"up": [-0.5, 0.7071, -0.5]},// Bottom-back-left corner
{boundaries: [[5, 5, 2, 2]], "dir": [0.5, -0.7071, -0.5], "up": [0.5, 0.7071, -0.5]}, // Left-front-top corner
{boundaries: [[11, 17, 1, 1], [17, 11, 2, 1]], "dir": [-0.5, 0.7071, 0.5], "up": [0.5, 0.7071, -0.5]}, // Bottom-back-right corner
{boundaries: [[17, 6, 2, 1], [11, 0, 1, 1]], "dir": [-0.5, -0.7071, 0.5], "up": [-0.5, 0.7071, 0.5]}, // Top-back-right corner
{boundaries: [[11, 11, 2, 2]], "dir": [-0.5, 0.7071, -0.5], "up": [0.5, 0.7071, 0.5]}, // Bottom-front-right corner
{boundaries: [[0, 6, 1, 1], [6, 0, 1, 1], [23, 6, 1, 1]], "dir": [0.5, -0.7071, 0.5], "up": [0.5, 0.7071, 0.5]},// Top-back-left corner
{boundaries: [[11, 5, 2, 2]], "dir": [-0.5, -0.7071, -0.5], "up": [-0.5, 0.7071, -0.5]}// Top-front-right corner
];
for (let i = 0, len = areasZUp.length; i < len; i++) {
math.normalizeVec3(areasZUp[i].dir, areasZUp[i].dir);
math.normalizeVec3(areasZUp[i].up, areasZUp[i].up);
}
for (let i = 0, len = areasYUp.length; i < len; i++) {
math.normalizeVec3(areasYUp[i].dir, areasYUp[i].dir);
math.normalizeVec3(areasYUp[i].up, areasYUp[i].up);
}
var faces = facesYUp;
var areas = areasYUp;
this._textureCanvas = document.createElement('canvas');
this._textureCanvas.width = width;
this._textureCanvas.height = height;
this._textureCanvas.style.width = width + "px";
this._textureCanvas.style.height = height + "px";
this._textureCanvas.style.padding = "0";
this._textureCanvas.style.margin = "0";
this._textureCanvas.style.top = "0";
this._textureCanvas.style.background = cubeColor;
this._textureCanvas.style.position = "absolute";
this._textureCanvas.style.opacity = "1.0";
this._textureCanvas.style.visibility = "hidden";
this._textureCanvas.style["z-index"] = 2000000;
const body = document.getElementsByTagName("body")[0];
body.appendChild(this._textureCanvas);
const context = this._textureCanvas.getContext("2d");
let zUp = false;
function paint() {
for (let i = 0, len = facesZUp.length; i < len; i++) {
const face = facesZUp[i];
const boundary = face.boundary;
const xmin = Math.round(boundary[0] * scale);
const ymin = Math.round(boundary[1] * scale);
const width = Math.round(boundary[2] * scale);
const height = Math.round(boundary[3] * scale);
context.fillStyle = face.color;
context.fillRect(xmin, ymin, width, height);
}
for (let i = 0, len = areas.length; i < len; i++) {
let xmin;
let ymin;
let width;
let height;
const area = areas[i];
const boundaries = area.boundaries;
for (var j = 0, lenj = boundaries.length; j < lenj; j++) {
const boundary = boundaries[j];
xmin = Math.round(boundary[0] * scale);
ymin = Math.round(boundary[1] * scale);
width = Math.round(boundary[2] * scale);
height = Math.round(boundary[3] * scale);
if (area.highlighted) {
context.fillStyle = area.highlighted ? cubeHighlightColor : (area.color || cubeColor);
context.fillRect(xmin, ymin, width, height);
}
}
if (area.label) {
context.fillStyle = textColor;
context.font = '60px sans-serif';
context.textAlign = "center";
var xcenter = xmin + (width * 0.5);
var ycenter = ymin + (height * 0.7);
context.fillText(translateLabel(area.label), xcenter, ycenter, 80);
}
}
navCubeScene.glRedraw();
}
const translateLabel = (function () {
const swizzleYUp = {
"NavCube.front": "NavCube.front",
"NavCube.back": "NavCube.back",
"NavCube.right": "NavCube.right",
"NavCube.left": "NavCube.left",
"NavCube.top": "NavCube.top",
"NavCube.bottom": "NavCube.bottom"
};
const swizzleZUp = {
"NavCube.front": "NavCube.front",
"NavCube.back": "NavCube.back",
"NavCube.right": "NavCube.right",
"NavCube.left": "NavCube.left",
"NavCube.top": "NavCube.top",
"NavCube.bottom": "NavCube.bottom"
};
const defaultLabels = {
"NavCube.front": "FRONT",
"NavCube.back": "BACK",
"NavCube.right": "RIGHT",
"NavCube.left": "LEFT",
"NavCube.top": "TOP",
"NavCube.bottom": "BOTTOM"
};
return function (key) {
const swizzle = zUp ? swizzleZUp : swizzleYUp;
const swizzledKey = swizzle ? swizzle[key] : null;
if (swizzledKey) {
return viewer.localeService.translate(swizzledKey) || defaultLabels[swizzledKey] || swizzledKey;
}
return key;
};
})();
this.setZUp = function () {
zUp = true;
faces = facesZUp;
areas = areasZUp;
this.clear();
};
this.setYUp = function () {
zUp = false;
faces = facesYUp;
areas = areasYUp;
this.clear();
};
this.clear = function () {
context.fillStyle = cubeColor;
context.fillRect(0, 0, width, height);
for (var i = 0, len = areas.length; i < len; i++) {
const area = areas[i];
area.highlighted = false;
}
paint();
};
this.getArea = function (uv) {
const s = uv[0] * width;
const t = height - (uv[1] * height); // Correct for our texture Y-flipping
for (var i = 0, len = areas.length; i < len; i++) {
const area = areas[i];
const boundaries = area.boundaries;
for (var j = 0, lenj = boundaries.length; j < lenj; j++) {
const boundary = boundaries[j];
if (s >= (boundary[0] * scale) && s <= ((boundary[0] + boundary[2]) * scale) && t >= (boundary[1] * scale) && t <= ((boundary[1] + boundary[3]) * scale)) {
return i;
}
}
}
return -1;
};
this.setAreaHighlighted = function (areaId, highlighted) {
var area = areas[areaId];
if (!area) {
throw "Area not found: " + areaId;
}
area.highlighted = !!highlighted;
paint();
};
this.getAreaDir = function (areaId) {
var area = areas[areaId];
if (!area) {
throw "Unknown area: " + areaId;
}
return area.dir;
};
this.getAreaUp = function (areaId) {
var area = areas[areaId];
if (!area) {
throw "Unknown area: " + areaId;
}
return area.up;
};
this.getImage = function () {
return this._textureCanvas;
};
this.destroy = function () {
if (this._textureCanvas) {
this._textureCanvas.parentNode.removeChild(this._textureCanvas);
this._textureCanvas = null;
}
};
}
export {CubeTextureCanvas};