Skip to content

Commit

Permalink
feat(core): cleaning up a little bit
Browse files Browse the repository at this point in the history
  • Loading branch information
alvarosabu committed Mar 12, 2023
1 parent e19da3a commit 8bdd825
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 161 deletions.
27 changes: 16 additions & 11 deletions packages/tres/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,39 @@
import { ref, watchEffect } from 'vue'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
import TresCanvas from './components/TresCanvas'
import AkuAku from './demos/AkuAku.vue'
import { useRenderLoop, useTres } from '/@/composables'
import { extend } from './core/catalogue'
// import TheEvents from '/@/components/TheEvents.vue'
const gl = {
antialias: true,
alpha: true,
shadows: true,
clearColor: '#82DBC5',
}
const { state } = useTres()
let controls = null
extend({ OrbitControls })
const { onLoop } = useRenderLoop()
watchEffect(() => {
if (state.camera && state.renderer) {
controls = new OrbitControls(state.camera, state.renderer.domElement)
/* controls = new OrbitControls(state.camera, state.renderer.domElement)
controls.enableDamping = true
controls.dampingFactor = 0.05
controls.screenSpacePanning = false
controls.minDistance = 1
controls.maxDistance = 500
controls.maxPolarAngle = Math.PI / 2
controls.maxPolarAngle = Math.PI / 2 */
}
})
onLoop(() => {
/* onLoop(() => {
if (controls) {
controls.update()
}
})
}) */
const gridVisible = ref(false)
function click(e) {
Expand All @@ -45,17 +47,20 @@ function enter(e) {
</script>

<template>
<button @click="click">{{ gridVisible }}</button>
<p v-if="gridVisible">Soc invisible</p>
<TresCanvas v-bind="gl">
<TresPerspectiveCamera :args="[75, 1, 0.1, 1000]" :position="[0, 2, 7]"></TresPerspectiveCamera>
<TresOrbitControls v-if="state.camera" :args="[state.camera, state.renderer.domElement]" />
<TresAmbientLight :color="0xffffff" :intensity="0.75" />
<TresDirectionalLight :color="0xffffff" :intensity="2" :position="[-2, 2, 0]" />
<TresMesh :position="[0, 1, 0]" @click="click" @pointer-enter="enter">
<TresDirectionalLight :color="0xffffff" :intensity="2" :position="[-2, 2, 0]" cast-shadow />
<TresMesh :position="[0, 3, 0]" @click="click" @pointer-enter="enter" cast-shadow>
<TresSphereGeometry :args="[1, 32, 16]"></TresSphereGeometry>
<TresMeshToonMaterial color="teal"></TresMeshToonMaterial>
</TresMesh>
<TresGridHelper v-if="gridVisible" :args="[4, 4]"></TresGridHelper>
<TresMesh :position="[0, 0, 0]" receive-shadow :rotation-x="-Math.PI / 2">
<TresPlaneGeometry :args="[12, 12, 100, 100]"></TresPlaneGeometry>
<TresMeshToonMaterial color="gray"></TresMeshToonMaterial>
</TresMesh>
<TresGridHelper :args="[4, 4]"></TresGridHelper>
</TresCanvas>
</template>

Expand Down
26 changes: 5 additions & 21 deletions packages/tres/src/components/TresCanvas.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { defineComponent, h, PropType, ref, watch, watchEffect, compile } from 'vue'
/* eslint-disable vue/one-component-per-file */
import { defineComponent, h, PropType, ref, watch } from 'vue'
import * as THREE from 'three'
import { ShadowMapType, TextureEncoding, ToneMapping, Scene } from 'three'
import { ShadowMapType, TextureEncoding, ToneMapping } from 'three'
import { createTres } from '/@/core/renderer'
import { useCamera, useRenderer, useRenderLoop, useRaycaster } from '/@/composables'
import TestRenderer from './TestRenderer.vue'
import { TresObject } from '../types'

export const TresCanvas = defineComponent({
name: 'TresCanvas',
Expand Down Expand Up @@ -53,22 +52,11 @@ export const TresCanvas = defineComponent({
})

const app = createTres(slots)
app.mount(scene)
app.mount(scene as unknown as TresObject)

watchEffect(() => {
if (slots) {
console.log('slots', slots)
}
})

console.log({
app,
scene,
TestRenderer,
})
console.log({ scene, renderer })
expose({
scene,
/* app, */
})
})

Expand All @@ -78,13 +66,10 @@ export const TresCanvas = defineComponent({
'div',
{
ref: container,
'data-v-app': true,
id: 'container',
style: {
position: 'relative',
width: '100%',
height: '100%',

pointerEvents: 'auto',
touchAction: 'none',
},
Expand All @@ -110,7 +95,6 @@ export const TresCanvas = defineComponent({
left: 0,
},
}),
/* ...(slots.default ? slots?.default() : [] || []), */
],
),
],
Expand Down
126 changes: 27 additions & 99 deletions packages/tres/src/core/nodeOps.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,10 @@
import { useCamera, useRaycaster, useRenderLoop } from '/@/composables'
import { Mesh } from 'three'
import { useCamera, useRaycaster, useRenderLoop, useLogger } from '/@/composables'
import { RendererOptions } from 'vue'
import { useLogger } from '/@/composables'
import { catalogue } from './catalogue'
import { Mesh } from 'three'
import { useEventListener } from '@vueuse/core'
import { TresEvent, TresObject } from '../types'

const HTML_TAGS =
'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +
'header,hgroup,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,' +
'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +
'data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,' +
'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +
'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +
'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +
'option,output,progress,select,textarea,details,dialog,menu,' +
'summary,template,blockquote,iframe,tfoot'

export const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS)

export function makeMap(str: string, expectsLowerCase?: boolean): (key: string) => boolean {
const map: Record<string, boolean> = Object.create(null)
const list: Array<string> = str.split(',')
for (let i = 0; i < list.length; i++) {
map[list[i]] = true
}
return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val]
}
import { isHTMLTag, kebabToCamel } from '../utils'

const { logWarning } = useLogger()

Expand All @@ -43,33 +21,17 @@ function noop(fn: string): any {
fn
}

const doc = (typeof document !== 'undefined' ? document : null) as Document
export const svgNS = 'http://www.w3.org/2000/svg'

const templateContainer = doc && /*#__PURE__*/ doc.createElement('template')
let scene: TresObject | null = null

let scene = null

export const nodeOps: RendererOptions<any, any> = {
createElement(tag, isSVG, anchor, props) {
// Vue core
/* const el = isSVG ? doc.createElementNS(svgNS, tag) : doc.createElement(tag, anchor ? { anchor } : undefined)
if (tag === 'select' && props && props.multiple != null) {
;(el as HTMLSelectElement).setAttribute('multiple', props.multiple)
}
return el */
// Tres
export const nodeOps: RendererOptions<TresObject, TresObject> = {
createElement(tag, _isSVG, _anchor, props) {
if (tag === 'template') return null
if (isHTMLTag(tag)) return null
let instance

if (props === null) {
props = {}
}
if (props === null) props = {}

if (props?.arg) {
if (props?.args) {
instance = new catalogue[tag.replace('Tres', '')](...props.args)
} else {
instance = new catalogue[tag.replace('Tres', '')]()
Expand Down Expand Up @@ -103,7 +65,7 @@ export const nodeOps: RendererOptions<any, any> = {
},
insert(child, parent, anchor) {
if (scene === null && parent.isScene) scene = parent
if (parent === null) parent = scene
if (parent === null) parent = scene as TresObject
//vue core
/* parent.insertBefore(child, anchor || null) */
if (parent?.isObject3D && child?.isObject3D) {
Expand Down Expand Up @@ -157,48 +119,30 @@ export const nodeOps: RendererOptions<any, any> = {
}
},
remove(node) {
// Vue Core
if (!node) return
const parent = node.parentNode
if (parent) {
parent.removeChild(node)
}
/* if (!node) return
const parent = node.parent
if (parent) {
if (parent.isObject3D && node.isObject3D) {
parent.remove(node)
} else if (typeof node.attach === 'string') {
parent[node.attach] = node.__previousAttach
delete node.__previousAttach
node.parent = null
}
}
node.dispose?.()
node.traverse?.(node => {
;(node as TresObject).dispose?.()
}) */
},
patchProp(node, prop, prevValue, nextValue) {
patchProp(node, prop, _prevValue, nextValue) {
if (node) {
let root = node
let key = prop
let target = root?.[key]
let target = root?.[kebabToCamel(key)]

// Traverse pierced props (e.g. foo-bar=value => foo.bar = value)
/* if (key.includes('-')) {
if (key.includes('-') && !Object.keys(root).includes(kebabToCamel(key))) {
const chain = key.split('-')
target = chain.reduce((acc, key) => acc[key], root)
key = chain.pop() as string

if (!target?.set) root = chain.reduce((acc, key) => acc[key], root)
} */
const value = nextValue
/* try {
const num = parseFloat(value)
value = isNaN(num) ? value : num
} catch (_) {} */
}
let value = nextValue
if (value === '') value = true
// Set prop, prefer atomic methods if applicable
if (!target?.set) root[key] = value
if (!target?.set) root[kebabToCamel(key)] = value
else if (target.constructor === value.constructor && target?.copy) target?.copy(value)
else if (Array.isArray(value)) target.set(...value)
else if (!target.isColor && target.setScalar) target.setScalar(value)
Expand All @@ -207,36 +151,20 @@ export const nodeOps: RendererOptions<any, any> = {
},

parentNode(node) {
// Vue core
return node.parentNode as Element | null
/* return node?.parent || null */
return node?.parent || null
},
createText: text => doc.createTextNode(text),
createText: () => noop('createText'),

createComment: text => doc.createComment(text),
createComment: () => noop('createComment'),

setText: (node, text) => {
node.nodeValue = text
},
setText: () => noop('setText'),

setElementText: (el, text) => {
el.textContent = text
},
nextSibling: node => node.nextSibling,
setElementText: () => noop('setElementText'),
nextSibling: () => noop('nextSibling'),

querySelector: selector => doc.querySelector(selector),
querySelector: () => noop('querySelector'),

setScopeId(el, id) {
/* el.setAttribute(id, '') */
},
setScopeId: () => noop('setScopeId'),
cloneNode: () => noop('cloneNode'),
insertStaticContent: () => noop('insertStaticContent'),

/* nextSibling(node) {
if (node?.parent?.children) {
const index = node.parent.children.indexOf(node)
if (index !== -1) return node.parent.children[index + 1]
}
return null
}, */
}
33 changes: 3 additions & 30 deletions packages/tres/src/core/renderer.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,16 @@
import { isString } from '@vueuse/core'
import * as THREE from 'three'

import { createRenderer } from 'vue'
import { createRenderer, Slots } from 'vue'
import { extend } from './catalogue'
import { nodeOps } from './nodeOps'

function normalizeContainer(container: Element | ShadowRoot | string): Element | null {
if (isString(container)) {
const res = document.querySelector(container)
/* if (__DEV__ && !res) {
console.warn(`Failed to mount app: mount target selector "${container}" returned null.`)
} */
return res
}
/* if (__DEV__ && window.ShadowRoot && container instanceof window.ShadowRoot && container.mode === 'closed') {
console.warn(`mounting on a ShadowRoot with \`{mode: "closed"}\` may lead to unpredictable bugs`)
} */
return container as any
}

export const { createApp } = createRenderer(nodeOps)

export const createTres = slots => {
export const createTres = (slots: Slots) => {
const app = createApp(internalFnComponent)
function internalFnComponent() {
return slots.default()
return slots && slots.default ? slots.default() : []
}

const { mount } = app
app.mount = containerOrSelector => {
const container = normalizeContainer(containerOrSelector)
if (!container) return
if (container instanceof Element) {
container.removeAttribute('v-cloak')
container.setAttribute('data-v-app', '')
}
mount(container, false, false)
}

return app
}

Expand Down
26 changes: 26 additions & 0 deletions packages/tres/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,29 @@ export const merge = (target: any, source: any) => {
Object.assign(target || {}, source)
return target
}

const HTML_TAGS =
'html,body,base,head,link,meta,style,title,address,article,aside,footer,' +
'header,hgroup,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,' +
'figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,' +
'data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,' +
'time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,' +
'canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,' +
'th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,' +
'option,output,progress,select,textarea,details,dialog,menu,' +
'summary,template,blockquote,iframe,tfoot'

export const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS)

export function kebabToCamel(str: string) {
return str.replace(/-([a-z])/g, (_, c) => c.toUpperCase())
}

export function makeMap(str: string, expectsLowerCase?: boolean): (key: string) => boolean {
const map: Record<string, boolean> = Object.create(null)
const list: Array<string> = str.split(',')
for (let i = 0; i < list.length; i++) {
map[list[i]] = true
}
return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val]
}

0 comments on commit 8bdd825

Please sign in to comment.