Skip to content

Commit c27d92c

Browse files
committed
separete resize and scale, copy emulation
1 parent 31e5e95 commit c27d92c

6 files changed

Lines changed: 82 additions & 15 deletions

File tree

css/styles.css

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* should be first rule here for detecting stylesheet */
21
.ptro-wrapper {
32
position: absolute;
43
top: 0;
@@ -7,6 +6,7 @@
76
right: 0;
87
text-align: center;
98
z-index: 10;
9+
font-family: "Open Sans", sans-serif;
1010
}
1111

1212
.ptro-holder {
@@ -368,13 +368,12 @@
368368
.ptro-link {
369369
float: left;
370370
margin-right: -12px;
371-
margin-top: -20px;
371+
margin-top: -23px;
372372
}
373373

374374
.ptro-resize-link-wrapper {
375375
display: inline-block;
376376
height: 20px;
377-
padding-left: 10px;
378377
}
379378

380379

js/inserter.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { tr } from './translation';
2-
import { genId, KEYS } from './utils';
2+
import { genId, KEYS, copyToClipboard } from './utils';
33

44
export default class Inserter {
55
constructor() {
@@ -75,6 +75,7 @@ export default class Inserter {
7575
}
7676

7777
init(main) {
78+
this.CLIP_DATA_MARKER = 'painterro-data:';
7879
this.ctx = main.ctx;
7980
this.main = main;
8081
this.worklog = main.worklog;
@@ -138,6 +139,18 @@ export default class Inserter {
138139
if (this.waitChoice && evt.keyCode === KEYS.esc) {
139140
this.cancelChoosing();
140141
}
142+
if (!this.waitChoice && !this.main.select.imagePlaced &&
143+
evt.keyCode === KEYS.c && (evt.ctrlKey || evt.metaKey)) {
144+
const a = this.main.select.area;
145+
const w = a.bottoml[0] - a.topl[0];
146+
const h = a.bottoml[1] - a.topl[1];
147+
const tmpCan = document.createElement('canvas');
148+
tmpCan.width = w;
149+
tmpCan.height = h;
150+
const tmpCtx = tmpCan.getContext('2d');
151+
tmpCtx.drawImage(this.main.canvas, -a.topl[0], -a.topl[1]);
152+
copyToClipboard(`${this.CLIP_DATA_MARKER}${tmpCan.toDataURL()}`);
153+
}
141154
}
142155

143156
startLoading() {

js/main.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,16 @@ class PainterroProc {
588588
const item = items[k];
589589
if (item.kind === 'file' && item.type.split('/')[0] === 'image') {
590590
this.openFile(item.getAsFile());
591+
} else if (item.kind === 'string') {
592+
let txt = '';
593+
if (window.clipboardData && window.clipboardData.getData) { // IE
594+
txt = window.clipboardData.getData('Text');
595+
} else if (event.clipboardData && event.clipboardData.getData) {
596+
txt = event.clipboardData.getData('text/plain');
597+
}
598+
if (txt.startsWith(this.inserter.CLIP_DATA_MARKER)) {
599+
this.loadImage(txt.slice(this.inserter.CLIP_DATA_MARKER.length));
600+
}
591601
}
592602
});
593603
}

js/resizer.js

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ export default class Resizer {
1111
this.linkButton = document.querySelector(`#${main.id} .ptro-resize-widget-wrapper button.ptro-link`);
1212
this.linkButtonIcon = document.querySelector(`#${main.id} .ptro-resize-widget-wrapper button.ptro-link i`);
1313
this.closeButton = document.querySelector(`#${main.id} .ptro-resize-widget-wrapper button.ptro-close`);
14-
this.applyButton = document.querySelector(`#${main.id} .ptro-resize-widget-wrapper button.ptro-apply`);
15-
14+
this.scaleButton = document.querySelector(`#${main.id} .ptro-resize-widget-wrapper button.ptro-scale`);
15+
this.resizeButton = document.querySelector(`#${main.id} .ptro-resize-widget-wrapper button.ptro-resize`);
1616
this.linked = true;
1717
this.closeButton.onclick = () => {
1818
this.startClose();
1919
};
2020

21-
this.applyButton.onclick = () => {
21+
this.scaleButton.onclick = () => {
2222
const origW = this.main.size.w;
2323
const origH = this.main.size.h;
2424

@@ -40,6 +40,20 @@ export default class Resizer {
4040
img.src = tmpData;
4141
};
4242

43+
this.resizeButton.onclick = () => {
44+
const tmpData = this.main.canvas.toDataURL();
45+
this.main.resize(this.newW, this.newH);
46+
this.main.clearBackground();
47+
const img = new Image();
48+
img.onload = () => {
49+
this.main.ctx.drawImage(img, 0, 0);
50+
this.main.adjustSizeFull();
51+
this.main.worklog.captureState();
52+
this.startClose();
53+
};
54+
img.src = tmpData;
55+
};
56+
4357
this.linkButton.onclick = () => {
4458
this.linked = !this.linked;
4559
if (this.linked) {
@@ -107,15 +121,16 @@ export default class Resizer {
107121
'</div>' +
108122
'<div class="ptro-resize-link-wrapper">' +
109123
`<button class="ptro-icon-btn ptro-link ptro-color-control" title="${tr('keepRatio')}">` +
110-
'<i class="ptro-icon ptro-icon-linked"></i>' +
124+
'<i class="ptro-icon ptro-icon-linked" style="font-size: 18px;"></i>' +
111125
'</button>' +
112126
'</div>' +
113-
'<div>' +
114-
'<button class="ptro-named-btn ptro-apply ptro-color-control" ' +
115-
'style="margin-top: 8px;position: absolute; top: 95px; right: 75px;">' +
116-
`${tr('apply')}</button>` +
117-
'<button class="ptro-named-btn ptro-close ptro-color-control" ' +
118-
'style="margin-top: 8px;position: absolute; top: 95px; right: 10px;">' +
127+
'<div></div>' +
128+
'<div style="margin-top: 40px;">' +
129+
'<button class="ptro-named-btn ptro-resize ptro-color-control">' +
130+
`${tr('resizeResize')}</button>` +
131+
'<button class="ptro-named-btn ptro-scale ptro-color-control">' +
132+
`${tr('resizeScale')}</button>` +
133+
'<button class="ptro-named-btn ptro-close ptro-color-control">' +
119134
`${tr('cancel')}</button>` +
120135
'</div>' +
121136
'</div>' +

js/translation.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ export class Translation {
2727
keepRatio: 'Keep width/height ratio',
2828
pixelSize: 'P:',
2929
pixelSizeFull: 'Pixel Size',
30+
resizeScale: 'Scale',
31+
resizeResize: 'Resize',
3032
tools: {
3133
crop: 'Crop image to selected area',
3234
pixelize: 'Pixelize selected area',
@@ -38,7 +40,7 @@ export class Translation {
3840
load: 'Load image',
3941
text: 'Put text',
4042
brush: 'Brush',
41-
resize: 'Resize image',
43+
resize: 'Resize or scale',
4244
open: 'Open image',
4345
select: 'Select area',
4446
},

js/utils.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,35 @@ export const KEYS = {
8181
y: 89,
8282
z: 90,
8383
s: 83,
84+
c: 67,
85+
x: 88,
8486
enter: 13,
8587
esc: 27,
8688
};
8789

90+
// Copies a string to the clipboard. Must be called from within an
91+
// event handler such as click. May return false if it failed, but
92+
// this is not always possible. Browser support for Chrome 43+,
93+
// Firefox 42+, Safari 10+, Edge and IE 10+.
94+
// IE: The clipboard feature may be disabled by an administrator. By
95+
// default a prompt is shown the first time the clipboard is
96+
// used (per session).
97+
export function copyToClipboard(text) {
98+
if (window.clipboardData && window.clipboardData.setData) {
99+
// IE specific code path to prevent textarea being shown while dialog is visible.
100+
window.clipboardData.setData('Text', text);
101+
} else if (document.queryCommandSupported && document.queryCommandSupported('copy')) {
102+
const textarea = document.createElement('textarea');
103+
textarea.textContent = text;
104+
textarea.style.position = 'fixed'; // Prevent scrolling to bottom of page in MS Edge.
105+
document.body.appendChild(textarea);
106+
textarea.select();
107+
try {
108+
document.execCommand('copy'); // Security exception may be thrown by some browsers.
109+
} catch (ex) {
110+
console.warn('Copy to clipboard failed.', ex);
111+
} finally {
112+
document.body.removeChild(textarea);
113+
}
114+
}
115+
}

0 commit comments

Comments
 (0)