React particles not interacting on hover after adding an image in background? - reactjs

I have the normal react particle code which works fine but after adding an image to the background the particles are not interacting on hover anymore. Image is in y.js file which is loaded in x.js file where react particles code exists
const ParticleOptions={
particles: {
number: {
value: 170,
density:{
enable: true,
value_area:850
}
}
},
interactivity:{
detect_on:"canvas",
events:{
onhover:{
enable:true,
mode: "repulse"
}
},
modes:{
repulse:{
distance:70,
duration: 0.4
}
}
}
}
My separate image in a different JS file:
return(
<div className='abx'>
<img src='https://samples.clarifai.com/face-det.jpg' alt=''/>
</div>
);
I expected thr interaction of particles on mouse movements to remain after adding a small image to the center but it does not

Just change detect_on:"canvas",to window

Related

React-Viro AR ImageTracking sub elements are positioned inside camera when target is seen

I am currently using Viro-React (React-Viro) for a AR project in which, if a certain pictures gets seen by the camera a video is played infront of it. I had it working perfectly, but somehow and a few days later, without changing the code, the video and everything inside the ViroARImageMarker is always positioned inside the camera, when the target gets seen.
This behavior only seems to happen in my own projects and not in the samples provided by Viro Media.
I have tried to:
Reinstalling node modules
Compared the package.json's and reinstalled.
Changed the position of the elements inside the ViroARImageMarker
And reorganised the elements.
But nothing seems to work.
As I said the code itself shows and hides the video, but does not position the video (every inside the ViroARImageMarker correctly, but positions them in the position of the camera when the targets gets seen and then keeps them there.
Here is the code. (Snippet at the end)
I pass this function to the ViroARSceneNavigator in another script.
There are a few animations, which just scale up/down the video depending if the target is in view or not.
(I removed the whitespaces to fit more onto one screen)
Main Code
Viro Animations and Material
"use strict";
import React, { useState } from "react";
import { ViroARScene, ViroNode, ViroARImageMarker, ViroVideo, ViroARTrackingTargets, ViroAnimations, ViroMaterials } from "react-viro";
const MainScene = (props) => {
const videoPath = require("./res/Test_Video.mp4");
const [playVideoAnimation, setPlayVideoAnimation] = useState(false);
const [videoAnimationName, setVideoAnimationString] = useState("showVideo");
const [shouldPlayVideo, setShouldPlayVideo] = useState(false);
function onAnchorFound() {
setPlayVideoAnimation(true);
setVideoAnimationString("showVideo");
setShouldPlayVideo(true);
}
function onAnchorRemoved() {
setShouldPlayVideo(false);
setVideoAnimationString("closeVideo");
setPlayVideoAnimation(true);
}
function onVideoAnimationFinish() {
setPlayVideoAnimation(false);
}
function onVideoFinish() {
setShouldPlayVideo(false);
setVideoAnimationString("closeVideo");
setPlayVideoAnimation(true);
}
return (
<ViroARScene>
<ViroARImageMarker target={"targetOne"} onAnchorFound={onAnchorFound} onAnchorRemoved={onAnchorRemoved}>
<ViroNode rotation={[-90, 0, 0]}>
<ViroVideo
position={[0, 0, 0]}
scale={[0, 0, 0]}
dragType="FixedToWorld"
animation={{ name: videoAnimationName, run: playVideoAnimation, onFinish: onVideoAnimationFinish }}
source={videoPath}
materials={["chromaKeyFilteredVideo"]}
height={0.2 * (9 / 16)}
width={0.2}
paused={!shouldPlayVideo}
onFinish={onVideoFinish}
/>
</ViroNode>
</ViroARImageMarker>
</ViroARScene>
);
};
ViroAnimations.registerAnimations({
showVideo: {
properties: { scaleX: 0.9, scaleY: 0.9, scaleZ: 0.9 },
duration: 1,
easing: "bounce",
},
closeVideo: {
properties: { scaleX: 0, scaleY: 0, scaleZ: 0 },
duration: 1,
},
});
ViroMaterials.createMaterials({
chromaKeyFilteredVideo: {
chromaKeyFilteringColor: "#00FF00",
},
});
ViroARTrackingTargets.createTargets({
targetOne: {
source: require("./res/Test_Bild.png"),
orientation: "Up",
physicalWidth: 0.01, // real world width in meters
},
});
export default MainScene;
I was able to resolve the issue by copying (downgrading) my dependencies in my package.json from the React-Viro codesamples and decreasing the width/height (inside the element) and scale (in the animation) of the video.
Note that if the sub element of the ViroARImageMarker is too big (in scale and size), the issue comes back.

Duplicate image shown - useEffect issue?

I have some code to display my board as shown below:
<Grid item xs={6} justify="center">
<Paper id="board">
</Paper>
</Grid>
But sometimes when I save my code, it displays a duplicate board on the screen on localhost:3000, although not always. Example below:
I am suspecting it it might have something to do with my useEffect:
useEffect(() => {
// componentDidMount() {
const board = new Gameboard(document.getElementById('board'), {
// position: 'r4r1k/p1P1qppp/1p6/8/5B2/2Q1P3/P4PPP/R3KB1R b KQ - 0 21',
position: game.fen(),
sprite: {
url: './gameboard-sprite.svg', // pieces and markers are stored as svg in the sprite
grid: 40, // the sprite is tiled with one piece every 40px
cache: true,
},
orientation: COLOR.white,
moveInputMode: MOVE_INPUT_MODE.dragPiece,
responsive: true,
});
board.enableMoveInput(inputHandler);
}, []);
Any idea why it could be displaying twice, but only sometimes? It always removes the duplicate board when I click the browser refresh button if that helps. But it is often there when I first save my code.
Save your Gameboard instance in useRef, this way only one instance is created:
const board = useRef();
useEffect(() => {
if(!board.current) {
board.current = new Gameboard(document.getElementById('board'), {
// position: 'r4r1k/p1P1qppp/1p6/8/5B2/2Q1P3/P4PPP/R3KB1R b KQ - 0 21',
position: game.fen(),
sprite: {
url: './gameboard-sprite.svg', // pieces and markers are stored as svg in the sprite
grid: 40, // the sprite is tiled with one piece every 40px
cache: true,
},
orientation: COLOR.white,
moveInputMode: MOVE_INPUT_MODE.dragPiece,
responsive: true,
});
board.current.enableMoveInput(inputHandler);
}
}, []);
You need to return cleanup function from effect, so when fast refresh will rerun it, there will be no duplicates. It works properly sometimes because sometimes fast refresh sometimes don't try to preserve state and renders everything as new. This depends on changes you made, so when you change one file it will render clean, but on another files it will try to preserve state and only rerun effects (this is where second board added).
Also, it is better not to interact with DOM directly and use ref instead. This is better way to work with DOM in react, since it's react main purpose to update DOM.

How can I display GIF images efficiently in my Gatsby blog website?

A few days ago, I bought a Gatsby blog theme and tried to modify it. The blog site uses Images(PNG, JPEG), not animated GIFs. So I tried to use GIF images for all blog posts but it affected site performance.
Also, I notice that Gatsby Image doesn't provide a GIF format. How can I use GIF on my blog with high performance?
You can convert GIFs into MP4 videos with H.264 encoding using ffmpeg. Then use <video src="..." /> in place of your img tag. To make this really easy, I have a React component that I use for this that includes automatic playback when the video is visible:
import React, { useEffect } from "react"
import PropTypes from "prop-types"
import { useInView } from "react-intersection-observer"
const GifVideo = ({ threshold = 0.15, ...playerProps }) => {
const [ref, inView] = useInView({ threshold })
useEffect(() => {
if (inView) {
ref.current?.play()
} else {
ref.current?.pause()
}
}, [ref, inView])
return <video ref={ref} autoPlay playsInline muted loop {...playerProps} />
}
export default GifVideo
GifVideo.propTypes = {
src: PropTypes.string,
threshold: PropTypes.number,
className: PropTypes.string,
}
Then to you use it, it's this easy:
<GifVideo src="/your/video.mp4" width={400} className="some-class" />
For what it's worth, I don't recommend using the sharp-backed GraphQL image transformers in Gatsby (gatsby-transformer-sharp). It's exceedingly slow, couples the presentation to the query, and doesn't provide any way to handle art direction.
I use gatsby-remark-interactive-gifs plugin to show gifs on my gatsby blog.
Install gatsby-remark-interactive-gifs
npm install --save gatsby-remark-interactive-gifs
yarn add gatsby-remark-interactive-gifs
Add this config to gatsby-config.js:
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
{
resolve: `gatsby-remark-interactive-gifs`,
options: {
root: `${__dirname}`,
src: `${__dirname}/content/gif`,
dest: `${__dirname}/public/static/gifs`,
play: `${__dirname}/src/img/play.gif`,
placeholder: `${__dirname}/src/img/play.gif`,
loading: `${__dirname}/src/img/play.gif`,
relativePath: `/static/gifs`,
},
},
],
},
},
From plugin document:
root - The root of your project.
src - Where all the gifs you want processed are stored. Absolute path.
dest - A path in public where your gifs are stored. Absolute path.
play - An image to indicate that the gif can be interacted with. Absolute path.
placeholder - An image to show when the gif is missing in action. Absolute path.
loading - An image which shows when the gif is downloading. Absolute path.
relativePath - The relative path served from public/.
! Make sure you are adding this above the prismjs config.
Sample code in MD file to show gifs on your gatsby blog:
<img src="/static/gifs/fileName.gif">

