migrates vp to DOMMatrix implementation
breaks select, but it was broken anyway. Signed-off-by: Victor Seiji Hariki <victorseijih@gmail.com>
This commit is contained in:
parent
b166efc5e2
commit
857cb29c12
8 changed files with 89 additions and 68 deletions
|
@ -25,6 +25,7 @@
|
|||
|
||||
.layer-render-target .collection {
|
||||
position: absolute;
|
||||
transform-origin: 0px 0px;
|
||||
}
|
||||
|
||||
.layer-render-target .collection > .collection-input-overlay {
|
||||
|
|
17
index.html
17
index.html
|
@ -8,7 +8,7 @@
|
|||
<link href="css/icons.css?v=caa702e" rel="stylesheet" />
|
||||
|
||||
<link href="css/index.css?v=5b8d4d6" rel="stylesheet" />
|
||||
<link href="css/layers.css?v=b4fbf61" rel="stylesheet" />
|
||||
<link href="css/layers.css?v=604f140" rel="stylesheet" />
|
||||
|
||||
<link href="css/ui/generic.css?v=4b9afe2" rel="stylesheet" />
|
||||
|
||||
|
@ -49,6 +49,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<!-- Prompts section -->
|
||||
<button type="button" class="collapsible">Prompts</button>
|
||||
<div class="content prompt">
|
||||
|
@ -331,15 +332,15 @@
|
|||
<div class="ui separator"></div>
|
||||
<iframe
|
||||
id="page-overlay"
|
||||
src="pages/configuration.html?v=3d710ce"></iframe>
|
||||
src="pages/configuration.html?v=7fca00b"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Basics -->
|
||||
<script src="js/global.js?v=3a1cde6" type="text/javascript"></script>
|
||||
<script src="js/global.js?v=5ee46bd" type="text/javascript"></script>
|
||||
|
||||
<!-- Base Libs -->
|
||||
<script src="js/lib/util.js?v=7f6847c" type="text/javascript"></script>
|
||||
<script src="js/lib/util.js?v=d0a24f7" type="text/javascript"></script>
|
||||
<script src="js/lib/events.js?v=2ab7933" type="text/javascript"></script>
|
||||
<script src="js/lib/input.js?v=09298ac" type="text/javascript"></script>
|
||||
<script src="js/lib/layers.js?v=a1f8aea" type="text/javascript"></script>
|
||||
|
@ -349,7 +350,7 @@
|
|||
<script src="js/lib/ui.js?v=76ede2b" type="text/javascript"></script>
|
||||
|
||||
<script
|
||||
src="js/initalize/layers.populate.js?v=c81f0a5"
|
||||
src="js/initalize/layers.populate.js?v=938a1b2"
|
||||
type="text/javascript"></script>
|
||||
|
||||
<!-- Configuration -->
|
||||
|
@ -368,15 +369,15 @@
|
|||
|
||||
<!-- Load Tools -->
|
||||
<script
|
||||
src="js/ui/tool/generic.js?v=2bcd36d"
|
||||
src="js/ui/tool/generic.js?v=d605457"
|
||||
type="text/javascript"></script>
|
||||
|
||||
<script src="js/ui/tool/dream.js?v=a2932df" type="text/javascript"></script>
|
||||
<script src="js/ui/tool/dream.js?v=76bc565" type="text/javascript"></script>
|
||||
<script
|
||||
src="js/ui/tool/maskbrush.js?v=1e8a893"
|
||||
type="text/javascript"></script>
|
||||
<script
|
||||
src="js/ui/tool/colorbrush.js?v=8acb4f6"
|
||||
src="js/ui/tool/colorbrush.js?v=3f8c01a"
|
||||
type="text/javascript"></script>
|
||||
<script
|
||||
src="js/ui/tool/select.js?v=ade791e"
|
||||
|
|
|
@ -160,61 +160,72 @@ debugLayer.hide(); // Hidden by default
|
|||
* The global viewport object (may be modularized in the future). All
|
||||
* coordinates given are of the center of the viewport
|
||||
*
|
||||
* cx and cy are the viewport's world coordinates, scaled to zoom level.
|
||||
* _x and _y are actual coordinates in the DOM space
|
||||
* cx and cy are the viewport's world coordinates.
|
||||
*
|
||||
* The transform() function does some transforms and writes them to the
|
||||
* provided element.
|
||||
*/
|
||||
const viewport = {
|
||||
get cx() {
|
||||
return this._x * this.zoom;
|
||||
},
|
||||
class Viewport {
|
||||
cx = 0;
|
||||
cy = 0;
|
||||
|
||||
set cx(v) {
|
||||
return (this._x = v / this.zoom);
|
||||
},
|
||||
_x: 0,
|
||||
get cy() {
|
||||
return this._y * this.zoom;
|
||||
},
|
||||
set cy(v) {
|
||||
return (this._y = v / this.zoom);
|
||||
},
|
||||
_y: 0,
|
||||
zoom: 1,
|
||||
rotation: 0,
|
||||
zoom = 1;
|
||||
|
||||
/**
|
||||
* Gets viewport width in canvas coordinates
|
||||
*/
|
||||
get w() {
|
||||
return (window.innerWidth * 1) / this.zoom;
|
||||
},
|
||||
return window.innerWidth * this.zoom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets viewport height in canvas coordinates
|
||||
*/
|
||||
get h() {
|
||||
return (window.innerHeight * 1) / this.zoom;
|
||||
},
|
||||
return window.innerHeight * this.zoom;
|
||||
}
|
||||
|
||||
constructor(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
get v2c() {
|
||||
const m = new DOMMatrix();
|
||||
|
||||
m.translateSelf(-this.w / 2, -this.h / 2);
|
||||
m.translateSelf(this.cx, this.cy);
|
||||
m.scaleSelf(this.zoom);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
get c2v() {
|
||||
return this.v2c.invertSelf();
|
||||
}
|
||||
|
||||
viewToCanvas(x, y) {
|
||||
return {
|
||||
x: this.cx + this.w * (x / window.innerWidth - 0.5),
|
||||
y: this.cy + this.h * (y / window.innerHeight - 0.5),
|
||||
};
|
||||
},
|
||||
if (x.x !== undefined) return this.v2c.transformPoint(x);
|
||||
return this.v2c.transformPoint({x, y});
|
||||
}
|
||||
|
||||
canvasToView(x, y) {
|
||||
return {
|
||||
x: window.innerWidth * ((x - this.cx) / this.w) + window.innerWidth / 2,
|
||||
y: window.innerHeight * ((y - this.cy) / this.h) + window.innerHeight / 2,
|
||||
};
|
||||
},
|
||||
if (x.x !== undefined) return this.c2v.transformPoint(x);
|
||||
return this.c2v.transformPoint({x, y});
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply transformation
|
||||
*
|
||||
* @param {HTMLElement} el Element to apply CSS transform to
|
||||
*/
|
||||
transform(el) {
|
||||
el.style.transformOrigin = `${this.cx}px ${this.cy}px`;
|
||||
el.style.transform = `scale(${this.zoom}) translate(${-(
|
||||
this._x -
|
||||
this.w / 2
|
||||
)}px, ${-(this._y - this.h / 2)}px)`;
|
||||
},
|
||||
};
|
||||
el.style.transformOrigin = "0px 0px";
|
||||
el.style.transform = this.c2v;
|
||||
}
|
||||
}
|
||||
|
||||
const viewport = new Viewport(0, 0);
|
||||
|
||||
viewport.cx = imageCollection.size.w / 2;
|
||||
viewport.cy = imageCollection.size.h / 2;
|
||||
|
@ -296,7 +307,7 @@ mouse.listen.camera.onwheel.on((evn) => {
|
|||
const pcy = viewport.cy;
|
||||
|
||||
// Apply zoom
|
||||
viewport.zoom *= 1 - evn.delta * 0.0002;
|
||||
viewport.zoom *= 1 + evn.delta * 0.0002;
|
||||
|
||||
// Apply normal zoom (center of viewport)
|
||||
viewport.cx = pcx;
|
||||
|
@ -305,11 +316,11 @@ mouse.listen.camera.onwheel.on((evn) => {
|
|||
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);
|
||||
//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);
|
||||
//viewport.transform(imageCollection.element);
|
||||
|
||||
toolbar.currentTool.redraw();
|
||||
});
|
||||
|
@ -320,8 +331,8 @@ const cameraPaintStart = (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;
|
||||
viewport.cx = worldInit.x + (evn.ix - evn.x) * viewport.zoom;
|
||||
viewport.cy = worldInit.y + (evn.iy - evn.y) * viewport.zoom;
|
||||
|
||||
// Limits
|
||||
viewport.cx = Math.max(
|
||||
|
|
|
@ -32,6 +32,16 @@ class BoundingBox {
|
|||
w = 0;
|
||||
h = 0;
|
||||
|
||||
/** @type {Point} */
|
||||
get tl() {
|
||||
return {x: this.x, y: this.y};
|
||||
}
|
||||
|
||||
/** @type {Point} */
|
||||
get br() {
|
||||
return {x: this.x + this.w, y: this.y + this.h};
|
||||
}
|
||||
|
||||
constructor({x, y, w, h} = {x: 0, y: 0, w: 0, h: 0}) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
|
|
@ -176,7 +176,7 @@ const colorBrushTool = () =>
|
|||
uiCtx.arc(
|
||||
vcp.x,
|
||||
vcp.y,
|
||||
(state.eyedropper ? 50 : state.brushSize / 2) * viewport.zoom,
|
||||
(state.eyedropper ? 50 : state.brushSize / 2) / viewport.zoom,
|
||||
0,
|
||||
2 * Math.PI,
|
||||
true
|
||||
|
@ -197,7 +197,7 @@ const colorBrushTool = () =>
|
|||
uiCtx.arc(
|
||||
vcp.x,
|
||||
vcp.y,
|
||||
(state.brushSize / 2) * viewport.zoom,
|
||||
state.brushSize / (2 * viewport.zoom),
|
||||
0,
|
||||
2 * Math.PI,
|
||||
true
|
||||
|
|
|
@ -1918,11 +1918,10 @@ const img2imgTool = () =>
|
|||
return;
|
||||
}
|
||||
|
||||
const bbvp = {
|
||||
...viewport.canvasToView(bb.x, bb.y),
|
||||
w: viewport.zoom * bb.w,
|
||||
h: viewport.zoom * bb.h,
|
||||
};
|
||||
const bbvp = BoundingBox.fromStartEnd(
|
||||
viewport.canvasToView(bb.tl),
|
||||
viewport.canvasToView(bb.br)
|
||||
);
|
||||
|
||||
// For displaying border mask
|
||||
const bbCanvas = document.createElement("canvas");
|
||||
|
|
|
@ -27,11 +27,10 @@ const _tool = {
|
|||
reticleStyle: global.hasActiveInput ? "#BBF" : "#FFF",
|
||||
});
|
||||
|
||||
const bbvp = {
|
||||
...viewport.canvasToView(bb.x, bb.y),
|
||||
w: viewport.zoom * bb.w,
|
||||
h: viewport.zoom * bb.h,
|
||||
};
|
||||
const bbvp = BoundingBox.fromStartEnd(
|
||||
viewport.canvasToView(bb.tl),
|
||||
viewport.canvasToView(bb.br)
|
||||
);
|
||||
|
||||
uiCtx.save();
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<link href="../css/icons.css?v=caa702e" rel="stylesheet" />
|
||||
|
||||
<link href="../css/index.css?v=5b8d4d6" rel="stylesheet" />
|
||||
<link href="../css/layers.css?v=b4fbf61" rel="stylesheet" />
|
||||
<link href="../css/layers.css?v=604f140" rel="stylesheet" />
|
||||
|
||||
<link href="../css/ui/generic.css?v=4b9afe2" rel="stylesheet" />
|
||||
|
||||
|
|
Loading…
Reference in a new issue