mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-11-26 00:53:00 +00:00
Add img2brush tool to website
Pending insertion of a link into the reference docs
This commit is contained in:
parent
ef2dbc1806
commit
691b71adfe
4 changed files with 159 additions and 1 deletions
|
@ -75,7 +75,7 @@ async function fetch(url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function(eleventyConfig) {
|
module.exports = function(eleventyConfig) {
|
||||||
|
eleventyConfig.addPassthroughCopy("img2brush/img2brush.js");
|
||||||
eleventyConfig.addAsyncShortcode("fetch", fetch);
|
eleventyConfig.addAsyncShortcode("fetch", fetch);
|
||||||
|
|
||||||
// eleventyConfig.addPassthroughCopy("images");
|
// eleventyConfig.addPassthroughCopy("images");
|
||||||
|
|
|
@ -411,3 +411,30 @@ footer {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes move-diagonal {
|
||||||
|
from {
|
||||||
|
background-position: -2px -2px, -2px -2px, -1px -1px, -1px -1px;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
background-position: -52px -52px, -52px -52px, -51px -51px, -51px -51px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#dropzone {
|
||||||
|
border: 0.3em dashed #aaaaaa;
|
||||||
|
transition: border 0.2s;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
#dropzone.dropzone-active {
|
||||||
|
border: 0.3em dashed hsl(203, 79%, 55%);
|
||||||
|
|
||||||
|
/* Ref https://www.magicpattern.design/tools/css-backgrounds */
|
||||||
|
background-image: linear-gradient(var(--bg-bright) 2px, transparent 2px), linear-gradient(90deg, var(--bg-bright) 2px, transparent 2px), linear-gradient(var(--bg-bright) 1px, transparent 1px), linear-gradient(90deg, var(--bg-bright) 1px, var(--bg-transcluscent) 1px);
|
||||||
|
background-size: 50px 50px, 50px 50px, 10px 10px, 10px 10px;
|
||||||
|
background-position: -2px -2px, -2px -2px, -1px -1px, -1px -1px;
|
||||||
|
|
||||||
|
animation: move-diagonal 5s linear infinite;
|
||||||
|
}
|
||||||
|
#brushimg-preview { flex: 1; }
|
||||||
|
|
97
.docs/img2brush/img2brush.js
Normal file
97
.docs/img2brush/img2brush.js
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
window.addEventListener("load", () => {
|
||||||
|
let dropzone = document.querySelector("#dropzone");
|
||||||
|
dropzone.addEventListener("dragenter", handle_drag_enter);
|
||||||
|
dropzone.addEventListener("dragleave", handle_drag_leave);
|
||||||
|
dropzone.addEventListener("dragover", handle_drag_over);
|
||||||
|
dropzone.addEventListener("drop", handle_drop);
|
||||||
|
|
||||||
|
document.querySelector("#brushimg-tsv").addEventListener("click", select_output);
|
||||||
|
let button_copy = document.querySelector("#brushimg-copy")
|
||||||
|
button_copy.addEventListener("click", () => {
|
||||||
|
select_output();
|
||||||
|
button_copy.innerHTML = document.execCommand("copy") ? "Copied!" : "Failed to copy :-(";
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
function select_output() {
|
||||||
|
let output = document.querySelector("#brushimg-tsv");
|
||||||
|
|
||||||
|
let selection = window.getSelection();
|
||||||
|
|
||||||
|
if (selection.rangeCount > 0)
|
||||||
|
selection.removeAllRanges();
|
||||||
|
|
||||||
|
let range = document.createRange();
|
||||||
|
range.selectNode(output);
|
||||||
|
selection.addRange(range);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function handle_drag_enter(event) {
|
||||||
|
event.target.classList.add("dropzone-active");
|
||||||
|
}
|
||||||
|
function handle_drag_leave(event) {
|
||||||
|
event.target.classList.remove("dropzone-active");
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_drag_over(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_drop(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
event.preventDefault();
|
||||||
|
event.target.classList.remove("dropzone-active");
|
||||||
|
|
||||||
|
let image_file = null;
|
||||||
|
|
||||||
|
image_file = event.dataTransfer.files[0];
|
||||||
|
|
||||||
|
let reader = new FileReader();
|
||||||
|
reader.addEventListener("load", function(_event) {
|
||||||
|
let image = new Image();
|
||||||
|
image.src = reader.result;
|
||||||
|
image.addEventListener("load", () => handle_new_image(image));
|
||||||
|
|
||||||
|
|
||||||
|
document.querySelector("#brushimg-preview").src = image.src;
|
||||||
|
});
|
||||||
|
reader.readAsDataURL(image_file);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function image2pixels(image) {
|
||||||
|
let canvas = document.createElement("canvas"),
|
||||||
|
ctx = canvas.getContext("2d");
|
||||||
|
|
||||||
|
canvas.width = image.width;
|
||||||
|
canvas.height = image.height;
|
||||||
|
|
||||||
|
ctx.drawImage(image, 0, 0);
|
||||||
|
|
||||||
|
return ctx.getImageData(0, 0, image.width, image.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_new_image(image) {
|
||||||
|
let tsv = pixels2tsv(image2pixels(image));
|
||||||
|
document.querySelector("#brushimg-stats").value = `${image.width} x ${image.height} | ${image.width * image.height} pixels`;
|
||||||
|
document.querySelector("#brushimg-tsv").value = tsv;
|
||||||
|
}
|
||||||
|
|
||||||
|
function round(number, decimal_places = 0) {
|
||||||
|
let multiplier = Math.pow(10, decimal_places);
|
||||||
|
return Math.round(number * multiplier) / multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
function pixels2tsv(pixels) {
|
||||||
|
let result = "";
|
||||||
|
for(let y = 0; y < pixels.height; y++) {
|
||||||
|
let row = [];
|
||||||
|
for(let x = 0; x < pixels.width; x++) {
|
||||||
|
row.push(round(pixels.data[((y*pixels.width + x) * 4) + 3], 3));
|
||||||
|
}
|
||||||
|
result += row.join(`\t`) + `\n`;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
34
.docs/img2brush/index.html
Normal file
34
.docs/img2brush/index.html
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
---
|
||||||
|
layout: theme.njk
|
||||||
|
title: Image to brush converter
|
||||||
|
---
|
||||||
|
|
||||||
|
<section class="panel-generic">
|
||||||
|
<h1>Image to sculpting brush converter</h1>
|
||||||
|
|
||||||
|
<p>Convert any image to a sculpting brush here! The <strong>alpha (opacity) channel</strong> is used to determine the weight of the brush - <strong>all colour is ignored</strong>.</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="dropzone" class="bigbox panel-generic">
|
||||||
|
<h2>Input</h2>
|
||||||
|
<p>Drop your image here.</p>
|
||||||
|
|
||||||
|
<img id="brushimg-preview" alt="" />
|
||||||
|
|
||||||
|
<output id="brushimg-stats"></output>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
<section class="panel-generic">
|
||||||
|
<h2>Output</h2>
|
||||||
|
|
||||||
|
<p>Paste the output below into a text file in <code>worldeditadditions/lib/sculpt/brushes</code> with the file extension <code>.txt</code> and restart your Minetest server for the brush to be recognised.</p>
|
||||||
|
|
||||||
|
<p class="text-centre">
|
||||||
|
<button id="brushimg-copy" class="bigbutton">Copy</button>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre><output id="brushimg-tsv"><em>(your output will appear here as soon as you drop an image above)</em></output></pre>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<script src="./img2brush.js"></script>
|
Loading…
Reference in a new issue