Last active: 2 years ago
Swap variables in array
const arr = [
{
id: 0,
text: 'xfy',
},
{
id: 1,
text: 'dfy',
},
{
id: 2,
text: 'hello',
},
{
id: 3,
text: 'world',
},
];
[arr[0], arr[1]] = [arr[1], arr[0]]
Last active: 2 years ago
ForEach add item into a Set without anonymous arrow function.
array.forEach(item => mySet.add(item))
// alternative, without anonymous arrow function
array.forEach(mySet.add, mySet)
Last active: 2 years ago
My three.js
function App() {
const { three, threeWrapper, RUAThree } = useThree();
useEffect(() => {
const geometry = new RUAThree.THREE.BoxGeometry(1, 1, 1);
const matrial = new RUAThree.THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new RUAThree.THREE.Mesh(geometry, matrial);
const light = new RUAThree.THREE.HemisphereLight(0xb1e1ff, 0xb97a20, 0.1);
const rotateCube = (time: DOMHighResTimeStamp) => {
cube.rotation.x = time;
cube.rotation.y = time;
};
three.camera.position.set(0, 0, 5);
three.controls.target.set(0, 0, 0);
three.scene.add(cube);
three.scene.add(light);
Last active: 2 years ago
My three.js
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import ResourceTracker, { Disposable } from 'lib/three/ResourceTracker';
import { Vector3 } from 'three';
import Stats from 'stats.js';
class SceneWithTracker extends THREE.Scene {
constructor(private tracker: ResourceTracker<Disposable>) {
super();
}
add(...object: THREE.Object3D<THREE.Event>[]): this {
super.add(...object);
this.tracker.track(...object);
return this;
}
}
export type ThreeProps = {
rotateInversion?: boolean;
Last active: 2 years ago
My three.js
import { Object3D } from 'three';
export abstract class Disposable {
dispose() {}
}
class ResourceTracker<T extends Disposable> {
resources = new Set<T | Object3D>();
private debugMode = false;
track(...object: (T | Object3D)[]) {
object.forEach((item) => {
if ('dispose' in item || item instanceof Object3D) {
this.resources.add(item);
}
});
if (this.debugMode)
console.log('>>> Resource trakcer: add resource', object);
return object;
Last active: 2 years ago
My three.js
import RUAThree, { defaultProps, ThreeProps } from 'lib/three';
import { useEffect, useRef } from 'react';
type Props = {
init: (three: RUAThree) => void;
} & ThreeProps;
const useThree = (props: Props) => {
const ref = useRef<HTMLCanvasElement>(null);
const three = useRef<RUAThree>();
useEffect(() => {
// When React created the canvas element.
// pass to renderer
const threeProps = {
...defaultProps,
canvas: ref.current,
};
three.current = new RUAThree(
props ? { ...threeProps, ...props } : threeProps
Last active: 2 years ago
Use useRef to create THREE
const appRef = useRef<HTMLDivElement>(null);
const scene = useRef(new THREE.Scene());
const camera = useRef(
new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
)
);
camera.current.position.z = 5;
const renderer = useRef<THREE.WebGLRenderer>(
new THREE.WebGLRenderer({
antialias: true,
})
);
renderer.current.setPixelRatio(window.devicePixelRatio);
renderer.current.setSize(window.innerWidth, window.innerHeight);
Last active: 3 years ago
Styled component group hover
const VideoWrapper = styled.div`
position: fixed;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 10px 15px -3px rgb(102 102 102 / 78%),
0 4px 6px -4px rgb(107 107 107 / 10%);
top: 30px;
left: 30px;
background-color: #fff;
width: 640px;
height: 480px;
`;
type VideoProps = {
readonly isPublishing: boolean;
};
const PlayVideo = styled.video<VideoProps>`
width: 640px;
height: 480px;
border-radius: 8px;
overflow: hidden;
Last active: 3 years ago
Generics limit function parameters
type Privilege = "user" | "admin";
type UserPrivilege = {
privilege: "user";
login: () => void;
logout: () => void;
};
type AdminPrivilege = {
privilege: "admin";
add: () => void;
delete: () => void;
};
type AdminPanelUsers = {
user: UserPrivilege;
admin: AdminPrivilege;
};
function adminPanel<T extends Privilege>(
privilege: T,
user: AdminPanelUsers[T]
) {
Last active: 3 years ago
Next.js loading when router changed
const handleStart = useCallback(
(url: string) => {
url !== router.pathname ? setLoading(true) : setLoading(false);
},
[router.pathname]
);
const handleComplete = useCallback(() => {
setLoading(false);
}, []);
useEffect(() => {
router.events.on('routeChangeStart', handleStart);
router.events.on('routeChangeComplete', handleComplete);
router.events.on('routeChangeError', handleComplete);
// If the component is unmounted, unsubscribe
// from the event with the `off` method:
return () => {
router.events.off('routeChangeStart', handleStart);
Last active: 3 years ago
React portal
{ReactDOM.createPortal(
<Suspense fallback>
<CommentPanel
style={{
display: showPanel ? 'block' : 'none',
minHeight: '52vh',
}}
closePanel={closeCommentPanel}
comments={data}
refresh={refresh}
commentLoading={loading}
/>
</Suspense>,
document.body
)}
Last active: 3 years ago
Text gradient
.gradient {
background: rgb(238, 174, 200);
background: linear-gradient(
45deg,
rgba(238, 174, 200, 1) 0%,
rgba(148, 187, 233, 1) 100%
);
background-size: 400%;
animation: gradient 5s ease infinite;
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
@keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
Last active: 3 years ago
Remove array duplicates
const arr = [
{
message: 'Hello',
messageID: 1,
},
{
message: 'Hello',
messageID: 1,
},
{
message: 'World',
messageID: 2,
}
]
const removeDuplicates = (arr) => {
const _obj = {}
arr.forEach(item => {
_obj[item.messageID] = item
Last active: 3 years ago
Remove array duplicates
type Msg = {
message: string,
messageID: number
}
const arr:Msg[] = [
{
message: 'Hello',
messageID: 1,
},
{
message: 'Hello',
messageID: 1,
},
{
message: 'World',
messageID: 2,
}
]