source: main/trunk/model-interfaces-dev/atea/ocr/src/components/EditPage.vue@ 35746

Last change on this file since 35746 was 35746, checked in by cstephen, 2 years ago

Implement edit saving

File size: 6.9 KB
Line 
1<template>
2<div class="edit-page-root">
3 <div class="image-panel">
4 <div class="image-container" :style="{ transform: transformString }">
5 <img v-if="rotateMode" src="images/rotate-arrow.svg" class="rotate-handle rotate-tl" @mousedown="allowRotation = true" draggable="false" />
6 <img v-if="rotateMode" src="images/rotate-arrow.svg" class="rotate-handle rotate-tr" @mousedown="allowRotation = true" draggable="false" />
7 <img v-if="rotateMode" src="images/rotate-arrow.svg" class="rotate-handle rotate-bl" @mousedown="allowRotation = true" draggable="false" />
8 <img v-if="rotateMode" src="images/rotate-arrow.svg" class="rotate-handle rotate-br" @mousedown="allowRotation = true" draggable="false" />
9
10 <table v-if="rotateMode" class="rotate-guide" :style="{ transform: transformStringInverted }">
11 <tr><td><hr /></td></tr>
12 <tr><td><hr /></td></tr>
13 <tr><td><hr /></td></tr>
14 <tr><td><hr /></td></tr>
15 <tr><td><hr /></td></tr>
16 <tr><td><hr /></td></tr>
17 <tr><td><hr /></td></tr>
18 <tr><td><hr /></td></tr>
19 <tr><td><hr /></td></tr>
20 <tr><td><hr /></td></tr>
21 <tr><td><hr /></td></tr>
22 <tr><td><hr /></td></tr>
23 </table>
24
25 <img ref="image" :src="src" class="image" :style="{ filter: filterString }" />
26 </div>
27 </div>
28
29 <div class="control-panel">
30 <button class="btn-fab" @click="$emit('closeAndDiscard')">
31 <span class="material-icons mdi-l">cancel</span>
32 </button>
33
34 <button class="btn-fab" @click="closeAndSave">
35 <span class="material-icons mdi-l">save</span>
36 </button>
37
38 <button class="btn-fab" @click="invert = !invert">
39 <span class="material-icons mdi-l">invert_colors</span>
40 </button>
41
42 <toggle-button v-model="rotateMode">
43 <span class="material-icons mdi-l">crop_rotate</span>
44 </toggle-button>
45 </div>
46</div>
47</template>
48
49<style lang="scss" scoped>
50.edit-page-root {
51 display: grid;
52 grid-template-columns: 1fr auto;
53 align-items: center;
54 justify-items: center;
55 background: rgba(0, 0, 0, 0.8);
56}
57
58.image-panel {
59 position: relative;
60 height: 100%;
61 width: 100%;
62
63 display: grid;
64 align-items: center;
65 justify-items: center;
66}
67
68.image {
69 max-width: 70vw;
70 max-height: 70vh;
71}
72
73.image-container {
74 position: relative;
75 margin: auto;
76 padding: 1.5em;
77 user-select: none;
78
79 .rotate-handle {
80 height: 2em;
81 position: absolute;
82 z-index: 5;
83
84 // Generated with https://codepen.io/sosuke/pen/Pjoqqp using var(--primary-bg-color)
85 // filter: invert(16%) sepia(100%) saturate(3091%) hue-rotate(347deg) brightness(75%) contrast(90%);
86 }
87
88 .rotate-tl {
89 top: 0;
90 left: 0;
91 }
92
93 .rotate-tr {
94 top: 0;
95 right: 0;
96 transform: rotate(90deg);
97 }
98
99 .rotate-bl {
100 bottom: 0;
101 left: 0;
102 transform: rotate(270deg);
103 }
104
105 .rotate-br {
106 bottom: 0;
107 right: 0;
108 transform: rotate(180deg);
109 }
110}
111
112.rotate-guide {
113 position: absolute;
114 top: 0;
115 left: 0;
116 height: 100%;
117 width: 100%;
118 z-index: 3;
119
120 tr {
121 td {
122 vertical-align: center;
123 }
124
125 hr {
126 background-color: rgba(var(--bg-color-raw), 0.5);
127 height: 2px;
128 }
129 }
130}
131
132.control-panel {
133 display: flex;
134 flex-direction: column;
135 justify-content: center;
136 align-items: center;
137
138 padding: 0.5em;
139 gap: 1em;
140 height: 100%;
141
142 // background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.2) 10%);
143}
144</style>
145
146<script>
147import { mapState } from "vuex";
148import Jimp from "jimp/es";
149import ToggleButton from "./ToggleButton.vue"
150
151export default {
152 name: "EditPage",
153 components: {
154 ToggleButton
155 },
156 props: {
157 imageBuffer: ArrayBuffer,
158 src: String
159 },
160 emits: [ "closeAndDiscard", "closeAndSave" ],
161 data() {
162 return {
163 invert: false,
164 rotation: 0,
165 rotateMode: false,
166 allowRotation: false
167 }
168 },
169 computed: {
170 ...mapState({
171 translations: state => state.translations,
172 filterString() {
173 let filters = "";
174
175 if (this.invert) {
176 filters += "invert(1) ";
177 }
178
179 return filters;
180 },
181 transformString() {
182 return `rotate(${this.rotation}deg)`;
183 },
184 transformStringInverted() {
185 return `rotate(-${this.rotation}deg)`;
186 }
187 })
188 },
189 methods: {
190 async closeAndSave() {
191 const buffer = Buffer.from(this.imageBuffer);
192 const that = this;
193
194 const modifiedBuffer = await Jimp.read(buffer)
195 .then(async image => {
196 if (that.invert) {
197 image.invert();
198 }
199
200 if (that.rotation !== 0) {
201 image.rotate(-that.rotation);
202 }
203
204 return await image.getBufferAsync(Jimp.MIME_PNG);
205 });
206
207 this.$emit("closeAndSave", modifiedBuffer, Jimp.MIME_PNG);
208 },
209
210 onRotateHandleMouseDown(point) {
211 console.log(point);
212 this.rotatePoint = point;
213 },
214 /**
215 * @param {MouseEvent} e The mouse movement event.
216 */
217 onDocumentMouseMove(e) {
218 if (!this.allowRotation) {
219 return;
220 }
221
222 const imageRectangle = this.$refs.image.getBoundingClientRect();
223 const imageCenterX = (imageRectangle.width / 2) + imageRectangle.left;
224 const imageCenterY = (imageRectangle.height / 2) + imageRectangle.top;
225
226 if (e.clientX > imageCenterX) {
227 this.rotation += e.movementY / 8;
228 }
229 else {
230 this.rotation -= e.movementY / 8;
231 }
232
233 if (e.clientY > imageCenterY) {
234 this.rotation -= e.movementX / 8;
235 }
236 else {
237 this.rotation += e.movementX / 8;
238 }
239
240 if (this.rotation < 0) {
241 this.rotation = 360 + this.rotation;
242 }
243 else if (this.rotation > 360) {
244 this.rotation -= 360;
245 }
246 },
247 onDocumentMouseUp() {
248 this.allowRotation = false;
249 }
250 },
251 beforeMount() {
252 document.addEventListener("mousemove", this.onDocumentMouseMove);
253 document.addEventListener("mouseup", this.onDocumentMouseUp);
254 },
255 beforeUnmount() {
256 document.removeEventListener("mousemove", this.onDocumentMouseMove);
257 document.removeEventListener("mouseup", this.onDocumentMouseUp);
258 }
259}
260</script>
Note: See TracBrowser for help on using the repository browser.