Skip to content

Commit

Permalink
Draw UX improvements, ignored layer color, pen-draw refactoring, laye…
Browse files Browse the repository at this point in the history
…r ids, setBitmapMode for transparency
  • Loading branch information
Mikahil Ilin committed Jul 28, 2023
1 parent 6ddcbdf commit 436d8c3
Show file tree
Hide file tree
Showing 9 changed files with 622 additions and 588 deletions.
28 changes: 16 additions & 12 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Vue.createApp({
screenElements: [],
currentLayer: null,

activeTool: "pen",
activeTool: "draw",
activeTab: "code",

isInverted: false,
Expand Down Expand Up @@ -37,6 +37,9 @@ Vue.createApp({
// this.screenElements = JSON.parse(localStorage.getItem("lopaka_layers")) ?? [];
},
mounted() {
if (this.isFlipper) {
this.activeTool = "frame";
}
if (this.screenElements.length) {
this.updateCode();
this.layerIndex = this.screenElements.length;
Expand All @@ -45,7 +48,6 @@ Vue.createApp({
methods: {
setactiveTab(tab) {
this.activeTab = tab;
this.updateCode();
},
prepareImages(e) {
this.fuiImages = e;
Expand Down Expand Up @@ -146,23 +148,25 @@ Vue.createApp({
selectLibrary(library) {
this.library = library;
if (library === "flipper") {
if (this.activeTool === "draw") {
this.activeTool = "frame";
};
this.display = "128×64";
localStorage.setItem("lopaka_display", this.display);
}
this.updateCode();
localStorage.setItem("lopaka_library", library);
},
updateCode() {
if (this.activeTab === "code") {
const context = this.$refs.fuiCanvas.$refs.screen.getContext("2d", {
willReadFrequently: true,
});
this.codePreview = generateCode(
this.screenElements,
this.library,
context
);
}
const context = this.$refs.fuiCanvas.$refs.screen.getContext("2d", {
willReadFrequently: true,
});
this.codePreview = generateCode(
this.screenElements,
this.library,
context,
this.imageDataCache,
);
},
saveLayers() {
// localStorage.setItem(
Expand Down
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<div id="lopaka_app"></div>
<script src="https://unpkg.com/[email protected]/dist/vue.global.prod.js" type="text/javascript"></script>
<script src="js/utils.js?v=0.3" type="text/javascript"></script>
<script src="js/graphics.js?v=0.3" type="text/javascript"></script>
<script src="js/const.js?v=0.3" type="text/javascript"></script>
<script src="js/templates.js?v=0.3" type="text/javascript"></script>
<script src="js/fui-canvas.js?v=0.3" type="text/javascript"></script>
Expand Down
45 changes: 31 additions & 14 deletions js/components.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ const fuiLayersComponent = {
screenElements: Array,
currentLayer: Object,
},
computed: {
classNames() {
return (item) => ({
layer_selected: this.currentLayer && this.currentLayer.index === item.index,
layer_ignored: item.isOverlay,
});
}
},
methods: {
updateCurrentLayer(item) {
this.$emit("updateCurrentLayer", item);
Expand Down Expand Up @@ -148,11 +156,12 @@ const fuiToolsComponent = {
props: {
callback: Function,
activeTool: String,
library: String,
},
data() {
return {
toolsList: ["pen", "frame", "box", "line", "dot", "circle", "disc"],
};
computed: {
toolsList() {
return [...(this.library !== "flipper" ? ["draw"] : []), "frame", "box", "line", "dot", "circle", "disc"];
},
},
};

Expand All @@ -165,22 +174,29 @@ const fuiInspectorComponent = {
data() {
return {};
},
computed: {
isHWVisible() {
// return true;
return ["frame", "box", "draw", "icon"].includes(
this.elem.type
);
},
isHWDisabled() {
return ["draw", "icon"].includes(
this.elem.type
);
},
isRadiusVisible() {
return ["circle", "disc"].includes(this.elem.type);
},
},
methods: {
update(element) {
this.$emit("updateCurrentLayer", element);
this.$emit("redrawCanvas");
this.$emit("saveLayers");
this.$emit("updateCode");
},
isHWVisible(elem) {
// return true;
return !["line", "str", "dot", "icon", "circle", "disc"].includes(
elem.type
);
},
isRadiusVisible(elem) {
return ["circle", "disc"].includes(elem.type);
},
},
};

Expand All @@ -191,14 +207,15 @@ const fuiInspectorInputComponent = {
<option v-for="(font, idx) in fontsList[library]" :key="idx" :value="font">{{ font }}</option>
</select>
<input v-else-if="type === 'checkbox'" class="inspector__input" @input="onInput" :type="type" :id="id" :checked="element[field]"></input>
<input v-else class="inspector__input" @input="onInput" :value="element[field]" :type="type" :id="id" max="1024" min="-1024" step="1"></input>
<input v-else class="inspector__input" @input="onInput" :value="element[field]" :type="type" :id="id" max="1024" min="-1024" step="1" :disabled="disabled"></input>
`,
props: {
element: Object,
type: String,
field: String,
library: String,
id: String,
disabled: Boolean,
},
computed: {
hasNoWidth() {
Expand Down
1 change: 1 addition & 0 deletions js/const.js
Original file line number Diff line number Diff line change
Expand Up @@ -306,4 +306,5 @@ const KEYS = {
DOWN: 40,
LEFT: 37,
RIGHT: 39,
ESC: 27,
}
120 changes: 36 additions & 84 deletions js/fui-canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const fuiCanvasComponent = {
currentLayer: Object,
fuiImages: Array,
imageDataCache: Object,
library: String,
},
data() {
return {
Expand All @@ -48,7 +49,7 @@ const fuiCanvasComponent = {
return {
"fui-canvas_select": this.activeTool === "select",
"fui-canvas_moving": this.isMoving,
"fui-canvas_draw": this.activeTool === "pen",
"fui-canvas_draw": this.activeTool === "draw",
};
},
canvasWidth() {
Expand Down Expand Up @@ -77,7 +78,7 @@ const fuiCanvasComponent = {

document.addEventListener("mouseup", this.canvasMouseUp);
this.$refs.screen.addEventListener("contextmenu", (event) => {
if (this.isDrawing || this.isMoving || this.activeTool === "pen") {
if (this.isDrawing || this.isMoving || this.activeTool === "draw") {
event.preventDefault();
}
});
Expand Down Expand Up @@ -118,11 +119,10 @@ const fuiCanvasComponent = {
},
canvasMouseDown(e) {
e.preventDefault();
const isRightClickDrawing = this.activeTool === "pen" && e.button === 2;
const isRightClickDrawing = this.activeTool === "draw" && e.button === 2;
if (e.button !== 0 && !isRightClickDrawing || this.isDrawing || this.isMoving) {
return;
}
let layerProps = {};
const [x, y] = [e.offsetX, e.offsetY];
this.oX = scaleDown(x);
this.oY = scaleDown(y);
Expand All @@ -131,54 +131,28 @@ const fuiCanvasComponent = {
this.isDrawing = true;
this.isEraser = e.button === 2;

if (this.currentLayer && this.currentLayer.type !== "pen" || this.activeTool === "select") {
if (this.currentLayer && this.currentLayer.type !== "draw" || this.activeTool === "select") {
this.$emit("updateCurrentLayer", undefined);
}
layerProps = {
name: "",
const uid = generateUID();
let layerProps = {
name: `${this.activeTool}_${uid}`,
type: this.activeTool,
index: this.layerIndex,
x: scaleDown(x),
y: scaleDown(y),
id: uid,
};

if (["pen"].includes(this.activeTool)) {
if (this.currentLayer && this.currentLayer.type === "pen") {
layerProps = {
...this.currentLayer,
imageData: addImageDataPadding(this.currentLayer.imageData, this.currentLayer.x, this.currentLayer.y, this.canvasWidth, this.canvasHeight),
x: this.currentLayer.x > 0 ? 0 : this.currentLayer.x,
y: this.currentLayer.y > 0 ? 0 : this.currentLayer.y,
width: this.currentLayer.imageData.width,
height: this.currentLayer.imageData.height,
}
this.$emit("updateCurrentLayer", layerProps);
} else {
layerProps.x = 0;
layerProps.y = 0;
const imageDataArraylength = 4 * this.canvasWidth * this.canvasHeight;
layerProps.imageData = new ImageData(
new Uint8ClampedArray(imageDataArraylength),
this.canvasWidth,
this.canvasHeight,
);
this.$emit("updateCurrentLayer", {
...layerProps,
width: layerProps.imageData.width,
height: layerProps.imageData.height,
});
this.$emit("addScreenLayer");
if (["draw"].includes(this.activeTool)) {
const isDrawingCurrent = this.currentLayer && this.currentLayer.type === "draw";

layerProps = startDrawing(isDrawingCurrent, layerProps, this.currentLayer, this.canvasWidth, this.canvasHeight, this.oX, this.oY, this.isEraser);

this.$emit("updateCurrentLayer", layerProps);
if (!isDrawingCurrent) {
this.$emit("addScreenLayer", layerProps);
}
drawingLayer = this.currentLayer ? this.currentLayer : layerProps;
drawLine(drawingLayer.imageData,
this.oX - drawingLayer.x,
this.oY - drawingLayer.y,
this.oX - drawingLayer.x,
this.oY - drawingLayer.y,
drawingLayer.imageData.width,
drawingLayer.imageData.height,
this.isEraser,
);
} else if (["frame", "box", "dot", "circle", "disc"].includes(this.activeTool)) {
this.$emit("updateCurrentLayer", {
...layerProps,
Expand Down Expand Up @@ -281,7 +255,7 @@ const fuiCanvasComponent = {
layerProps.x = scaleDown(x);
layerProps.y = scaleDown(y);
}
} else if (this.activeTool === "pen") {
} else if (this.activeTool === "draw") {
drawLine(this.currentLayer.imageData,
this.oX - this.currentLayer.x,
this.oY - this.currentLayer.y,
Expand Down Expand Up @@ -334,7 +308,7 @@ const fuiCanvasComponent = {
canvasMouseLeave(e) {
e.preventDefault();
// this.$refs.cursor.style.transform = `translate3d(-1000px, -1000px, 0)`;
if (["select", "pen"].includes(this.activeTool) && this.isMoving) {
if (["select", "draw"].includes(this.activeTool) && this.isMoving) {
this.isDrawing = false;
this.stopDrawing(e);
}
Expand All @@ -350,7 +324,9 @@ const fuiCanvasComponent = {
this.stopDrawing(e);
this.isDrawing = false;
}
this.redrawCanvas(this.screenElements);
if (this.isDrawing || this.isMoving) {
this.redrawCanvas(this.screenElements);
}
},
stopDrawing() {
this.isEraser = false;
Expand All @@ -377,15 +353,7 @@ const fuiCanvasComponent = {
}
const { isCustom, width, height } = this.fuiImages[name];
const layer = {
type: "icon",
name: name,
index: this.layerIndex,
x: x,
y: y,
width: width,
height: height,
isOverlay: false,
isCustom: isCustom,
type: "icon", name: name, index: this.layerIndex, x: x, y: y, width: width, height: height, isOverlay: false, isCustom: isCustom,
};
this.$emit("updateCurrentLayer", layer);
this.$emit("addScreenLayer", layer);
Expand Down Expand Up @@ -419,46 +387,23 @@ const fuiCanvasComponent = {
}
break;
case "line":
drawLine(
imgData,
x,
y,
x2,
y2,
this.canvasWidth,
this.canvasHeight,
this.scale
);
drawLine(imgData, x, y, x2, y2, this.canvasWidth, this.canvasHeight, false);
this.CTX.putImageData(imgData, 0, 0);
break;
case "circle":
drawCircle(
imgData,
x + radius,
y + radius,
radius,
this.canvasWidth,
this.canvasHeight
);
drawCircle(imgData, x + radius, y + radius, radius, this.canvasWidth, this.canvasHeight);
this.CTX.putImageData(imgData, 0, 0);
break;
case "disc":
drawDisc(
imgData,
x + radius,
y + radius,
radius,
this.canvasWidth,
this.canvasHeight
);
drawDisc(imgData, x + radius, y + radius, radius, this.canvasWidth, this.canvasHeight);
this.CTX.putImageData(imgData, 0, 0);
break;
case "str":
const fontSize = fontSizes[font];
this.CTX.font = `${fontSize}px ${font}`;
this.CTX.fillText(text, x, y);
break;
case "pen":
case "draw":
const newImageData = maskAndMixImageData(imgData, screenElement.imageData, x, y);
this.CTX.putImageData(newImageData, 0, 0);
break;
Expand All @@ -469,10 +414,17 @@ const fuiCanvasComponent = {
this.CTX.restore();
},
keyDownHandler(event) {
if (event.isComposing || event.target !== document.body) {
if (event.isComposing || !Object.values(KEYS).includes(event.keyCode)) {
return;
}
if (event.keyCode === KEYS.ESC) {
this.$emit("updateCurrentLayer");
return;
}
if (event.target !== document.body) {
return;
}
if (this.currentLayer && Object.values(KEYS).includes(event.keyCode)) {
if (this.currentLayer) {
event.preventDefault();
const shift = event.shiftKey ? 10 : 1;
switch (event.keyCode) {
Expand Down
Loading

0 comments on commit 436d8c3

Please sign in to comment.