React-konva and konva doesn't draw blurred image - reactjs

Can't make image to be drawn on layer when I apply blur filter.
In the parent component I add two instances of my component with konva image. One as is and one with image blur filter. First one draw correctly, the second one show no image. Interestingly if I go to another route and return to this it drawn correctly if I add the same image.
Image is added in componentDidMount:
componentDidMount() {
var img = new Konva.Image({
image: this.state.imageStateScaled,
width: 300,
height: 250
});
let st: Konva.Stage = this.konvaLayer.current.getStage();
if (this.state.blured) {
img.filters([Konva.Filters.Blur]);
img.blurRadius(30);
img.cache({ width: this.konvaLayer.current.getWidth(), height: this.konvaLayer.current.getHeight() });
}
this.konvaLayer.current.add(img);
st.draw();
}
My render function:
public render() {
let stageWithImage =
<Stage ref={this.konvaStage} width={300} height={250}>
<Layer ref={this.konvaLayer}></Layer>
</Stage>
return ({ stageWithImage })
}
It looks like it caused by konva.image.cache() function. If I put it outside if block and it is applied to both images, non is drawn first time.
Any ideas?
UPDATE
I've created a small demo with the issue
source https://github.com/CAIIIA/konvaDrawImageIssue
Live demo http://domit.co.uk/demo/index.html
I've also noticed that all browser works differently with this demo.
Chrome as I described above. One image shown, the other only after refresh.
Firefox doesn't draw at first hit only after reload
Also EDGE browser seems not to have this issue. Works like charm
!!!Doesn't work in Internet explorer for some reason at all.

You need to apply filters and cache AFTER image is loaded.
var img = new Konva.Image({
image: this.props.image,
width: 300,
height: 250
});
this.konvaLayer.current.add(img);
this.props.image.onload = () => {
if (this.props.blurred) {
img.filters([Konva.Filters.Blur]);
img.blurRadius(30);
img.cache({ width: this.konvaLayer.current.getWidth(), height: this.konvaLayer.current.getHeight() });
this.konvaLayer.current.draw();
}
}
Offtopic notes:
Try to define all Konva nodes in render function. Do not create them manually with new Konva.Something()
Do not create new Image() in render function. You may have unexpected behavior when you update your components. Take a looks here for demos: https://konvajs.github.io/docs/react/Images.html

Related

Printing multiple pages not working in React-to-Print

we are loading 100 records in the grid initially, after that when we scroll down , loading another set of data.
But when we try to print the page its loading just 100 records in the print preview screen, we are using react-to-print, functional component.
const handlePrint = useReactToPrint({
content: () => componentRef.current,
});
we want load all the data available in the List, please help.
I found myself in a similar problem and this answer from github helped me.
You have to surround your render with a div of styling overflow: scroll and also remove overflow styling, maximum height and any other view limiting styling from the surrounded element's "stylings" like the example below.
Disclaimer: I used MUI in some instances.
render() {
<div sx={{ overflow: "scroll" }}>
{
sampleIterable.map((x,n) => {
...
})
}
</div>
}

Problem with initializing existing canvas with PixiJs

As titled,
Is it possible to initialize canvas with image on it using Pixi so that i can add filter on top of it? Im using gsap 3.2.6 and Pixi 5.2.4.
I have the canvas created like this (using React btw)
useEffect(() => {
let ctx = imgDisplayer.current.getContext('2d');
let img = new Image();
img.onload = function(){
imgDisplayer.current.width = img.width; // To set canvas width to image width
imgDisplayer.current.height = img.height; // To set canvas height to image height
ctx.drawImage(img, 0, 0);
setCanvas(imgDisplayer.current);
}
img.src = source;
}, []);
That setCanvas is to store the loaded canvas into state, so that i can use it to initialize Pixi.
if (canvas){
const app = new Pixi.Application({
width: 1300,
height: 866,
backgroundColor: 0x000000,
autoResize: true,
view: canvas
});
}
Problem is, this throws me the following error
Error: This browser does not support WebGL. Try using the canvas renderer
If only i could fetch an https image (direct image link) then this wouldn't be a problem, and i can load the image using Pixi.Sprite insteaad.. but because of cross origin, i cannot think of way on how to render the image. I can render it just fine on canvas, but not with Pixi.
The error you pasted is saying that your browser does not support WebGL.
Please check WebGL support on those pages: https://get.webgl.org/ , https://webglreport.com/
Can you try to initialize Pixi on some simpler page just to check if it works for you? I mean, just create simple html page (without React etc), try to setup Pixi there and try to draw anything (some red circle etc).

