Add copy to clipboard button on image converter (not supported in all browsers)
This commit is contained in:
parent
cc5340bc7a
commit
a3d1f33969
|
@ -8,8 +8,9 @@ import { connect } from 'react-redux';
|
|||
import fileDownload from 'js-file-download';
|
||||
import { utils, applyPalette } from 'image-q';
|
||||
|
||||
import printGIMPPalette from '../core/exportGPL';
|
||||
import type { State } from '../reducers';
|
||||
import printGIMPPalette from '../core/exportGPL';
|
||||
import { copyCanvasToClipboard } from '../utils/clipboard';
|
||||
|
||||
const titleStyle = {
|
||||
color: '#4f545c',
|
||||
|
@ -190,7 +191,6 @@ async function renderOutputImage(opts) {
|
|||
palette.add(point);
|
||||
});
|
||||
const progEl = document.getElementById('qprog');
|
||||
progEl.style.display = 'block';
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
pointContainer = await applyPalette(pointContainer, palette, {
|
||||
colorDistanceFormula: colorDist,
|
||||
|
@ -199,7 +199,7 @@ async function renderOutputImage(opts) {
|
|||
progEl.innerHTML = `Loading... ${Math.round(progress)} %`;
|
||||
},
|
||||
});
|
||||
progEl.style.display = 'none';
|
||||
progEl.innerHTML = 'Done';
|
||||
image = drawPixels(
|
||||
pointContainer.toUint8Array(),
|
||||
image.width,
|
||||
|
@ -267,13 +267,9 @@ function Converter({
|
|||
scaling: scaleData,
|
||||
});
|
||||
} else {
|
||||
// draw gray rectanglue if no file selected
|
||||
const output = document.getElementById('imgoutput');
|
||||
const ctx = output.getContext('2d');
|
||||
output.width = 128;
|
||||
output.height = 100;
|
||||
ctx.fillStyle = '#C4C4C4';
|
||||
ctx.fillRect(0, 0, 128, 100);
|
||||
output.width = 0;
|
||||
output.height = 0;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -595,7 +591,7 @@ function Converter({
|
|||
</div>
|
||||
)
|
||||
: null}
|
||||
<p id="qprog" />
|
||||
<p id="qprog">Select an Image</p>
|
||||
<p>
|
||||
<canvas
|
||||
id="imgoutput"
|
||||
|
@ -608,6 +604,19 @@ function Converter({
|
|||
>
|
||||
Download Template
|
||||
</button>
|
||||
{(typeof ClipboardItem === 'undefined')
|
||||
? null
|
||||
: (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => {
|
||||
const output = document.getElementById('imgoutput');
|
||||
copyCanvasToClipboard(output);
|
||||
}}
|
||||
>
|
||||
Copy to Clipboard
|
||||
</button>
|
||||
)}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ class LogInForm extends React.Component {
|
|||
onChange={(evt) => this.setState({ nameoremail: evt.target.value })}
|
||||
type="text"
|
||||
placeholder="Name or Email"
|
||||
/>
|
||||
/><br />
|
||||
<input
|
||||
value={password}
|
||||
style={inputStyles}
|
||||
|
|
|
@ -111,7 +111,7 @@ function SettingsModal({
|
|||
}) {
|
||||
return (
|
||||
<Modal title="Settings">
|
||||
<p style={{ paddingLeft: '5%', paddingRight: '5%' }}>
|
||||
<p style={{ paddingLeft: '5%', paddingRight: '5%', paddingTop: 30 }}>
|
||||
<SettingsItem
|
||||
title="Show Grid"
|
||||
description="Turn on grid to highlight pixel borders."
|
||||
|
|
|
@ -107,21 +107,21 @@ class SignUpForm extends React.Component {
|
|||
onChange={(evt) => this.setState({ name: evt.target.value })}
|
||||
type="text"
|
||||
placeholder="Name"
|
||||
/>
|
||||
/><br />
|
||||
<input
|
||||
style={inputStyles}
|
||||
value={this.state.email}
|
||||
onChange={(evt) => this.setState({ email: evt.target.value })}
|
||||
type="text"
|
||||
placeholder="Email"
|
||||
/>
|
||||
/><br />
|
||||
<input
|
||||
style={inputStyles}
|
||||
value={this.state.password}
|
||||
onChange={(evt) => this.setState({ password: evt.target.value })}
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
/>
|
||||
/><br />
|
||||
<input
|
||||
style={inputStyles}
|
||||
value={this.state.confirmPassword}
|
||||
|
@ -130,8 +130,7 @@ class SignUpForm extends React.Component {
|
|||
})}
|
||||
type="password"
|
||||
placeholder="Confirm Password"
|
||||
/>
|
||||
<br />
|
||||
/><br />
|
||||
<button type="submit">
|
||||
{(this.state.submitting) ? '...' : 'Submit'}
|
||||
</button>
|
||||
|
|
|
@ -75,7 +75,7 @@ class UserMessages extends React.Component {
|
|||
const messages = [...this.props.messages];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={{ paddingLeft: '5%', paddingRight: '5%' }}>
|
||||
{(messages.includes('not_verified') && messages.splice(messages.indexOf('not_verified'), 1))
|
||||
? (
|
||||
<p className="usermessages">
|
||||
|
@ -98,7 +98,7 @@ class UserMessages extends React.Component {
|
|||
</p>
|
||||
) : null}
|
||||
{messages.map((message) => (
|
||||
<p className="usermessages" key={message} className="message">{message}</p>
|
||||
<p className="usermessages" key={message}>{message}</p>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -24,7 +24,27 @@ function fallbackCopyTextToClipboard(text) {
|
|||
}
|
||||
}
|
||||
|
||||
export default async function copyTextToClipboard(text) {
|
||||
export async function copyCanvasToClipboard(canvas) {
|
||||
canvas.toBlob((blob) => {
|
||||
try {
|
||||
if (!navigator.clipboard) {
|
||||
throw new Error('Clipboard API not implemented');
|
||||
}
|
||||
navigator.clipboard.write([
|
||||
// this is defined in current chrome, but not firefox
|
||||
// eslint-disable-next-line no-undef
|
||||
new ClipboardItem({
|
||||
'image/png': blob,
|
||||
}),
|
||||
]);
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log("Couldn't copy canvas to clipboard", e);
|
||||
}
|
||||
}, 'image/png');
|
||||
}
|
||||
|
||||
async function copyTextToClipboard(text) {
|
||||
if (!navigator.clipboard) {
|
||||
return fallbackCopyTextToClipboard(text);
|
||||
}
|
||||
|
@ -35,3 +55,5 @@ export default async function copyTextToClipboard(text) {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export default copyTextToClipboard;
|
||||
|
|
Loading…
Reference in New Issue
Block a user