From ce8160888c1b7d423e545f8583d3c4f363911e0f Mon Sep 17 00:00:00 2001 From: Fritz Lin Date: Sun, 19 Apr 2020 16:14:49 +0800 Subject: [PATCH] feat: add vue-threejs demo & track mountNode resize, etc --- public/code/index.yml | 1 + public/code/vue-threejs.js | 63 +++++++++++++++++++++++++++++++++ public/code/vue-threejs.js.png | Bin 0 -> 10280 bytes public/index.html | 2 +- src/playground/Playground.tsx | 22 ++++++++++-- src/playground/types.d.ts | 1 + 6 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 public/code/vue-threejs.js create mode 100644 public/code/vue-threejs.js.png diff --git a/public/code/index.yml b/public/code/index.yml index a818580..f691a42 100644 --- a/public/code/index.yml +++ b/public/code/index.yml @@ -1,4 +1,5 @@ - hello-world.jsx +- vue-threejs.js - react-at.jsx - vue-at.js - vue-render-h.js diff --git a/public/code/vue-threejs.js b/public/code/vue-threejs.js new file mode 100644 index 0000000..e9e6e97 --- /dev/null +++ b/public/code/vue-threejs.js @@ -0,0 +1,63 @@ +// await loadJs('https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js') +await loadJs('https://unpkg.com/vue@2.6.11/dist/vue.min.js') + +// await loadJs('https://unpkg.com/three@0.115.0/build/three.min.js') +await loadJs('https://unpkg.com/three@0.81.2/build/three.min.js') + +// await loadJs('https://unpkg.com/vue-threejs@0.2.0-alpha.1/lib/VueThreejs.umd.min.js') +await loadJs('https://unpkg.com/vue-threejs@0.2.0-alpha.1/lib/VueThreejs.umd.js') + +appendCss(` +#mountNode { overflow:hidden; background-color:black } +`) + +Vue.use(VueThreejs) + +// Creating a scene - Three.js Documentation +// https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene +let App = { + template: ` +
+ + + + + + + + + + +
+ `, + data() { + return { + bg: { + sysKey: 0, + // size: { w: window.innerWidth, h: window.innerHeight }, + size: { w: mountNode.clientWidth, h: mountNode.clientHeight }, + }, + ui: { + rotation: { x: 0, y: 0, z: 0 }, + } + } + }, + created() { + this.handleResize = _.debounce(this.handleResize, 2000) + }, + mounted() { + mountNode.addEventListener('resize', this.handleResize) + }, + beforeDestroy() { + mountNode.removeEventListener('resize', this.handleResize) + }, + methods: { + animate() { + this.ui.rotation.x += 0.01 + this.ui.rotation.y += 0.01 + }, + handleResize() { + triggerPreview() + } + } +} diff --git a/public/code/vue-threejs.js.png b/public/code/vue-threejs.js.png new file mode 100644 index 0000000000000000000000000000000000000000..38f47a37f75498cbbd337164dcff7a95bcb4617f GIT binary patch literal 10280 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 literal 0 HcmV?d00001 diff --git a/public/index.html b/public/index.html index dd1ccfd..91612cf 100644 --- a/public/index.html +++ b/public/index.html @@ -19,7 +19,7 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - React App + diff --git a/src/playground/Playground.tsx b/src/playground/Playground.tsx index fd8cc84..64c5633 100644 --- a/src/playground/Playground.tsx +++ b/src/playground/Playground.tsx @@ -131,9 +131,8 @@ export let Playground: React.FC = () => { setCompiling(true); try { let res = wrapCode(code); - if (file && file.endsWith('.jsx')) { - res = await babelTransform(res); - } + let hasJsx = file && ['.jsx', '.tsx'].some(ext => file.endsWith(ext)); + if (hasJsx) res = await babelTransform(res); setPreview(res); } catch (err) { displayError(err); @@ -158,6 +157,10 @@ export let Playground: React.FC = () => { doPreview, [codeBinding.value] ); + window.triggerPreview = () => { + // doPreview(codeBinding.value); + doPreview(codeBinding.value + `\n\n/* ${new Date()} */`); + }; // useTrigger( // { @@ -170,6 +173,18 @@ export let Playground: React.FC = () => { // keeping sync'd with styled.ts (medium=768px) let isGreaterThanMedium = useMedia({ minWidth: '768px' }); + let handleSizingUpdate = useCallback(() => { + let event = new Event('resize'); + window.mountNode.dispatchEvent(event); + }, []); + + useEffect(() => { + window.addEventListener('resize', handleSizingUpdate); + return () => { + window.removeEventListener('resize', handleSizingUpdate); + }; + }, [handleSizingUpdate]); + return (
@@ -185,6 +200,7 @@ export let Playground: React.FC = () => { void; }