diff --git a/css/layers.css b/css/layers.css
index 6d426c0..a4f2ee7 100644
--- a/css/layers.css
+++ b/css/layers.css
@@ -63,3 +63,8 @@
image-rendering: pixelated;
image-rendering: crisp-edges;
}
+
+canvas.pixelated {
+ image-rendering: pixelated;
+ image-rendering: crisp-edges;
+}
diff --git a/index.html b/index.html
index d49bd4c..34dce50 100644
--- a/index.html
+++ b/index.html
@@ -306,6 +306,9 @@
+
+
+
@@ -324,7 +327,6 @@
-
diff --git a/js/config.js b/js/config.js
index 6120e78..a6f7ba6 100644
--- a/js/config.js
+++ b/js/config.js
@@ -7,6 +7,9 @@ const config = makeReadOnly(
{
// Scroll Tick Limit (How much must scroll to reach next tick)
wheelTickSize: 50,
+
+ // Endpoint
+ api: makeReadOnly({path: "/sdapi/v1/"}),
},
"config"
);
diff --git a/js/index.js b/js/index.js
index ace7a55..8c9505d 100644
--- a/js/index.js
+++ b/js/index.js
@@ -132,35 +132,9 @@ var stableDiffusionData = {
};
// stuff things use
-let debug = false;
-var returnedImages;
-var imageIndex = 0;
-var tmpImgXYWH = {};
var host = "";
var url = "/sdapi/v1/";
-var endpoint = "txt2img";
-var frameX = 512;
-var frameY = 512;
-var drawThis = {};
const basePixelCount = 64; //64 px - ALWAYS 64 PX
-var snapToGrid = true;
-var backupMaskPaintCanvas; //???
-var backupMaskPaintCtx; //...? look i am bad at this
-var backupMaskChunk = null;
-var backupMaskX = null;
-var backupMaskY = null;
-var totalImagesReturned;
-var overMaskPx = 0;
-var drawTargets = []; // is this needed? i only draw the last one anyway...
-var dropTargets = []; // uhhh yeah similar to the above but for arbitrary dropped images
-var arbitraryImage;
-var arbitraryImageData;
-var arbitraryImageBitmap;
-var arbitraryImageBase64; // seriously js cmon work with me here
-var placingArbitraryImage = false; // for when the user has loaded an existing image from their computer
-var marchOffset = 0;
-var inProgress = false;
-var marchCoords = {};
//
function startup() {
diff --git a/js/initalize/layers.populate.js b/js/initalize/layers.populate.js
index 744b15d..0496848 100644
--- a/js/initalize/layers.populate.js
+++ b/js/initalize/layers.populate.js
@@ -22,6 +22,9 @@ const bgLayer = imageCollection.registerLayer("bg", {
name: "Background",
category: "background",
});
+
+bgLayer.canvas.classList.add("pixelated");
+
const imgLayer = imageCollection.registerLayer("image", {
name: "Image",
category: "image",
@@ -245,12 +248,30 @@ mouse.registerContext(
{
target: imageCollection.inputElement,
validate: (evn) => {
- if (!global.hasActiveInput || evn.type === "mousemove") return true;
+ if ((!global.hasActiveInput && !evn.ctrlKey) || evn.type === "mousemove")
+ return true;
return false;
},
}
);
+mouse.registerContext(
+ "camera",
+ (evn, ctx) => {
+ ctx.coords.prev.x = ctx.coords.pos.x;
+ ctx.coords.prev.y = ctx.coords.pos.y;
+
+ // Set coords
+ ctx.coords.pos.x = evn.x;
+ ctx.coords.pos.y = evn.y;
+ },
+ {
+ validate: (evn) => {
+ return !!evn.ctrlKey;
+ },
+ }
+);
+
// Redraw on active input state change
(() => {
mouse.listen.window.onany.on((evn) => {
@@ -264,32 +285,41 @@ mouse.registerContext(
});
})();
-mouse.listen.window.onwheel.on((evn) => {
- if (evn.evn.ctrlKey) {
- evn.evn.preventDefault();
+mouse.listen.camera.onwheel.on((evn) => {
+ evn.evn.preventDefault();
- const pcx = viewport.cx;
- const pcy = viewport.cy;
- if (evn.delta < 0) {
- viewport.zoom *= 1 + Math.abs(evn.delta * 0.0002);
- } else {
- viewport.zoom *= 1 - Math.abs(evn.delta * 0.0002);
- }
+ // Get cursor world position
+ const cursorPosition = viewport.viewToCanvas(evn.x, evn.y);
+ console.debug(cursorPosition);
- viewport.cx = pcx;
- viewport.cy = pcy;
+ // Get viewport center
+ const pcx = viewport.cx;
+ const pcy = viewport.cy;
- viewport.transform(imageCollection.element);
+ // Apply zoom
+ viewport.zoom *= 1 - evn.delta * 0.0002;
- toolbar.currentTool.redraw();
- }
+ // Apply normal zoom (center of viewport)
+ viewport.cx = pcx;
+ viewport.cy = pcy;
+
+ viewport.transform(imageCollection.element);
+
+ // Calculate new viewport center and move
+ const newCursorPosition = viewport.viewToCanvas(evn.x, evn.y);
+ viewport.cx = pcx - (newCursorPosition.x - cursorPosition.x);
+ viewport.cy = pcy - (newCursorPosition.y - cursorPosition.y);
+
+ viewport.transform(imageCollection.element);
+
+ toolbar.currentTool.redraw();
});
-mouse.listen.window.btn.middle.onpaintstart.on((evn) => {
- if (evn.evn.ctrlKey) worldInit = {x: viewport.cx, y: viewport.cy};
-});
+const cameraPaintStart = (evn) => {
+ worldInit = {x: viewport.cx, y: viewport.cy};
+};
-mouse.listen.window.btn.middle.onpaint.on((evn) => {
+const cameraPaint = (evn) => {
if (worldInit) {
viewport.cx = worldInit.x + (evn.ix - evn.x) / viewport.zoom;
viewport.cy = worldInit.y + (evn.iy - evn.y) / viewport.zoom;
@@ -315,11 +345,20 @@ mouse.listen.window.btn.middle.onpaint.on((evn) => {
debugCtx.arc(viewport.cx, viewport.cy, 5, 0, Math.PI * 2);
debugCtx.fill();
}
-});
+};
-mouse.listen.window.btn.middle.onpaintend.on((evn) => {
+const cameraPaintEnd = (evn) => {
worldInit = null;
-});
+};
+
+mouse.listen.camera.btn.middle.onpaintstart.on(cameraPaintStart);
+mouse.listen.camera.btn.left.onpaintstart.on(cameraPaintStart);
+
+mouse.listen.camera.btn.middle.onpaint.on(cameraPaint);
+mouse.listen.camera.btn.left.onpaint.on(cameraPaint);
+
+mouse.listen.window.btn.middle.onpaintend.on(cameraPaintEnd);
+mouse.listen.window.btn.left.onpaintend.on(cameraPaintEnd);
window.addEventListener("resize", () => {
viewport.transform(imageCollection.element);
diff --git a/js/lib/input.js b/js/lib/input.js
index bf67dfd..4a385a1 100644
--- a/js/lib/input.js
+++ b/js/lib/input.js
@@ -220,6 +220,7 @@ window.addEventListener(
const key = buttons[evn.button];
if (
(!target || target === evn.target) &&
+ mouse.coords[name].dragging[key] &&
!mouse.coords[name].dragging[key].drag &&
key
) {
@@ -273,13 +274,12 @@ window.addEventListener(
(evn) => {
const time = performance.now();
- mouse._contexts.forEach(({target, name, buttons, validate}) => {
+ mouse._contexts.forEach(({target, name, buttons}) => {
const key = buttons[evn.button];
if (
(!target || target === evn.target) &&
key &&
- mouse.coords[name].dragging[key] &&
- (!validate || validate(evn))
+ mouse.coords[name].dragging[key]
) {
const start = {
x: mouse.coords[name].dragging[key].x,
@@ -447,7 +447,7 @@ window.addEventListener(
_discard = evn.deltaMode;
mouse._contexts.forEach(({name, target, validate}) => {
- if (!target || (target === evn.target && (!validate || validate(evn)))) {
+ if ((!target || target === evn.target) && (!validate || validate(evn))) {
mouse.listen[name].onwheel.emit({
target: evn.target,
delta: evn.deltaY,
diff --git a/js/ui/tool/colorbrush.js b/js/ui/tool/colorbrush.js
index 32701b3..5786307 100644
--- a/js/ui/tool/colorbrush.js
+++ b/js/ui/tool/colorbrush.js
@@ -208,14 +208,12 @@ const colorBrushTool = () =>
};
state.wheelcb = (evn) => {
- if (!evn.evn.ctrlKey) {
- state.brushSize = state.setBrushSize(
- state.brushSize -
- Math.floor(state.config.brushScrollSpeed * evn.delta)
- );
- uiCtx.clearRect(0, 0, uiCanvas.width, uiCanvas.height);
- state.movecb(evn);
- }
+ state.brushSize = state.setBrushSize(
+ state.brushSize -
+ Math.floor(state.config.brushScrollSpeed * evn.delta)
+ );
+ uiCtx.clearRect(0, 0, uiCanvas.width, uiCanvas.height);
+ state.movecb(evn);
};
/**
diff --git a/js/ui/tool/dream.js b/js/ui/tool/dream.js
index bb3f2dc..ada341f 100644
--- a/js/ui/tool/dream.js
+++ b/js/ui/tool/dream.js
@@ -13,7 +13,7 @@ let generating = false;
const _monitorProgress = (bb, oncheck = null) => {
const minDelay = 1000;
- const apiURL = `${host}${url}progress?skip_current_image=true`;
+ const apiURL = `${host}${config.api.path}progress?skip_current_image=true`;
const expanded = {...bb};
expanded.x--;
@@ -84,7 +84,7 @@ const _monitorProgress = (bb, oncheck = null) => {
* @returns {Promise}
*/
const _dream = async (endpoint, request) => {
- const apiURL = `${host}${url}${endpoint}`;
+ const apiURL = `${host}${config.api.path}${endpoint}`;
// Debugging is enabled
if (global.debug) {
@@ -380,7 +380,7 @@ const _generate = async (endpoint, request, bb, options = {}) => {
interruptButton.classList.add("dream-stop-btn");
interruptButton.textContent = "Interrupt";
interruptButton.addEventListener("click", () => {
- fetch(`${host}${url}interrupt`, {method: "POST"});
+ fetch(`${host}${config.api.path}interrupt`, {method: "POST"});
interruptButton.disabled = true;
});
const marchingOptions = {};
@@ -400,13 +400,13 @@ const _generate = async (endpoint, request, bb, options = {}) => {
if (lastProgress < nextCP && data.progress >= nextCP) {
nextCP += options.drawEvery;
- fetch(`${host}${url}progress?skip_current_image=false`).then(
- async (response) => {
- if (stopDrawingStatus) return;
- const imagedata = await response.json();
- redraw(imagedata.current_image);
- }
- );
+ fetch(
+ `${host}${config.api.path}progress?skip_current_image=false`
+ ).then(async (response) => {
+ if (stopDrawingStatus) return;
+ const imagedata = await response.json();
+ redraw(imagedata.current_image);
+ });
}
lastProgress = data.progress;
});
@@ -619,11 +619,7 @@ const _generate = async (endpoint, request, bb, options = {}) => {
);
const onmorehandler = mouse.listen.world.btn.middle.onclick.on(
(evn, state) => {
- if (
- !state.dream_processed &&
- bb.contains(evn.x, evn.y) &&
- !evn.evn.ctrlKey
- ) {
+ if (!state.dream_processed && bb.contains(evn.x, evn.y)) {
makeMore();
state.dream_processed = true;
}
@@ -633,7 +629,6 @@ const _generate = async (endpoint, request, bb, options = {}) => {
);
const onwheelhandler = mouse.listen.world.onwheel.on(
(evn, state) => {
- if (evn.evn.ctrlKey) return;
if (!state.dream_processed && bb.contains(evn.x, evn.y)) {
if (evn.delta < 0) nextImg();
else prevImg();
@@ -1086,26 +1081,24 @@ const dream_img2img_callback = (bb, resolution, state) => {
let _dream_wheel_accum = 0;
const _dream_onwheel = (evn, state) => {
- if (!evn.evn.ctrlKey) {
- if (evn.mode !== WheelEvent.DOM_DELTA_PIXEL) {
- // We don't really handle non-pixel scrolling
- return;
- }
+ if (evn.mode !== WheelEvent.DOM_DELTA_PIXEL) {
+ // We don't really handle non-pixel scrolling
+ return;
+ }
- // A simple but (I hope) effective fix for mouse wheel behavior
- _dream_wheel_accum += evn.delta;
+ // A simple but (I hope) effective fix for mouse wheel behavior
+ _dream_wheel_accum += evn.delta;
- if (Math.abs(_dream_wheel_accum) > config.wheelTickSize) {
- // Snap to next or previous position
- const v =
- state.cursorSize -
- 128 * (_dream_wheel_accum / Math.abs(_dream_wheel_accum));
+ if (Math.abs(_dream_wheel_accum) > config.wheelTickSize) {
+ // Snap to next or previous position
+ const v =
+ state.cursorSize -
+ 128 * (_dream_wheel_accum / Math.abs(_dream_wheel_accum));
- state.cursorSize = state.setCursorSize(v + snap(v, 0, 128));
- state.mousemovecb(evn);
+ state.cursorSize = state.setCursorSize(v + snap(v, 0, 128));
+ state.mousemovecb(evn);
- _dream_wheel_accum = 0; // Zero accumulation
- }
+ _dream_wheel_accum = 0; // Zero accumulation
}
};
@@ -1191,7 +1184,7 @@ const dreamTool = () =>
state.invertMask = false;
state.keepUnmasked = true;
state.keepUnmaskedBlur = 8;
- state.overMaskPx = 0;
+ state.overMaskPx = 20;
state.preserveMasks = false;
state.erasePrevCursor = () =>
@@ -2022,7 +2015,8 @@ const img2imgTool = () =>
window.onbeforeunload = async () => {
// Stop current generation on page close
- if (generating) await fetch(`${host}${url}interrupt`, {method: "POST"});
+ if (generating)
+ await fetch(`${host}${config.api.path}interrupt`, {method: "POST"});
};
const sendSeed = (seed) => {
diff --git a/js/ui/tool/interrogate.js b/js/ui/tool/interrogate.js
index 4224645..2090c03 100644
--- a/js/ui/tool/interrogate.js
+++ b/js/ui/tool/interrogate.js
@@ -33,7 +33,6 @@ const interrogateTool = () =>
state.snapToGrid = true;
state.invertMask = false;
- state.overMaskPx = 0;
state.block_res_change = true;
state.erasePrevReticle = () => ovLayer.clear();
@@ -163,7 +162,7 @@ const interrogate_callback = async (evn, state) => {
* @returns {Promise}
*/
const _interrogate = async (request) => {
- const apiURL = `${host}${url}` + "interrogate";
+ const apiURL = `${host}${config.api.path}interrogate`;
/** @type {StableDiffusionResponse} */
let data = null;
diff --git a/js/ui/tool/maskbrush.js b/js/ui/tool/maskbrush.js
index 9649cde..0b68c4b 100644
--- a/js/ui/tool/maskbrush.js
+++ b/js/ui/tool/maskbrush.js
@@ -167,13 +167,11 @@ const maskBrushTool = () =>
};
state.wheelcb = (evn) => {
- if (!evn.evn.ctrlKey) {
- state.brushSize = state.setBrushSize(
- state.brushSize -
- Math.floor(state.config.brushScrollSpeed * evn.delta)
- );
- state.redraw();
- }
+ state.brushSize = state.setBrushSize(
+ state.brushSize -
+ Math.floor(state.config.brushScrollSpeed * evn.delta)
+ );
+ state.redraw();
};
state.drawcb = (evn) =>