How to navigate to a particular div on the same page in ReactJS?

I have to navigate to a particular div on the same page in React JS application. For example how it is being done in the following website. When one clicks on < NavLink > the UI scrolls and focuses on the particular div and similarly for other Links on this website.
https://reacttraining.com/react-router/web/api/NavLink/strict-bool
Get the offset of the target element and use window.scrollTo to position it either on top of the page or where ever you want. This would work in chrome/latest browsers. You might want to check for other browser compatibility.
let offsetTop = document.getElementById("yourelement").offsetTop;
window.scrollTo({
top: offsetTop-100,
behavior: "smooth"
});
Program is in codepen https://codepen.io/Divine1/pen/zbQVwR
Update
i have added this logic into a online reactjs project editor and it works.
You can see how this code works https://repl.it/#Divine1/QuietHeartyApplicationstack
Check App.js App.css and the live result.
I think that maybe is a better aproach to use useRef hook. on click is almost the same:
const ref = useRef();
// the function when you want to scroll:
() => window.scrollTo({
top: ref.current.offsetTop -100,
behavior: "smooth"
})
// Where you want to go
<div ref={ref} />

How can I make my react-native-camera capture fast?

takePicture = async function() {
if (this.camera) {
const options = { quality: 0.5, base64: true, };
const data = await this.camera.takePictureAsync(options);
this.setState({path: data.uri})
}
}
As soon as I call my takePicture fuction to capture image, the camera still keeps moving and doesn't pause. I want the camera to pause and then show me the image.
Is there something here to with handling Promise? If yes, I don't know where to do it and how.
I've also tried using pauseAfterCapture:true but it still takes 1 or 2 second to capture the image.
I know this is an old issue but no solution could help me yet. Please help.
I've also found the available camera components very slow, that is why I created react-native-fast-camera and I just open sourced it for the public use. It is very customizable and completely controllable by react native components.
Note: Currently the Android version is still work in progress.
Here is an example:
import FastCamera, { Methods } from 'react-native-fast-camera';
<FastCamera style={{ height: cameraHeight, width: cameraWidth }}
onSaveSuccess={imageUrl => {
console.log("onSaveSuccess: ", imageUrl);
}}
onGalleryImage={imageUrl => {
console.log("onGalleryImage: ", imageUrl);
}}
onFlashToggle={isflashOn => {
console.log('flash info: ', isflashOn);
}}
>
{/* here render your buttons to control the camera component */}
<Button
title="capture picture"
onPress={()=> Methods.takePicture();}
/>
</FastCamera>
And here is a screenshot:

Is it possible to combine 'px' and 'vh' into the height of 1 component in react js

I have a few components and some of them are sized with px. The others I want to be variable size. However, the ones that are variable size are not a constant percentage of the page because of the components with a fixed px height. So I want a component to be about 80% of the screen height('80vh') minus the height of the other component. I was hoping to use something like
style={{height:'80vh-40px'}}
but that does not work.
I found this page which gets close but that my program does not recognize that calc function. Do I need to require it from some library maybe?
Any ideas on how to make this work?
Thanks!
I use syntax like this in my React.js components:
<div style={{height: 'calc(100vh - 400px)'}}></div>
it works for me.
Inside CSS code with LESS preprocessor I use the same syntax, but not equal:
.right_col {
height: calc(~"100vh - 400px");
}
In my experiments, I found that symbol "~" doesn't work in React.js components.
A way to solve it is by using style={} in your component.
const styles = {targetDiv: { height: 'calc(100vh - Xpx)'}}
then...
<div style={styles.targetDiv}>
...
</div>
Note - you can get the window.innerHeight (see http://ryanve.com/lab/dimensions/ for height and width options in javascript) and just calculate this yourself in react and set the width or height in pixels.
If you do this with height, you'd need to recalculate if it changes
state = {
windowHeight: window.innerHeight
}
componentWillMount () {
window.addEventListener('resize', this.handleResize)
}
componentWillUnmount () {
window.removeEventListener('resize', this.handleResize)
}
handleResize = () => {
this.setState({ windowHeight: window.innerHeight })
}
in your div
<div style={{height: this.state.windowHeight}} > ... </div>
You wouldn't want to do this everywhere, but it's very handy for some situations. For example - setting 100% height on Android mobile web, where 100vh does not work and device buttons cover up part of the screen.

Resources