mirror of
https://github.com/GTAmodding/modelviewjs.git
synced 2025-07-09 10:30:14 +02:00
commit
d3f78b364e
73
index.html
73
index.html
@ -1,32 +1,54 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>WebGL</title>
|
<title>GTA Model Viewer</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<link rel="stylesheet" href="webgl.css" type="text/css">
|
<link rel="stylesheet" href="webgl.css" type="text/css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="control">
|
<div class="viewer-panel">
|
||||||
<a href="javascript: startVehicleViewerIII(defaultModel);">III</a>
|
<canvas id="glcanvas"></canvas>
|
||||||
<a href="javascript: startVehicleViewerVC(defaultModel);">VC</a>
|
|
||||||
<a href="javascript: startVehicleViewerSA(defaultModel);">SA</a>
|
<table class="ui" id="colors">
|
||||||
|
<!-- JS inserts colors here -->
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="frames-wrapper ui">
|
||||||
|
<ul id="frames">
|
||||||
|
<!-- JS inserts frames here -->
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="custom-colors ui">
|
||||||
|
<input type="color" id="custom-color0">
|
||||||
|
<input type="color" id="custom-color1">
|
||||||
|
<input type="color" id="custom-color2">
|
||||||
|
<input type="color" id="custom-color3">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<canvas id="glcanvas" width="640" height="480" style="float:left"></canvas>
|
|
||||||
<div style="float:left">
|
<div class="select-panel ui">
|
||||||
<select id="objects" size="25">
|
<div id="control">
|
||||||
<!-- JS inserts models here -->
|
<a id="game-select-iii" href="javascript: startVehicleViewerIII(defaultModel);">III</a> |
|
||||||
</select>
|
<a id="game-select-vc" href="javascript: startVehicleViewerVC(defaultModel);">VC</a> |
|
||||||
|
<a id="game-select-sa" href="javascript: startVehicleViewerSA(defaultModel);">SA</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="objects-wrapper">
|
||||||
|
<select id="objects" size="25">
|
||||||
|
<!-- JS inserts models here -->
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<table id="colors" style="float:left">
|
|
||||||
<!-- JS inserts colors here -->
|
<ul class="bottom-links ui">
|
||||||
</table>
|
<li>Press I to toggle interface</li>
|
||||||
<div style="display:table;">
|
<li>|</li>
|
||||||
<ul id="frames">
|
<li>
|
||||||
<!-- JS inserts frames here -->
|
<a href="https://github.com/GTAmodding/modelviewjs" id="source-link" target="blank" rel="noopener">Source code</a>
|
||||||
</ul>
|
</li>
|
||||||
</div>
|
</ul>
|
||||||
<div style="clear:both;"></div>
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
@ -39,6 +61,8 @@
|
|||||||
<script src="rwstream.js"></script>
|
<script src="rwstream.js"></script>
|
||||||
<script src="main.js"></script>
|
<script src="main.js"></script>
|
||||||
<script src="loaddata.js"></script>
|
<script src="loaddata.js"></script>
|
||||||
|
<script src="ui.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var defaultModel = 'cheetah';
|
var defaultModel = 'cheetah';
|
||||||
var initialGame = 'iii';
|
var initialGame = 'iii';
|
||||||
@ -62,6 +86,9 @@ startVehicleViewerIII(model)
|
|||||||
else {
|
else {
|
||||||
SelectModel(model);
|
SelectModel(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uiSetCurrentGame("iii");
|
||||||
|
uiSetCurrentModel(CurrentModel.model);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +107,9 @@ startVehicleViewerVC(model)
|
|||||||
else {
|
else {
|
||||||
SelectModel(model);
|
SelectModel(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uiSetCurrentGame("vc");
|
||||||
|
uiSetCurrentModel(CurrentModel.model);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,6 +128,9 @@ startVehicleViewerSA(model)
|
|||||||
else {
|
else {
|
||||||
SelectModel(model);
|
SelectModel(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uiSetCurrentGame("sa");
|
||||||
|
uiSetCurrentModel(CurrentModel.model);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,5 +163,5 @@ else if(initialGame === 'vc') {
|
|||||||
else if(initialGame === 'sa') {
|
else if(initialGame === 'sa') {
|
||||||
startVehicleViewerSA(initialModel);
|
startVehicleViewerSA(initialModel);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
85
main.js
85
main.js
@ -25,6 +25,8 @@ var defaultProgram;
|
|||||||
var envMapProgram;
|
var envMapProgram;
|
||||||
var carPS2Program;
|
var carPS2Program;
|
||||||
|
|
||||||
|
var backgroundColor = [0, 0, 0, 0];
|
||||||
|
|
||||||
function deg2rad(d) { return d / 180.0 * Math.PI; }
|
function deg2rad(d) { return d / 180.0 * Math.PI; }
|
||||||
|
|
||||||
var rotating, zooming;
|
var rotating, zooming;
|
||||||
@ -81,6 +83,15 @@ InitRW()
|
|||||||
{
|
{
|
||||||
console.log("InitRW()");
|
console.log("InitRW()");
|
||||||
let canvas = document.querySelector('#glcanvas');
|
let canvas = document.querySelector('#glcanvas');
|
||||||
|
canvas.width = window.innerWidth;
|
||||||
|
canvas.height = window.innerHeight;
|
||||||
|
|
||||||
|
// Get background color from stylesheet
|
||||||
|
var bgColorStr = window.getComputedStyle(canvas, null).getPropertyValue("background-color");
|
||||||
|
bgColorStr = bgColorStr.substring(4, bgColorStr.length-1);
|
||||||
|
backgroundColor = bgColorStr.replace(" ", "").split(",");
|
||||||
|
backgroundColor = [parseFloat(backgroundColor[0])/255, parseFloat(backgroundColor[1])/255, parseFloat(backgroundColor[2])/255, 1.0];
|
||||||
|
|
||||||
gl = canvas.getContext('webgl');
|
gl = canvas.getContext('webgl');
|
||||||
|
|
||||||
if(!gl){
|
if(!gl){
|
||||||
@ -159,18 +170,6 @@ displayFrames(frame, parelem)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function
|
|
||||||
putControl()
|
|
||||||
{
|
|
||||||
// let ctl = document.getElementById('control');
|
|
||||||
// let reloadbtn = document.createElement('input');
|
|
||||||
// reloadbtn.type = "button";
|
|
||||||
// reloadbtn.value = "reload";
|
|
||||||
// reloadbtn.onclick = reload;
|
|
||||||
// ctl.appendChild(reloadbtn);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function
|
function
|
||||||
loadCarIII(filename)
|
loadCarIII(filename)
|
||||||
{
|
{
|
||||||
@ -203,11 +202,11 @@ loadCarSA(filename)
|
|||||||
setupSACar(myclump);
|
setupSACar(myclump);
|
||||||
setVehicleColors(modelinfo,
|
setVehicleColors(modelinfo,
|
||||||
carColors[0], carColors[1], carColors[2], carColors[3]);
|
carColors[0], carColors[1], carColors[2], carColors[3]);
|
||||||
// setVehicleLightColors(modelinfo,
|
setVehicleLightColors(modelinfo,
|
||||||
// [ 128, 0, 0, 255 ],
|
[ 255, 255, 255, 255 ],
|
||||||
// [ 128, 0, 0, 255 ],
|
[ 255, 255, 255, 255 ],
|
||||||
// [ 128, 0, 0, 255 ],
|
[ 255, 255, 255, 255 ],
|
||||||
// [ 128, 0, 0, 255 ]);
|
[ 255, 255, 255, 255 ]);
|
||||||
main();
|
main();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -238,8 +237,6 @@ main()
|
|||||||
if(!running){
|
if(!running){
|
||||||
running = true;
|
running = true;
|
||||||
|
|
||||||
putControl();
|
|
||||||
|
|
||||||
let then = 0;
|
let then = 0;
|
||||||
function render(now){
|
function render(now){
|
||||||
now *= 0.001; // convert to seconds
|
now *= 0.001; // convert to seconds
|
||||||
@ -309,6 +306,11 @@ setVehicleColors(vehinfo, c1, c2, c3, c4)
|
|||||||
vehinfo.thirdMaterials[i].color = c3;
|
vehinfo.thirdMaterials[i].color = c3;
|
||||||
for(let i = 0; i < vehinfo.fourthMaterials.length; i++)
|
for(let i = 0; i < vehinfo.fourthMaterials.length; i++)
|
||||||
vehinfo.fourthMaterials[i].color = c4;
|
vehinfo.fourthMaterials[i].color = c4;
|
||||||
|
|
||||||
|
if(c1) document.getElementById("custom-color0").value = RGB2HTML(c1);
|
||||||
|
if(c2) document.getElementById("custom-color1").value = RGB2HTML(c2);
|
||||||
|
if(c3) document.getElementById("custom-color2").value = RGB2HTML(c3);
|
||||||
|
if(c4) document.getElementById("custom-color3").value = RGB2HTML(c4);
|
||||||
}
|
}
|
||||||
|
|
||||||
function
|
function
|
||||||
@ -362,6 +364,10 @@ processVehicle(clump)
|
|||||||
fourthLightMaterials: [], // back right
|
fourthLightMaterials: [], // back right
|
||||||
clump: clump
|
clump: clump
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Wheel atomic to clone
|
||||||
|
let wheel = null;
|
||||||
|
|
||||||
for(let i = 0; i < clump.atomics.length; i++){
|
for(let i = 0; i < clump.atomics.length; i++){
|
||||||
a = clump.atomics[i];
|
a = clump.atomics[i];
|
||||||
f = a.frame;
|
f = a.frame;
|
||||||
@ -369,17 +375,41 @@ processVehicle(clump)
|
|||||||
f.name.endsWith("_lo") ||
|
f.name.endsWith("_lo") ||
|
||||||
f.name.endsWith("_vlo"))
|
f.name.endsWith("_vlo"))
|
||||||
a.visible = false;
|
a.visible = false;
|
||||||
|
|
||||||
|
if(!wheel && f.name.startsWith("wheel")) {
|
||||||
|
wheel = a;
|
||||||
|
}
|
||||||
|
|
||||||
findEditableMaterials(a.geometry, vehicleInfo);
|
findEditableMaterials(a.geometry, vehicleInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clone wheels
|
||||||
|
let frame = clump.frame.child;
|
||||||
|
while(wheel && frame) {
|
||||||
|
if(["wheel_rb_dummy", "wheel_rm_dummy", "wheel_lf_dummy", "wheel_lb_dummy", "wheel_lm_dummy"].includes(frame.name)) {
|
||||||
|
let wheel2 = RpAtomicClone(wheel);
|
||||||
|
mat4.copy(wheel2.frame.ltm, frame.ltm);
|
||||||
|
if(["wheel_lf_dummy", "wheel_lb_dummy", "wheel_lm_dummy"].includes(frame.name)) {
|
||||||
|
// Rotate cloned wheel
|
||||||
|
mat4.rotate(wheel2.frame.ltm, wheel2.frame.ltm, Math.PI, [0, 0, 1]);
|
||||||
|
}
|
||||||
|
frame.child = wheel2.frame;
|
||||||
|
clump.atomics.push(wheel2);
|
||||||
|
}
|
||||||
|
frame = frame.next;
|
||||||
|
}
|
||||||
|
|
||||||
return vehicleInfo;
|
return vehicleInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
function
|
function
|
||||||
drawScene(deltaTime)
|
drawScene(deltaTime)
|
||||||
{
|
{
|
||||||
// camYaw += deltaTime;
|
if(window.autoRotateCamera) {
|
||||||
|
camYaw += deltaTime * 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
gl.clearColor(0.5, 0.5, 0.5, 1.0);
|
gl.clearColor(backgroundColor[0], backgroundColor[1], backgroundColor[2], 1.0);
|
||||||
gl.clearDepth(1.0);
|
gl.clearDepth(1.0);
|
||||||
gl.enable(gl.DEPTH_TEST);
|
gl.enable(gl.DEPTH_TEST);
|
||||||
gl.depthFunc(gl.LEQUAL);
|
gl.depthFunc(gl.LEQUAL);
|
||||||
@ -428,3 +458,16 @@ loadDFF(filename, cb)
|
|||||||
|
|
||||||
req.send(null);
|
req.send(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function
|
||||||
|
rgbToCSSString(r, g, b)
|
||||||
|
{
|
||||||
|
return ["rgb(",r,",",g,",",b,")"].join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
function
|
||||||
|
RGB2HTML(color)
|
||||||
|
{
|
||||||
|
let decColor = 0x1000000 + color[2] + 0x100 * color[1] + 0x10000 * color[0];
|
||||||
|
return '#' + decColor.toString(16).substr(1);
|
||||||
|
}
|
||||||
|
26
rw.js
26
rw.js
@ -269,6 +269,20 @@ RpAtomicCreate()
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function
|
||||||
|
RpAtomicClone(a)
|
||||||
|
{
|
||||||
|
let a2 = RpAtomicCreate();
|
||||||
|
a2.type = a.type;
|
||||||
|
a2.visible = a.visible;
|
||||||
|
a2.frame = RwFrameClone(a.frame);
|
||||||
|
a2.geometry = a.geometry;
|
||||||
|
a2.pipeline = a.pipeline;
|
||||||
|
a2.frame.objects = [];
|
||||||
|
a2.frame.objects[0] = a2;
|
||||||
|
return a2;
|
||||||
|
}
|
||||||
|
|
||||||
function
|
function
|
||||||
RpAtomicSetFrame(a, f)
|
RpAtomicSetFrame(a, f)
|
||||||
{
|
{
|
||||||
@ -488,6 +502,18 @@ rwFrameInit(f)
|
|||||||
mat4.copy(f.ltm, f.matrix);
|
mat4.copy(f.ltm, f.matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function
|
||||||
|
RwFrameClone(f) {
|
||||||
|
let f2 = RwFrameCreate();
|
||||||
|
mat4.copy(f2.matrix, f.matrix);
|
||||||
|
mat4.copy(f2.ltm, f.ltm);
|
||||||
|
f2.child = f.child;
|
||||||
|
f2.name = f.name;
|
||||||
|
f2.parent = f.parent;
|
||||||
|
f2.root = f.root;
|
||||||
|
return f2;
|
||||||
|
}
|
||||||
|
|
||||||
function
|
function
|
||||||
rpMaterialInit(m)
|
rpMaterialInit(m)
|
||||||
{
|
{
|
||||||
|
101
ui.js
Normal file
101
ui.js
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
showInterface = true;
|
||||||
|
autoRotateCamera = false;
|
||||||
|
|
||||||
|
function
|
||||||
|
hex2rgb(hex) {
|
||||||
|
let r = parseInt(hex.slice(1, 3), 16);
|
||||||
|
let g = parseInt(hex.slice(3, 5), 16);
|
||||||
|
let b = parseInt(hex.slice(5, 7), 16);
|
||||||
|
return [r, g, b];
|
||||||
|
}
|
||||||
|
|
||||||
|
function
|
||||||
|
updateVehicleCustomColors() {
|
||||||
|
let colors = [];
|
||||||
|
for(let i = 0; i < 4; i++) {
|
||||||
|
let cStr = document.getElementById("custom-color" + i).value;
|
||||||
|
let c = hex2rgb(cStr);
|
||||||
|
c[3] = 255;
|
||||||
|
colors[i] = c;
|
||||||
|
}
|
||||||
|
setVehicleColors(modelinfo, colors[0], colors[1], colors[2], colors[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(let i = 0; i < 4; i++) {
|
||||||
|
document.getElementById("custom-color" + i).addEventListener("input", updateVehicleCustomColors, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("keypress",
|
||||||
|
function(e) {
|
||||||
|
if(e.key === "i") {
|
||||||
|
showInterface = !showInterface;
|
||||||
|
document.querySelectorAll(".ui").forEach((v) => {
|
||||||
|
v.style.visibility = showInterface ? "unset" : "hidden";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(e.key === "r") {
|
||||||
|
autoRotateCamera = !autoRotateCamera;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
false);
|
||||||
|
|
||||||
|
document.getElementById("objects").addEventListener("keypress",
|
||||||
|
function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
false);
|
||||||
|
|
||||||
|
var lastModelChangeViaKey = 0;
|
||||||
|
document.getElementById("objects").addEventListener("keydown",
|
||||||
|
function(e) {
|
||||||
|
if(e.keyCode !== 38 && e.keyCode !== 40) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Date.now() - lastModelChangeViaKey < 750) {
|
||||||
|
e.preventDefault();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastModelChangeViaKey = Date.now();
|
||||||
|
},
|
||||||
|
false);
|
||||||
|
|
||||||
|
|
||||||
|
document.getElementById("objects").addEventListener("keyup",
|
||||||
|
function(e) {
|
||||||
|
if(e.keyCode !== 38 && e.keyCode !== 40) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastModelChangeViaKey -= 400;
|
||||||
|
|
||||||
|
let model = document.getElementById("objects").value;
|
||||||
|
if(model !== CurrentModel.model) {
|
||||||
|
SelectModel(model);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
false);
|
||||||
|
|
||||||
|
function
|
||||||
|
uiSetCurrentGame(game) {
|
||||||
|
document.querySelectorAll("#control a").forEach((v) => {
|
||||||
|
v.classList.remove("active");
|
||||||
|
});
|
||||||
|
|
||||||
|
let gameSelect = document.getElementById("game-select-" + game);
|
||||||
|
gameSelect.classList.add("active");
|
||||||
|
}
|
||||||
|
|
||||||
|
function
|
||||||
|
uiSetCurrentModel(model) {
|
||||||
|
let l = document.querySelectorAll("#objects option");
|
||||||
|
for(let i = 0; i < l.length; i++) {
|
||||||
|
if(l[i].value === model) {
|
||||||
|
l[i].selected = 'selected';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
166
webgl.css
166
webgl.css
@ -1,7 +1,167 @@
|
|||||||
canvas {
|
html {
|
||||||
border: 2px solid black;
|
height: 100%;
|
||||||
background-color: black;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
body, canvas {
|
||||||
|
background-color: #808080;
|
||||||
|
}
|
||||||
|
|
||||||
video {
|
video {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#objects {
|
||||||
|
outline: none;
|
||||||
|
height: calc(100% - 18.4px);
|
||||||
|
width: 110px;
|
||||||
|
border: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-panel {
|
||||||
|
position: absolute;
|
||||||
|
float: left;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#control {
|
||||||
|
text-align: center;
|
||||||
|
background-color: white;
|
||||||
|
color: black;
|
||||||
|
font-family: Arial;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
padding-top: 5px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.objects-wrapper {
|
||||||
|
float: left;
|
||||||
|
height: calc(100% - 15px);
|
||||||
|
width: calc(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewer-panel {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
option {
|
||||||
|
padding-left: 5px;
|
||||||
|
font-size: 14px;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
option:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#colors {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 20px;
|
||||||
|
left: 130px;
|
||||||
|
|
||||||
|
border-radius: 2px;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#colors td {
|
||||||
|
border: 1px solid white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#colors td:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.frames-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-links {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
right: 10px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-links ul {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-links li {
|
||||||
|
float: left;
|
||||||
|
margin-left: 10px;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-colors {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 210px;
|
||||||
|
left: 130px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-colors input:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#control a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#control a:hover, #control a.active {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark)
|
||||||
|
{
|
||||||
|
body, canvas {
|
||||||
|
background-color: #181818;
|
||||||
|
}
|
||||||
|
|
||||||
|
body, a, #objects, option {
|
||||||
|
color: #f5f5f5 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#objects {
|
||||||
|
background-color: #292929;
|
||||||
|
}
|
||||||
|
|
||||||
|
option:checked, option:hover, .option:active {
|
||||||
|
background-color: #4f4f4f !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#colors, .custom-colors input {
|
||||||
|
background-color: #343434;
|
||||||
|
}
|
||||||
|
|
||||||
|
#colors td {
|
||||||
|
border: 1px solid white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-colors input {
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#objects option:nth-child(2n) {
|
||||||
|
background-color: #2e2e2e;
|
||||||
|
}
|
||||||
|
|
||||||
|
#control {
|
||||||
|
background-color: #292929;
|
||||||
|
color: #f5f5f5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user