Update image component
5
.idea/.gitignore
generated
vendored
@ -1,5 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
12
.idea/DefectingCat.github.io.iml
generated
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
15
.idea/git_toolbox_prj.xml
generated
@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GitToolBoxProjectSettings">
|
||||
<option name="commitMessageIssueKeyValidationOverride">
|
||||
<BoolValueOverride>
|
||||
<option name="enabled" value="true" />
|
||||
</BoolValueOverride>
|
||||
</option>
|
||||
<option name="commitMessageValidationEnabledOverride">
|
||||
<BoolValueOverride>
|
||||
<option name="enabled" value="true" />
|
||||
</BoolValueOverride>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
6
.idea/inspectionProfiles/Project_Default.xml
generated
@ -1,6 +0,0 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
8
.idea/modules.xml
generated
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/DefectingCat.github.io.iml" filepath="$PROJECT_DIR$/.idea/DefectingCat.github.io.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
7
.idea/prettier.xml
generated
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PrettierConfiguration">
|
||||
<option name="myRunOnSave" value="true" />
|
||||
<option name="myRunOnReformat" value="true" />
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
generated
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -1,5 +0,0 @@
|
||||
const main = `export default function App() {
|
||||
return <h1>Hello world</h1>
|
||||
}`;
|
||||
|
||||
export default main;
|
@ -1,17 +1,12 @@
|
||||
import NextImage, { ImageProps } from 'next/image';
|
||||
import NextImage, { ImageProps } from 'next/future/image';
|
||||
|
||||
interface Props extends ImageProps {}
|
||||
|
||||
const Image = ({ alt, ...rest }: Props) => {
|
||||
const supportImg = ['jpeg', 'png', 'webp', 'avif'];
|
||||
const placeholder = supportImg.includes((rest.src as { src: string }).src)
|
||||
? 'blur'
|
||||
: 'empty';
|
||||
|
||||
return (
|
||||
<>
|
||||
<span className="block text-center">
|
||||
<NextImage alt={alt} placeholder={placeholder} {...rest} />
|
||||
<NextImage alt={alt} {...rest} />
|
||||
{alt && <span className="block text-center text-gray-400">{alt}</span>}
|
||||
</span>
|
||||
</>
|
||||
|
@ -1,9 +1,11 @@
|
||||
import RUASandpack from 'components/RUA/RUASandpack';
|
||||
import Anchor from 'components/mdx/Anchor';
|
||||
import Image from 'components/mdx/Image';
|
||||
|
||||
const components = {
|
||||
RUASandpack,
|
||||
a: Anchor,
|
||||
Image,
|
||||
};
|
||||
|
||||
export default components;
|
||||
|
@ -1,8 +1,23 @@
|
||||
import main from 'assets/sandpack/hello-world/main';
|
||||
import { hello } from 'data/sandpack/hello-world';
|
||||
import {
|
||||
main,
|
||||
main2,
|
||||
styles,
|
||||
} from 'data/sandpack/how-to-load-a-background-with-threejs';
|
||||
|
||||
import skybox_example from 'public/images/p/how-to-load-a-background-with-threejs/Skybox_example.png';
|
||||
|
||||
const data = {
|
||||
sandpack: {
|
||||
'hello-world': main,
|
||||
'hello-world': hello,
|
||||
'load-background-main': main,
|
||||
'load-background-main2': main2,
|
||||
'load-background-styles': styles,
|
||||
},
|
||||
images: {
|
||||
'load-background': {
|
||||
skybox_example,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -4,21 +4,6 @@ date: '2022-04-13'
|
||||
tags: ['three.js', 'JavaScript']
|
||||
---
|
||||
|
||||
import Layout from 'layouts/MDXLayout';
|
||||
import dynamic from 'next/dynamic';
|
||||
import Image from 'components/mdx/Image';
|
||||
import image1 from 'assets/images/p/how-to-load-a-background-with-threejs/Skybox_example.png';
|
||||
|
||||
export const RUASandpack = dynamic(() => import('components/RUA/RUASandpack'));
|
||||
|
||||
export const meta = {
|
||||
title: 'How to load a background with three.js',
|
||||
date: '2022-04-13',
|
||||
tags: ['three.js', 'JavaScript'],
|
||||
};
|
||||
|
||||
export default ({ children }) => <Layout {...meta}>{children}</Layout>;
|
||||
|
||||
## Three.js setup
|
||||
|
||||
First, we need a little of setup. Let's create a scene and a camera.
|
||||
@ -60,57 +45,11 @@ renderer.render(scene, camera);
|
||||
|
||||
Now, we can get a black canvas in our document.
|
||||
|
||||
export const main = `import { useEffect, useRef } from 'react';
|
||||
import * as THREE from 'three';
|
||||
|
||||
export default function App() {
|
||||
const ref = useRef(null);
|
||||
const scene = new THREE.Scene();
|
||||
const camera = new THREE.PerspectiveCamera(
|
||||
75,
|
||||
window.innerWidth / window.innerHeight,
|
||||
0.1,
|
||||
1000
|
||||
);
|
||||
useEffect(() => {
|
||||
const renderer = new THREE.WebGLRenderer({
|
||||
canvas: ref.current,
|
||||
});
|
||||
renderer.setPixelRatio(window.devicePixelRatio);
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
const render = (time) => {
|
||||
renderer.render(scene, camera);
|
||||
requestAnimationFrame(render);
|
||||
};
|
||||
requestAnimationFrame(render);
|
||||
function onWindowResize() {
|
||||
camera.aspect = window.innerWidth / window.innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
render(0);
|
||||
}
|
||||
window.addEventListener('resize', onWindowResize);
|
||||
return () => {
|
||||
window.removeEventListener('resize', onWindowResize);
|
||||
};
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<canvas ref={ref}></canvas>
|
||||
</>
|
||||
)
|
||||
}`;
|
||||
|
||||
export const styles = `* {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}`;
|
||||
|
||||
<RUASandpack
|
||||
template="react"
|
||||
files={{
|
||||
'/App.js': main,
|
||||
'/styles.css': styles,
|
||||
'/App.js': sandpack['load-background-main'],
|
||||
'/styles.css': sandpack['load-background-styles'],
|
||||
}}
|
||||
options={{
|
||||
autorun: false,
|
||||
@ -142,7 +81,7 @@ We need set texture to cube box each side. so we need six pictures.
|
||||
|
||||
The skybox is six images that can be connected each other.
|
||||
|
||||
<Image src={image1} alt="Skyboxes example" />
|
||||
<Image src={images['load-background']['skybox_example']} />
|
||||
|
||||
We just need load six images in some order, and set them to the scene background.
|
||||
|
||||
@ -184,74 +123,11 @@ controls.enablePan = false;
|
||||
controls.update();
|
||||
```
|
||||
|
||||
export const main2 = `import { useEffect, useRef } from "react";
|
||||
import * as THREE from "three";
|
||||
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
|
||||
const manager = new THREE.LoadingManager();
|
||||
manager.onProgress = (item, loaded, total) => {
|
||||
console.log(loaded, total);
|
||||
};
|
||||
|
||||
export default function App() {
|
||||
const ref = useRef(null);
|
||||
const scene = new THREE.Scene();
|
||||
const sky = new THREE.CubeTextureLoader(manager).load([
|
||||
"https://raw.githubusercontent.com/DefectingCat/three-playground/master/src/assets/first-project/skybox/corona_ft.png",
|
||||
"https://raw.githubusercontent.com/DefectingCat/three-playground/master/src/assets/first-project/skybox/corona_bk.png",
|
||||
"https://raw.githubusercontent.com/DefectingCat/three-playground/master/src/assets/first-project/skybox/corona_up.png",
|
||||
"https://raw.githubusercontent.com/DefectingCat/three-playground/master/src/assets/first-project/skybox/corona_dn.png",
|
||||
"https://raw.githubusercontent.com/DefectingCat/three-playground/master/src/assets/first-project/skybox/corona_rt.png",
|
||||
"https://raw.githubusercontent.com/DefectingCat/three-playground/master/src/assets/first-project/skybox/corona_lf.png"
|
||||
]);
|
||||
scene.background = sky;
|
||||
const camera = new THREE.PerspectiveCamera(
|
||||
75,
|
||||
window.innerWidth / window.innerHeight,
|
||||
0.1,
|
||||
1000
|
||||
);
|
||||
camera.position.set(0, 1, 0);
|
||||
camera.up.set(0, 0, 1);
|
||||
scene.add(camera);
|
||||
useEffect(() => {
|
||||
const renderer = new THREE.WebGLRenderer({
|
||||
canvas: ref.current
|
||||
});
|
||||
renderer.setPixelRatio(window.devicePixelRatio);
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
const controls = new OrbitControls(camera, ref.current);
|
||||
controls.enablePan = false;
|
||||
controls.target.set(0, 0, 0);
|
||||
controls.update();
|
||||
const render = (time) => {
|
||||
renderer.render(scene, camera);
|
||||
requestAnimationFrame(render);
|
||||
};
|
||||
requestAnimationFrame(render);
|
||||
function onWindowResize() {
|
||||
camera.aspect = window.innerWidth / window.innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
render(0);
|
||||
}
|
||||
window.addEventListener("resize", onWindowResize);
|
||||
return () => {
|
||||
window.removeEventListener("resize", onWindowResize);
|
||||
};
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<canvas ref={ref}></canvas>
|
||||
</>
|
||||
);
|
||||
}
|
||||
`;
|
||||
|
||||
<RUASandpack
|
||||
template="react"
|
||||
files={{
|
||||
'/App.js': main2,
|
||||
'/styles.css': styles,
|
||||
'/App.js': sandpack['load-background-main2'],
|
||||
'/styles.css': sandpack['load-background-styles'],
|
||||
}}
|
||||
options={{
|
||||
autorun: false,
|
||||
|
3
data/sandpack/hello-world/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export const hello = `export default function App() {
|
||||
return <h1>Hello world</h1>
|
||||
}`;
|
108
data/sandpack/how-to-load-a-background-with-threejs/index.ts
Normal file
@ -0,0 +1,108 @@
|
||||
export const main = `import { useEffect, useRef } from 'react';
|
||||
import * as THREE from 'three';
|
||||
|
||||
export default function App() {
|
||||
const ref = useRef(null);
|
||||
const scene = new THREE.Scene();
|
||||
const camera = new THREE.PerspectiveCamera(
|
||||
75,
|
||||
window.innerWidth / window.innerHeight,
|
||||
0.1,
|
||||
1000
|
||||
);
|
||||
useEffect(() => {
|
||||
const renderer = new THREE.WebGLRenderer({
|
||||
canvas: ref.current,
|
||||
});
|
||||
renderer.setPixelRatio(window.devicePixelRatio);
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
const render = (time) => {
|
||||
renderer.render(scene, camera);
|
||||
requestAnimationFrame(render);
|
||||
};
|
||||
requestAnimationFrame(render);
|
||||
function onWindowResize() {
|
||||
camera.aspect = window.innerWidth / window.innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
render(0);
|
||||
}
|
||||
window.addEventListener('resize', onWindowResize);
|
||||
return () => {
|
||||
window.removeEventListener('resize', onWindowResize);
|
||||
};
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<canvas ref={ref}></canvas>
|
||||
</>
|
||||
)
|
||||
}`;
|
||||
|
||||
export const main2 = `import { useEffect, useRef } from "react";
|
||||
import * as THREE from "three";
|
||||
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
|
||||
const manager = new THREE.LoadingManager();
|
||||
manager.onProgress = (item, loaded, total) => {
|
||||
console.log(loaded, total);
|
||||
};
|
||||
|
||||
export default function App() {
|
||||
const ref = useRef(null);
|
||||
const scene = new THREE.Scene();
|
||||
const sky = new THREE.CubeTextureLoader(manager).load([
|
||||
"https://raw.githubusercontent.com/DefectingCat/three-playground/master/src/assets/first-project/skybox/corona_ft.png",
|
||||
"https://raw.githubusercontent.com/DefectingCat/three-playground/master/src/assets/first-project/skybox/corona_bk.png",
|
||||
"https://raw.githubusercontent.com/DefectingCat/three-playground/master/src/assets/first-project/skybox/corona_up.png",
|
||||
"https://raw.githubusercontent.com/DefectingCat/three-playground/master/src/assets/first-project/skybox/corona_dn.png",
|
||||
"https://raw.githubusercontent.com/DefectingCat/three-playground/master/src/assets/first-project/skybox/corona_rt.png",
|
||||
"https://raw.githubusercontent.com/DefectingCat/three-playground/master/src/assets/first-project/skybox/corona_lf.png"
|
||||
]);
|
||||
scene.background = sky;
|
||||
const camera = new THREE.PerspectiveCamera(
|
||||
75,
|
||||
window.innerWidth / window.innerHeight,
|
||||
0.1,
|
||||
1000
|
||||
);
|
||||
camera.position.set(0, 1, 0);
|
||||
camera.up.set(0, 0, 1);
|
||||
scene.add(camera);
|
||||
useEffect(() => {
|
||||
const renderer = new THREE.WebGLRenderer({
|
||||
canvas: ref.current
|
||||
});
|
||||
renderer.setPixelRatio(window.devicePixelRatio);
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
const controls = new OrbitControls(camera, ref.current);
|
||||
controls.enablePan = false;
|
||||
controls.target.set(0, 0, 0);
|
||||
controls.update();
|
||||
const render = (time) => {
|
||||
renderer.render(scene, camera);
|
||||
requestAnimationFrame(render);
|
||||
};
|
||||
requestAnimationFrame(render);
|
||||
function onWindowResize() {
|
||||
camera.aspect = window.innerWidth / window.innerHeight;
|
||||
camera.updateProjectionMatrix();
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
render(0);
|
||||
}
|
||||
window.addEventListener("resize", onWindowResize);
|
||||
return () => {
|
||||
window.removeEventListener("resize", onWindowResize);
|
||||
};
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<canvas ref={ref}></canvas>
|
||||
</>
|
||||
);
|
||||
}
|
||||
`;
|
||||
|
||||
export const styles = `* {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}`;
|
@ -1,26 +1,11 @@
|
||||
import remarkFrontmatter from 'remark-frontmatter';
|
||||
import mdx from '@next/mdx';
|
||||
import rehypePrism from '@mapbox/rehype-prism';
|
||||
import composePlugins from 'next-compose-plugins';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import rehypeSlug from 'rehype-slug';
|
||||
// import { remarkCodeHike } from '@code-hike/mdx';
|
||||
// import { createRequire } from 'module';
|
||||
// const require = createRequire(import.meta.url);
|
||||
// const theme = require('shiki/themes/nord.json');
|
||||
|
||||
const composedConfig = composePlugins([
|
||||
mdx({
|
||||
extension: /\.mdx?$/,
|
||||
options: {
|
||||
remarkPlugins: [remarkFrontmatter, remarkGfm],
|
||||
rehypePlugins: [
|
||||
[rehypePrism, { alias: { vue: 'xml' }, ignoreMissing: true }],
|
||||
rehypeSlug,
|
||||
],
|
||||
providerImportSource: '@mdx-js/react',
|
||||
},
|
||||
}),
|
||||
/** @type {import('next').NextConfig} */
|
||||
{
|
||||
reactStrictMode: true,
|
||||
@ -28,6 +13,7 @@ const composedConfig = composePlugins([
|
||||
experimental: {
|
||||
// runtime: 'nodejs',
|
||||
// outputStandalone: true,
|
||||
images: { allowFutureImage: true },
|
||||
},
|
||||
pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'],
|
||||
images: { domains: ['avatars.githubusercontent.com'] },
|
||||
|
@ -8,7 +8,6 @@ import rehypePrism from '@mapbox/rehype-prism';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import rehypeSlug from 'rehype-slug';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { MyMatters } from 'types';
|
||||
|
||||
const Footer = dynamic(() => import('components/Footer'));
|
||||
const HeadBar = dynamic(() => import('components/NavBar'));
|
||||
@ -26,7 +25,7 @@ const Slug = ({
|
||||
<time>{mdxSource.frontmatter?.date}</time>
|
||||
|
||||
<article id="post-content">
|
||||
<MDXRemote {...mdxSource} components={components} />
|
||||
<MDXRemote {...mdxSource} components={components as {}} />
|
||||
<PostComment />
|
||||
</article>
|
||||
</main>
|
||||
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 504 KiB After Width: | Height: | Size: 504 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 218 KiB After Width: | Height: | Size: 218 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |