Status overlay (SVG mask) does not show
rovansteen opened this issue · comments
When I upload an image via filepond the status overlay becomes a solid color, on further inspection it seems that the SVG mask is not displayed, causing the status color to fill the complete shape with a solid color.
Here is the code I use to set up Filepond.
import React from 'react';
import 'doka/doka.min.css';
import * as Doka from 'doka';
import cookie from 'js-cookie';
import Box from 'components/box';
import styled from 'library/styled';
import * as config from 'library/config';
import { File, FilePond, registerPlugin } from 'react-filepond';
import 'filepond/dist/filepond.min.css';
import FilePondPluginImageEdit from 'filepond-plugin-image-edit';
import FilePondPluginImageCrop from 'filepond-plugin-image-crop';
import FilePondPluginImageResize from 'filepond-plugin-image-resize';
import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
import 'filepond-plugin-image-edit/dist/filepond-plugin-image-edit.css';
import FilePondPluginImageTransform from 'filepond-plugin-image-transform';
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css';
import FilePondPluginImageExifOrientation from 'filepond-plugin-image-exif-orientation';
registerPlugin(
FilePondPluginImageExifOrientation,
FilePondPluginImagePreview,
FilePondPluginImageCrop,
FilePondPluginImageResize,
FilePondPluginImageTransform,
FilePondPluginImageEdit,
);
interface Props {
required?: boolean;
cropAspectRatio?: string | number | null;
onChange: (value: any) => void;
value?: any;
}
interface State {
image: any;
}
export default class ImageUpload extends React.Component<Props> {
/**
* Define the default props.
*/
static defaultProps = {
cropAspectRatio: null,
};
/**
* Get the derived state from the props.
*
* @static
* @param {Props} props
* @param {State} state
*/
static getDerivedStateFromProps(props: Props, state: State) {
return {
image: state.image || props.value,
};
}
/**
* Define the initial state.
*/
state = {
image: null,
};
/**
* Ref to the pond instance.
*/
pond = React.createRef();
/**
* Server config.
*/
getConfig() {
const token = cookie.get('XSRF-TOKEN');
if (!token) {
throw new Error('Could not set up a secure connection with the server.');
}
return {
url: config.api.uploadImage,
process: {
withCredentials: true,
headers: {
Accept: 'application/json',
'X-XSRF-TOKEN': token,
},
},
};
}
/**
* Handle when the image is uploaded.
*/
handleUpload = (error: any, file: any) => {
if (error) throw error;
this.props.onChange(file.serverId);
};
/**
* Handle when the image is added.
*/
handleUpdate = (files: Array<any>) => {
this.setState({ image: files.length ? files[0].file : null });
};
/**
* Handle when the image is removed.
*/
handleRemoval = (file: any) => {
this.props.onChange(null);
};
/**
* Render the component.
*/
render() {
const { image } = this.state;
const { cropAspectRatio, required } = this.props;
return (
<Box maxWidth="170px">
<FilePond
name="payload"
ref={(ref: any) => (this.pond = ref)}
required={required}
allowRevert={false}
allowMultiple={false}
imageCropAspectRatio={cropAspectRatio}
imageEditInstantEdit={false}
imageEditEditor={Doka.create()}
server={this.getConfig()}
onprocessfile={this.handleUpload}
onupdatefiles={this.handleUpdate}
onremovefile={this.handleRemoval}
labelIdle={`Drag & Drop your picture or <span class="filepond--label-action">Browse</span>`}
imagePreviewHeight={170}
imageResizeTargetWidth={100}
imageResizeTargetHeight={100}
stylePanelLayout="compact circle"
styleButtonRemoveItemPosition="center bottom"
styleProgressIndicatorPosition="center bottom"
styleImageEditButtonEditItemPosition="right bottom"
>
{image && <File key={image} src={image} origin="local" />}
</FilePond>
</Box>
);
}
}
Versions:
"filepond": "^3.5.1",
"filepond-plugin-image-crop": "^2.0.0",
"filepond-plugin-image-edit": "^1.0.1",
"filepond-plugin-image-exif-orientation": "^1.0.3",
"filepond-plugin-image-preview": "^3.1.4",
"filepond-plugin-image-resize": "^2.0.1",
"filepond-plugin-image-transform": "^3.1.0",
Weirdly enough, sometimes it does work (like once every 10 attempts). Could it be some kind of race condition?
Hi Robert, that's weird indeed. The Image Preview plugin generates a sprite map at the root of the page (as a child of the body element). Maybe it's somehow removed? Does the React app live in a <div>
as a child of <body>
?
@rikschennink Yes I'm using the default create-react-app
template which renders React in a <div id="root" />
that is a direct descendant of <body>
.
In the cases it does work (seemingly random) I indeed see a <svg>
node as child of <body>
and in the cases it does not work it's missing.
Okay, thanks for clarifying, my test environment is based on create-react-app
as well so that should make it easier to test. Will get back to you later this week (again, probably Thursday).
I've just published a new version 3.1.5
of the image preview plugin that tries to add the SVG a bit earlier and is a bit more persistent in trying to add it. Can you give it a try and let me know if it fixes the issue.
@rikschennink tested for a bit and the SVG mask displayed correctly every time I tried so seem to be resolved, thanks!
Fantastic! Thanks for confirming!
I have the exact same problem with a similar setup in Angular 7. Works on desktop and most other devices but iOS (latest version) with Safari is a source of trouble which gives the same green large box.
Updated all your packages to the latest version but problem remains. The solution mentioned here does solve the problem but is not quite as appealing.
@supports (-webkit-marquee-repetition: infinite) and (object-fit: fill) {
.filepond--image-preview-overlay svg rect { display: none; }
.filepond--image-preview-overlay svg { background: linear-gradient(currentColor 0%, transparent 66%); }
}
Any idea's?
@Zwimber Do you see the <svg>
element that is generated by the image preview plugin, it should be appended to the element, somewhere near the end of the DOM.
@Zwimber reproduced the issue, it's related to the <base>
tag.
See this issue: airbnb/lottie-web#360
Fixing it now.
Should be fixed in Image Preview plugin version 4.0.2
I think this update actually broke it for me again, I'm getting the solid color like @Zwimber but it was working fine in 4.0.1
Haha oh no 🤦🏼♂️
Any <base>
tag present in your code?
This is the injected SVG code:
<svg class="filepond--image-preview-sprite" style="position: absolute; width: 0px; height: 0px;"><radialGradient id="filepond--image-preview-radial-gradient" cx=".5" cy="1.25" r="1.15">
<stop offset="50%" stop-color="#000000"></stop>
<stop offset="56%" stop-color="#0a0a0a"></stop>
<stop offset="63%" stop-color="#262626"></stop>
<stop offset="69%" stop-color="#4f4f4f"></stop>
<stop offset="75%" stop-color="#808080"></stop>
<stop offset="81%" stop-color="#b1b1b1"></stop>
<stop offset="88%" stop-color="#dadada"></stop>
<stop offset="94%" stop-color="#f6f6f6"></stop>
<stop offset="100%" stop-color="#ffffff"></stop>
</radialGradient>
<mask id="filepond--image-preview-masking">
<rect x="0" y="0" width="500" height="200" fill="url(http://localhost:3000#filepond--image-preview-radial-gradient)"></rect>
</mask></svg>
There's no <base>
tag in my code.
If it is there it’s probably in the <head>
of the page.
Tried to reproduce with create-react-app but it seems to work correctly
@rikschennink how exactly should it look? The <svg>
should be wrapped in a <base>
tag?
@rovansteen It's unrelated to the <svg>
, it's literally an element called <base>
that sits in the <head>
of the website.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
Ah, I didn't even know that existed. So I'm not using that. I'm guessing it has something to do with using push state routing, but it's weird that it was working fine before.
I've updated the plugin to change the contents of the url()
value inside the SVG, maybe it conflicts with push state, will check later today.
Just published version 4.0.3
, it should fix the issue @rovansteen
@rikschennink thanks! Works perfectly again.