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

Last change on this file since 35748 was 35748, checked in by cstephen, 13 months ago

Annotated some UI components

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