From 356dd92e56a0f1a2bb33b177de55a5fa885c3a30 Mon Sep 17 00:00:00 2001 From: Guillaume CATEL Date: Sun, 5 Nov 2023 11:52:09 +0100 Subject: [PATCH] feat: create tapioca --- package.json | 2 +- src/tapioca/index.tsx | 59 +++++++++++++++++++++++++++++++++ src/tapioca/noise-texture.svg | 7 ++++ src/tapioca/tapioca.stories.tsx | 20 +++++++++++ src/tapioca/tapioca.tsx | 51 ++++++++++++++++++++++++++++ 5 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 src/tapioca/index.tsx create mode 100644 src/tapioca/noise-texture.svg create mode 100644 src/tapioca/tapioca.stories.tsx create mode 100644 src/tapioca/tapioca.tsx diff --git a/package.json b/package.json index 05a3322..fb3eb6d 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "scripts": { "prepare": "husky install", "preinstall": "npx -y only-allow pnpm", - "dev": "start-storybook -p 6006", + "dev": "storybook dev -p 6006", "deploy:storybook": "gh-pages -d storybook-static", "lint": "pnpm eslint && pnpm stylelint", "lint:fix": "pnpm eslint --fix && pnpm stylelint --fix", diff --git a/src/tapioca/index.tsx b/src/tapioca/index.tsx new file mode 100644 index 0000000..e0fdf18 --- /dev/null +++ b/src/tapioca/index.tsx @@ -0,0 +1,59 @@ +import React, { useRef } from 'react' +import { Canvas } from '@react-three/fiber' +import { OrbitControls } from '@react-three/drei' + +import { Scene } from './tapioca' + +import NoiseTexture from './noise-texture.svg?url' + +interface Props { + scale: number +} + +const Tapioca = ({ scale = 5 }: Props) => { + const canvas = useRef(null) + + const handleCanvasClick = () => { + if (canvas.current) { + canvas.current.toBlob( + (blob) => { + const link = document.createElement('a') + link.href = window.URL.createObjectURL(blob as Blob) + link.download = `${Date.now().toString()}.webp` + link.click() + }, + 'image/webp', + 1 + ) + } + return false + } + + return ( +
+ + + + +
+
+ ) +} + +export { Tapioca } diff --git a/src/tapioca/noise-texture.svg b/src/tapioca/noise-texture.svg new file mode 100644 index 0000000..5aba404 --- /dev/null +++ b/src/tapioca/noise-texture.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/tapioca/tapioca.stories.tsx b/src/tapioca/tapioca.stories.tsx new file mode 100644 index 0000000..43c3c26 --- /dev/null +++ b/src/tapioca/tapioca.stories.tsx @@ -0,0 +1,20 @@ +import React from 'react' +import type { Meta, StoryObj } from '@storybook/react' + +import { Tapioca } from '.' + +const meta: Meta = { + title: '3D/Tapioca', + component: Tapioca, + argTypes: { + scale: { + control: { type: 'number' } + } + } +} + +export default meta + +type Story = StoryObj + +export const Primary: Story = {} diff --git a/src/tapioca/tapioca.tsx b/src/tapioca/tapioca.tsx new file mode 100644 index 0000000..3d4a51b --- /dev/null +++ b/src/tapioca/tapioca.tsx @@ -0,0 +1,51 @@ +/* eslint-disable react/no-unknown-property */ +import React, { useRef } from 'react' +import { useFrame } from '@react-three/fiber' +import { BoxGeometry, Mesh, ShaderMaterial } from 'three' + +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore +import { sculptToThreeJSMesh } from 'shader-park-core' + +const mesh: Mesh = sculptToThreeJSMesh(` + setMaxIterations(3); + + displace(mouse.x*-.2, mouse.y*-.2, 0) + + let s = getSpace(); + let r = getRayDirection(); + let n1 = noise(r*1 + vec3(0, 0.3, time*.1)); + let n = noise(s + vec3(0, 0, time*.1) + n1); + + metal(n*.5 + .5); + shine(n*.5 + .75); + + color(normal*.1 + vec3(5, 0, 0)); + + boxFrame(vec3(4), .1); + mixGeo(0) + sphere(.25 + n*.5); +`) + +interface Props { + scale: number +} + +const Scene = ({ scale }: Props) => { + const el = useRef>() + + useFrame(() => { + if (el.current) { + el.current.material.uniforms.time.value += 0.075 + } + }) + + return ( + <> + + + + ) +} + +export { Scene }