Rollup author's new work: Svelte Cubed, embrace three js !

Posted by slimjim on Fri, 10 Dec 2021 06:03:07 +0100

On November 20, 2021, Svelte held the fourth virtual conference.

Of course, the most refreshing thing in front of me at the meeting was the svelte cube brought by rich Harris, the wheel brother.

Popular science: rich Harris, author of Svelte and Rollup

The highlight of this project is not because other speakers are not good, nor because brother wheel is the author of Svelte. But because the Svelte cube he brought has a very similar feeling to the technology stack I am currently responsible for the project in the company. Because a new H5 project needs to be developed in the company, I adopted the more radical Svelte + aframe / three js + Tailwind. CSS + vite combination. The volume of both the development experience and the final production package is very wonderful after the whole set of combination. Therefore, when I saw brother wheel release this new wheel, I was very excited and actually integrated the combination I wanted directly into Svelte.

Then let's look at the face of svelte cubed:

open https://svelte-cubed.vercel.app/ At present, the official website does not use a custom domain name, but directly uses the domain name of vercel. It is speculated that brother wheel went to vercel to work.

Let's take a look at some official examples of cubed:

actual combat

Let's try to write a project ourselves. First, initialize an svelte project

npm init svelte@next my-new-app
cd my-new-app
npm install
npm run dev

Install three JS and svelte cubed

npm install three svelte-cubed

If you use TypeScript, you also need to introduce three ts declaration of JS

npm install -D @types/three

Open Src / routes / index svelte

<script>
    import * as THREE from 'three';
    import * as SC from 'svelte-cubed';
</script>

<SC.Canvas>
    <SC.Mesh geometry={new THREE.BoxGeometry()} />
    <SC.PerspectiveCamera position={[1, 1, 3]} />
</SC.Canvas>

Then run npm run dev

Then an error is reported. Through the query, it is probably because a vite option is not set.

Open svelte config. JS, which can be solved by adding the option of Guan Xu vite ssr.

import adapter from '@sveltejs/adapter-auto';

/** @type {import('@sveltejs/kit').Config} */
const config = {
    kit: {
        adapter: adapter(),

        // hydrate the <div id="svelte"> element in src/app.html
        target: '#svelte',
        vite: {
            ssr: {
                noExternal: ["three"]
            }
        }
    }
};

export default config;

Our project is running.

The official also made it clear that it would not be against three JS object, but directly use three JS to create and set objects, so you need to introduce three JS, (I personally feel that this benefit is that we can migrate from other non data-driven Three.js projects to svelte cubed at no cost).

You can see that if you use pure three JS to write code will have several times more content than svelte cube. Over time, imperative code becomes less maintainable.

By adding controllers, we can interact easily.

Open Src / routes / index svelte

<SC.Canvas antialias background={new THREE.Color('papayawhip')}>
    <SC.Mesh geometry={new THREE.BoxGeometry()} />
    <SC.PerspectiveCamera position={[1, 1, 3]} />
+    <SC.OrbitControls enableZoom={false} />
</SC.Canvas>

Use Svelte's data-driven to easily modify three js Objects.

<script>
    import * as THREE from 'three';
    import * as SC from 'svelte-cubed';
+
+    let width = 1;
+    let height = 1;
+    let depth = 1;
</script>

<SC.Canvas antialias background={new THREE.Color('papayawhip')}>
    <SC.Mesh
        geometry={new THREE.BoxGeometry()}
        material={new THREE.MeshStandardMaterial({ color: 0xff3e00 })}
+        scale={[width, height, depth]}
    />
    <SC.PerspectiveCamera position={[1, 1, 3]} />
    <SC.OrbitControls enableZoom={false} />
    <SC.AmbientLight intensity={0.6} />
    <SC.DirectionalLight intensity={0.6} position={[-2, 3, 2]} />
​</SC.Canvas>

+<div class="controls">
+    <label><input type="range" bind:value={width} min={0.1} max={3} step={0.1} /> width</label>
+    <label><input type="range" bind:value={height} min={0.1} max={3} step={0.1} /> height</label>
+    <label><input type="range" bind:value={depth} min={0.1} max={3} step={0.1} /> depth</label>
+</div>
+
+<style>
+    .controls {
+        position: absolute;
+    }
+</style>

Using data-driven, animation can also be added quickly.

<script>
    import * as THREE from 'three';
    import * as SC from 'svelte-cubed';

    let width = 1;
    let height = 1;
    let depth = 1;
+
+    let spin = 0;
+
+    SC.onFrame(() => {
+        spin += 0.01;
+    });
</script>

<SC.Canvas antialias background={new THREE.Color('papayawhip')}>
    <SC.Mesh
        geometry={new THREE.BoxGeometry()}
        material={new THREE.MeshStandardMaterial({ color: 0xff3e00 })}
        scale={[width, height, depth]}
+        rotation={[0, spin, 0]}
    />
    <SC.PerspectiveCamera position={[1, 1, 3]} />
    <SC.OrbitControls enableZoom={false} />
    <SC.AmbientLight intensity={0.6} />
    <SC.DirectionalLight intensity={0.6} position={[-2, 3, 2]} />
</SC.Canvas>

summary

However, with the release of svelte cube, there are many doubts. Some people think that this thing is not really "creating new things", but just writing some glue layer code.

RH also replied in person

In short, you use Svelte Cubed for the same reason you use Svelte (or any component framework) itself: declarative code is often more robust, easier to read, and easier to maintain than imperative code.
There is absolutely nothing wrong with using Three directly, but this is equivalent to using DOM directly. To some extent, it is difficult to track hierarchical relationships that are not expressed as hierarchies, and managing the state of the entire application becomes a burden.

In addition, because components have a manageable life cycle, if you use a framework like Vite (or Vite's SvelteKit), you can get hot module overloading for free. Once you try to build a scene in this way (for example, keep your camera position when you adjust the properties of the object you zoom in), Cmd-R driven development will feel very pale—— By deep Com translation

Additional note: the difference between declarative and functional expressions. Take creating div as an example:
1. Declarative writing < div > < / div >
2. Functional writing document createElement('div');

However, personally, svelte cubed brings the following advantages

1. Level clarity brought by declarative

2. Data driven can bring traversal (much faster than Three.js)

3. When the component is not very large, its volume is still very small (compared with React and Vue, it is much smaller to introduce a whole runtime)

Now that svelte cubed has integrated three JS, in the era of the rise of meta concept, will it be far from VR/AR? (in fact, as long as Three.js is integrated, it is very easy to write VR using the ecology of Three.js)

Finally, list some excellent frameworks in the VR/AR field (if you are interested in this aspect), aframe (a wonderful statement similar to Svelte), react three fiber and Babylon js .

reference resources

https://twitter.com/opensas/s...

https://twitter.com/SvelteSoc...

https://svelte-cubed.vercel.a...

https://github.com/Rich-Harri...

https://news.ycombinator.com/...

epilogue

❤️ Follow + like + collect + comment + forward ❤️ , Original is not easy, encourage the author to create better articles

Note the official account of autumn wind, a front end official account focused on front-end interview, engineering and open source.

Topics: Javascript Front-end Three.js svelte