37 |
38 |
39 |
--------------------------------------------------------------------------------
/resources/view_nine_patch.js:
--------------------------------------------------------------------------------
1 | const main = document.getElementById('main');
2 | const ninePatchPreview = document.getElementById('nine_patch_preview');
3 | const previewBackground = document.getElementById('preview');
4 | const stretchWidth = document.getElementById('stretch_width');
5 | const stretchHeight = document.getElementById('stretch_height');
6 | const showContent = document.getElementById('show_content');
7 | const bgToggleLight = document.getElementById('bg_toggle_light');
8 | const bgToggleDark = document.getElementById('bg_toggle_dark');
9 | const bgToggleWhite = document.getElementById('bg_toggle_white');
10 | const labelStretchWidth = document.getElementById('label_stretch_width');
11 | const labelStretchHeight = document.getElementById('label_stretch_height');
12 | const labelStretchContext = document.getElementById('label_stretch_content');
13 | const cancelButton = document.getElementById('cancel');
14 | const exportButton = document.getElementById('export');
15 | let originalWidth = ninePatchPreview.offsetWidth;
16 | let originalHeight = ninePatchPreview.offsetHeight;
17 |
18 | bgToggleLight.onclick = function() {
19 | previewBackground.setAttribute("class", "bg_light");
20 | }
21 |
22 | bgToggleDark.onclick = function() {
23 | previewBackground.setAttribute("class", "bg_dark");
24 | }
25 |
26 | bgToggleWhite.onclick = function() {
27 | previewBackground.setAttribute("class", "bg_white");
28 | }
29 |
30 | function redrawNinePatch(base64) {
31 | var ninePatchWidth = originalWidth + originalWidth * stretchWidth.value/50,
32 | ninePatchHeight = originalHeight + originalHeight * stretchHeight.value/50;
33 | ninePatchPreview.style.transition = ".2s"; //width .2s, height
34 | stretchHeight.style.backgroundSize = stretchHeight.value + "% 100%";
35 | stretchWidth.style.backgroundSize = stretchWidth.value + "% 100%";
36 | drawNinePatch(base64, ninePatchWidth, ninePatchHeight, showContent.checked);
37 | }
38 |
39 | function drawNinePatch(base64, width, height, showContent) {
40 |
41 | var scale = 2;
42 | var _canvas = document.createElement("canvas");
43 | var _ctx = _canvas.getContext("2d");
44 | var img = new Image();
45 | img.onload = function() {
46 | _canvas.width = img.width;
47 | _canvas.height = img.height;
48 | _ctx.drawImage(img, 0, 0);
49 |
50 | // Patch data
51 | var horizontalData = _ctx.getImageData(0, 0, img.width - 1 * scale, 1).data;
52 | var verticalData = _ctx.getImageData(0, 0, 1, img.height - 1 * scale).data;
53 | var patchTop = [[scale,0,0]];
54 | var patchLeft = [[scale,0,0]];
55 | for (var i = 1; i < horizontalData.length/4; i ++) {
56 | var a = horizontalData[i*4+3],
57 | _a = horizontalData[(i-1)*4+3];
58 | if (a != _a) {
59 | patchTop[patchTop.length - 1][1] = i - patchTop[patchTop.length - 1][0];
60 | if (a == 255) {
61 | patchTop[patchTop.length - 1][2] = 0;
62 | } else {
63 | patchTop[patchTop.length - 1][2] = 1;
64 | }
65 | patchTop.push([i, horizontalData.length/4-i, 0])
66 | }
67 | if (i == horizontalData.length/4 - 1 && a == 255) {
68 | patchTop[patchTop.length - 1][2] = 1;
69 | }
70 | }
71 | for (var i = 1; i < verticalData.length/4; i ++) {
72 | var a = verticalData[i*4+3],
73 | _a = verticalData[(i-1)*4+3];
74 | if (a != _a) {
75 | patchLeft[patchLeft.length - 1][1] = i - patchLeft[patchLeft.length - 1][0];
76 | if (a == 255) {
77 | patchLeft[patchLeft.length - 1][2] = 0;
78 | } else {
79 | patchLeft[patchLeft.length - 1][2] = 1;
80 | }
81 | patchLeft.push([i, verticalData.length/4-i, 0])
82 | }
83 | if (i == verticalData.length/4 - 1 && a == 255) {
84 | patchLeft[patchLeft.length - 1][2] = 1;
85 | }
86 | }
87 |
88 | // Get padding
89 | var paddingTop = 0,
90 | paddingBottom = 0,
91 | paddingLeft = 0,
92 | paddingRight = 0;
93 | var paddingTopBottomData = _ctx.getImageData(img.width-1, 1*scale, 1, img.height-2*scale).data;
94 | var paddingLeftRightData = _ctx.getImageData(1*scale, img.height-1, img.width-2*scale, 1).data;
95 | for (var i = 0; i < paddingTopBottomData.length/4; i ++) {
96 | if (
97 | paddingTopBottomData[i*4] == 0 &&
98 | paddingTopBottomData[i*4+1] == 0 &&
99 | paddingTopBottomData[i*4+2] == 0 &&
100 | paddingTopBottomData[i*4+3] == 255
101 | ) {
102 | paddingTop = i;
103 | break;
104 | }
105 | }
106 | for (var i = paddingTopBottomData.length/4; i > -1; i --) {
107 | if (
108 | paddingTopBottomData[i*4] == 0 &&
109 | paddingTopBottomData[i*4+1] == 0 &&
110 | paddingTopBottomData[i*4+2] == 0 &&
111 | paddingTopBottomData[i*4+3] == 255
112 | ) {
113 | paddingBottom = paddingTopBottomData.length/4-i-1;
114 | break;
115 | }
116 | }
117 | for (var i = 0; i < paddingLeftRightData.length/4; i ++) {
118 | if (
119 | paddingLeftRightData[i*4] == 0 &&
120 | paddingLeftRightData[i*4+1] == 0 &&
121 | paddingLeftRightData[i*4+2] == 0 &&
122 | paddingLeftRightData[i*4+3] == 255
123 | ) {
124 | paddingLeft = i;
125 | break;
126 | }
127 | }
128 | for (var i = paddingLeftRightData.length/4; i > -1; i --) {
129 | if (
130 | paddingLeftRightData[i*4] == 0 &&
131 | paddingLeftRightData[i*4+1] == 0 &&
132 | paddingLeftRightData[i*4+2] == 0 &&
133 | paddingLeftRightData[i*4+3] == 255
134 | ) {
135 | paddingRight = paddingLeftRightData.length/4-i-1;
136 | break;
137 | }
138 | }
139 |
140 | var canvas = document.createElement("canvas");
141 | var ctx = canvas.getContext("2d");
142 | canvas.width = width;
143 | canvas.height = height;
144 | canvas.style.width = width + "px";
145 | canvas.style.height = height + "px";
146 |
147 | ctx.imageSmoothingEnabled = false;
148 |
149 | // Draw start
150 | var dx = 0,
151 | dy = 0,
152 | dw = 0,
153 | dh = 0;
154 | for (var i = 0; i < patchLeft.length; i++) {
155 | dy += dh;
156 | if (patchLeft[i][2] == 0) {
157 | dh = patchLeft[i][1];
158 | } else {
159 | dh = getLength(patchLeft, height);
160 | }
161 | for (var j = 0; j < patchTop.length; j++) {
162 | var sx = patchTop[j][0],
163 | sy = patchLeft[i][0],
164 | sw = patchTop[j][1],
165 | sh = patchLeft[i][1];
166 | dx += dw;
167 | if (patchTop[j][2] == 0) {
168 | dw = patchTop[j][1];
169 | } else {
170 | dw = getLength(patchTop, width);
171 | }
172 | ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh);
173 | }
174 | dx = 0;
175 | dw = 0;
176 | }
177 |
178 | // Draw padding
179 | if (showContent) {
180 | ctx.fillStyle = "rgba(233, 32, 99, 0.3)";
181 | ctx.fillRect(
182 | paddingLeft,
183 | paddingTop,
184 | width-paddingLeft-paddingRight,
185 | height-paddingTop-paddingBottom
186 | );
187 | }
188 |
189 | ninePatchPreview.style.width = (width / scale) + "px";
190 | ninePatchPreview.style.height = (height / scale) + "px";
191 | ninePatchPreview.style.marginLeft = (width / scale) * -0.5 + "px";
192 | ninePatchPreview.style.marginTop = (height / scale) * -0.5 + "px";
193 | ninePatchPreview.style.background = "url(" + canvas.toDataURL("image/png") + ") no-repeat";
194 | ninePatchPreview.style.backgroundSize = "cover";
195 |
196 | }
197 |
198 | img.src = "data:image/png;base64," + base64;
199 | }
200 |
201 | function getLength(patchData, maxLength) {
202 | var fixWidth = 0,
203 | count = 0;
204 | for (var i = 0; i < patchData.length; i++) {
205 | if (patchData[i][2] == 0) {
206 | fixWidth += patchData[i][1];
207 | } else {
208 | count ++;
209 | }
210 | }
211 | return Math.round((maxLength - fixWidth) / count);
212 | }
213 |
214 | // disable the context menu (eg. the right click menu) to have a more native feel
215 | document.addEventListener('contextmenu', (e) => {
216 | e.preventDefault();
217 | });
218 |
219 | // call the plugin from the webview
220 | exportButton.addEventListener('click', () => {
221 | window.postMessage('export');
222 | });
223 |
224 | cancelButton.addEventListener('click', () => {
225 | window.postMessage('cancel');
226 | });
227 |
228 | main.style.opacity = '0';
229 |
230 | window.main = (base64, ninePatchWidth, ninePatchHeight, json) => {
231 |
232 | originalWidth = ninePatchWidth;
233 | originalHeight = ninePatchHeight;
234 |
235 | stretchWidth.oninput = function() {
236 | redrawNinePatch(base64);
237 | }
238 |
239 | stretchHeight.oninput = function() {
240 | redrawNinePatch(base64);
241 | }
242 |
243 | showContent.onchange = function() {
244 | redrawNinePatch(base64);
245 | }
246 |
247 | drawNinePatch(base64, ninePatchWidth, ninePatchHeight, false);
248 |
249 | // i18n
250 | const langs = JSON.parse(json);
251 | bgToggleLight.setAttribute('title', langs.tip_bg_light);
252 | bgToggleDark.setAttribute('title', langs.tip_bg_dark);
253 | bgToggleWhite.setAttribute('title', langs.tip_bg_white);
254 | labelStretchWidth.textContent = langs.width;
255 | labelStretchHeight.textContent = langs.height;
256 | labelStretchContext.textContent = langs.content;
257 | exportButton.textContent = langs.export;
258 | cancelButton.textContent = langs.cancel;
259 |
260 | main.style.opacity = '1';
261 | }
262 |
--------------------------------------------------------------------------------
/resources/view_vector_drawable_code.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
42 |