Initial project import
This commit is contained in:
150
node_modules/@react-three/drei/core/Trail.js
generated
vendored
Normal file
150
node_modules/@react-three/drei/core/Trail.js
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
import { useFrame, useThree, createPortal } from '@react-three/fiber';
|
||||
import * as React from 'react';
|
||||
import { Vector3, Object3D, Vector2 } from 'three';
|
||||
import { MeshLineGeometry, MeshLineMaterial } from 'meshline';
|
||||
|
||||
const defaults = {
|
||||
width: 0.2,
|
||||
length: 1,
|
||||
decay: 1,
|
||||
local: false,
|
||||
stride: 0,
|
||||
interval: 1
|
||||
};
|
||||
const shiftLeft = (collection, steps = 1) => {
|
||||
collection.set(collection.subarray(steps));
|
||||
collection.fill(-Infinity, -steps);
|
||||
return collection;
|
||||
};
|
||||
function useTrail(target, settings) {
|
||||
const {
|
||||
length,
|
||||
local,
|
||||
decay,
|
||||
interval,
|
||||
stride
|
||||
} = {
|
||||
...defaults,
|
||||
...settings
|
||||
};
|
||||
const points = React.useRef(null);
|
||||
const [worldPosition] = React.useState(() => new Vector3());
|
||||
React.useLayoutEffect(() => {
|
||||
if (target) {
|
||||
points.current = Float32Array.from({
|
||||
length: length * 10 * 3
|
||||
}, (_, i) => target.position.getComponent(i % 3));
|
||||
}
|
||||
}, [length, target]);
|
||||
const prevPosition = React.useRef(new Vector3());
|
||||
const frameCount = React.useRef(0);
|
||||
useFrame(() => {
|
||||
if (!target) return;
|
||||
if (!points.current) return;
|
||||
if (frameCount.current === 0) {
|
||||
let newPosition;
|
||||
if (local) {
|
||||
newPosition = target.position;
|
||||
} else {
|
||||
target.getWorldPosition(worldPosition);
|
||||
newPosition = worldPosition;
|
||||
}
|
||||
const steps = 1 * decay;
|
||||
for (let i = 0; i < steps; i++) {
|
||||
if (newPosition.distanceTo(prevPosition.current) < stride) continue;
|
||||
shiftLeft(points.current, 3);
|
||||
points.current.set(newPosition.toArray(), points.current.length - 3);
|
||||
}
|
||||
prevPosition.current.copy(newPosition);
|
||||
}
|
||||
frameCount.current++;
|
||||
frameCount.current = frameCount.current % interval;
|
||||
});
|
||||
return points;
|
||||
}
|
||||
const Trail = /* @__PURE__ */React.forwardRef((props, forwardRef) => {
|
||||
const {
|
||||
children
|
||||
} = props;
|
||||
const {
|
||||
width,
|
||||
length,
|
||||
decay,
|
||||
local,
|
||||
stride,
|
||||
interval
|
||||
} = {
|
||||
...defaults,
|
||||
...props
|
||||
};
|
||||
const {
|
||||
color = 'hotpink',
|
||||
attenuation,
|
||||
target
|
||||
} = props;
|
||||
const size = useThree(s => s.size);
|
||||
const scene = useThree(s => s.scene);
|
||||
const ref = React.useRef(null);
|
||||
const [anchor, setAnchor] = React.useState(null);
|
||||
const points = useTrail(anchor, {
|
||||
length,
|
||||
decay,
|
||||
local,
|
||||
stride,
|
||||
interval
|
||||
});
|
||||
React.useEffect(() => {
|
||||
const t = (target == null ? void 0 : target.current) || ref.current.children.find(o => {
|
||||
return o instanceof Object3D;
|
||||
});
|
||||
if (t) {
|
||||
setAnchor(t);
|
||||
}
|
||||
}, [points, target]);
|
||||
const geo = React.useMemo(() => new MeshLineGeometry(), []);
|
||||
const mat = React.useMemo(() => {
|
||||
var _matOverride, _matOverride2;
|
||||
const m = new MeshLineMaterial({
|
||||
lineWidth: 0.1 * width,
|
||||
color: color,
|
||||
sizeAttenuation: 1,
|
||||
resolution: new Vector2(size.width, size.height)
|
||||
});
|
||||
|
||||
// Get and apply first <meshLineMaterial /> from children
|
||||
let matOverride;
|
||||
if (children) {
|
||||
if (Array.isArray(children)) {
|
||||
matOverride = children.find(child => {
|
||||
const c = child;
|
||||
return typeof c.type === 'string' && c.type === 'meshLineMaterial';
|
||||
});
|
||||
} else {
|
||||
const c = children;
|
||||
if (typeof c.type === 'string' && c.type === 'meshLineMaterial') {
|
||||
matOverride = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeof ((_matOverride = matOverride) == null ? void 0 : _matOverride.props) === 'object' && ((_matOverride2 = matOverride) == null ? void 0 : _matOverride2.props) !== null) {
|
||||
m.setValues(matOverride.props);
|
||||
}
|
||||
return m;
|
||||
}, [width, color, size, children]);
|
||||
React.useEffect(() => {
|
||||
mat.uniforms.resolution.value.set(size.width, size.height);
|
||||
}, [size]);
|
||||
useFrame(() => {
|
||||
if (!points.current) return;
|
||||
geo.setPoints(points.current, attenuation);
|
||||
});
|
||||
return /*#__PURE__*/React.createElement("group", null, createPortal(/*#__PURE__*/React.createElement("mesh", {
|
||||
ref: forwardRef,
|
||||
geometry: geo,
|
||||
material: mat
|
||||
}), scene), /*#__PURE__*/React.createElement("group", {
|
||||
ref: ref
|
||||
}, children));
|
||||
});
|
||||
|
||||
export { Trail, useTrail };
|
||||
Reference in New Issue
Block a user