React blueimp-load-image rescaling of uploaded image

I'm using the package blueimp-load-image package to load an image in my react application. The image should be resized and put into a canvas afterwards.
This is my code that handles the upload. It can only be an image.
const handleImageUpload = e => {
const [file] = e.target.files;
if (file) {
loadImage(
file,
img => {
setImage(img);
changeOffset(img);
},
{
orientation: true,
maxWidth: innerWidth,
maxHeight: innerHeight,
downsamplingRatio: 0.25,
pixelRatio: window.devicePixelRatio,
imageSmoothingEnabled: true,
imageSmoothingQuality: 'high',
canvas: false,
contain: true,
}
);
}
};
The img gets put into a state variable that gets shown in my canvas (I'm using a KonvaImage from react-konva for that). My problem is that if I don't use pixelRatio: window.devicePixelRatio, the image gets shown correctly, but the quality is poor. If I, however, use pixelRatio: window.devicePixelRatio, the picture is zoomed in.
If I log out the img inside the loadImage this is the output. The first one without pixelRatio, the second one with pixelRatio.
This is what the image on the screen looks like (again first one without pixelRation, the second one with pixelRatio):
I hope somebody can help me with my problem. I would of course also be open for a different way of resizing the images if it works better.
Thanks in advance!

gl-react-expo shader with external image texture input

I'm trying to use gl-react-expo shaders to apply some effects on some images in an Expo project. The images are from an external url (like http://i.imgur.com/rkiglmm.jpg).
I can make simple shaders that don't use a texture input, and it works perfectly. But I am not finding the correct way to pass the image to the shader. I'm trying to implement the DiamondCrop example from this site (http://greweb.me/2016/06/glreactconf/) and all the other simple examples that I found that passes an image to the shader. But none of them work.
This is my shader definition:
import React from "react";
import { Shaders, Node, GLSL } from "gl-react";
const frags = {
diamond: GLSL`
precision highp float;
varying vec2 uv;
uniform sampler2D t;
void main () {
gl_FragColor = mix(
texture2D(t, uv),
vec4(0.0),
step(0.5, abs(uv.x - 0.5) + abs(uv.y - 0.5))
);
}`
}
const shaders = Shaders.create({
DiamondCrop: {
frag: frags.image
}
});
const DiamondCrop = ({ children: t }) => (
<Node
shader={shaders.DiamondCrop}
// uniformsOptions={{
// t: { interpolation: "nearest" },
// }}
uniforms={ { t } }
>
</Node>
);
export { DiamondCrop }
I tried passing the image in the following ways:
// 1
<Surface style={{width: 200, height: 200}}>
<DiamondCrop>
{{uri:'http://i.imgur.com/rkiglmm.jpg'}}
</DiamondCrop>
</Surface>
// 2
<Surface style={{width: 200, height: 200}}>
<DiamondCrop>
{{image:{uri:'http://i.imgur.com/rkiglmm.jpg'}}}
</DiamondCrop>
</Surface>
// 3
<Surface style={{width: 200, height: 200}}>
<DiamondCrop>
http://i.imgur.com/rkiglmm.jpg
</DiamondCrop>
</Surface>
// 4
<Surface style={{width: 200, height: 200}}>
<DiamondCrop>
{'http://i.imgur.com/rkiglmm.jpg'}
</DiamondCrop>
</Surface>
And the errors I get are the following:
// 1 (on 'expo red screen of death')
undefined is not an object (evaluating '_expo2.default.FileSystem')
// 2 (Expo warning; nothing appears on the Surface region)
Node#1(DiamondCrop#2), uniform t: no loader found for value, Object {
"image": Object {
"uri": "http://i.imgur.com/rkiglmm.jpg",
},
}, Object {
"image": Object {
"uri": "http://i.imgur.com/rkiglmm.jpg",
},
}
// 3 (Expo warning; nothing appears on the Surface region)
Node#1(DiamondCrop#2), uniform t: no loader found for value, http://i.imgur.com/rkiglmm.jpg, http://i.imgur.com/rkiglmm.jpg
// 4 (Expo warning; nothing appears on the Surface region)
Node#1(DiamondCrop#2), uniform t: no loader found for value, http://i.imgur.com/rkiglmm.jpg, http://i.imgur.com/rkiglmm.jpg
Could anyone point me in the right directions to accomplish this task??
This question is quite old, but I wanted to write an answer for those who may be into the gl related stuff with react-native and Expo.
TL;DR The reason this is happening is because the library gl-react-expo is outdated, it is doing import Expo from "Expo" which is deprecated(breaks the entire thing actually) in V33 of expo SDK.
I made a github repo that hosts the corrected libraries, you may want to use that. Here is the link gl-expo-libraries Also, If you want to stick to original libraries then go to the node_modules folder, go to the gl-react-expo fodler and look for _expo2 variable in the files and change _expo2.default to _expo. It will do the trick.
Cheers :)

Resources