<!-- Lume 3D elements 👉 https://lume.io ✨ -->
<lume-scene webgl physically-correct-lights perspective="800" fog-mode="linear" fog-color="black" fog-near="600" fog-far="700">
<lume-camera-rig distance="800" min-distance="800" max-distance="800" min-vertical-angle="0" max-vertical-angle="0">
<lume-point-light intensity="1900" slot="camera-child"></lume-point-light>
</lume-camera-rig>
<!-- This element is defined in the JS to show how to make custom elements. -->
<my-photos></my-photos>
</lume-scene>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!--
The following importmap tells the browser where Lume and its dependencies will come from.
Import map generated with JSPM Generator.
Edit: https://generator.jspm.io/#U2NhYGBiDs0rySzJSU1hyCnNTXUw0DPWM9BNzCnISNQzMWQozs/JTNHNKnYw1LPQMzTTLy7JL0oFAOY0iAI4AA
-->
<script type="importmap">
{
"imports": {
"lume": "https://ga.jspm.io/npm:lume@0.3.0-alpha.41/dist/index.js",
"solid-js/store": "https://ga.jspm.io/npm:solid-js@1.8.16/store/dist/store.js",
"classy-solid": "https://ga.jspm.io/npm:classy-solid@0.3.7/dist/index.js"
},
"scopes": {
"https://ga.jspm.io/": {
"@lume/autolayout": "https://ga.jspm.io/npm:@lume/autolayout@0.10.1/dist/AutoLayout.js",
"@lume/custom-attributes/dist/index.js": "https://ga.jspm.io/npm:@lume/custom-attributes@0.2.3/dist/index.js",
"@lume/element": "https://ga.jspm.io/npm:@lume/element@0.11.7/dist/index.js",
"@lume/eventful": "https://ga.jspm.io/npm:@lume/eventful@0.3.2/dist/index.js",
"@lume/kiwi": "https://ga.jspm.io/npm:@lume/kiwi@0.4.3/dist/kiwi.js",
"@lume/three-projected-material/dist/ProjectedMaterial.js": "https://ga.jspm.io/npm:@lume/three-projected-material@0.3.1/dist/ProjectedMaterial.js",
"element-behaviors": "https://ga.jspm.io/npm:element-behaviors@5.0.3/dist/index.js",
"james-bond": "https://ga.jspm.io/npm:james-bond@0.7.3/dist/index.js",
"lowclass": "https://ga.jspm.io/npm:lowclass@7.0.1/dist/index.js",
"regexr": "https://ga.jspm.io/npm:regexr@2.0.4/dist/index.js",
"solid-js": "https://ga.jspm.io/npm:solid-js@1.8.16/dist/solid.js",
"solid-js/html": "https://ga.jspm.io/npm:solid-js@1.8.16/html/dist/html.js",
"solid-js/web": "https://ga.jspm.io/npm:solid-js@1.8.16/web/dist/web.js",
"three": "https://ga.jspm.io/npm:three@0.163.0/build/three.module.js",
"three/": "https://ga.jspm.io/npm:three@0.163.0/"
}
}
}
</script>
html,
body {
margin: 0;
height: 100%;
background: black;
touch-action: none;
}
import {Element3D, element, html, attribute, Index} from 'lume'
import {signalify} from 'classy-solid'
async function fetchPhotos() {
const json = await fetch('https://picsum.photos/v2/list?page=2&limit=14').then(r => r.json())
// change the size to 100x100
json.forEach(photo => {
const parts = photo.download_url.split('/')
parts.pop()
parts.pop()
parts.push(100)
photo.download_url = parts.join('/')
})
console.log('photos:', json.map(photo => photo.download_url))
return json.map(photo => photo.download_url)
}
const photos = await fetchPhotos()
element('my-photos')(class extends Element3D {
template = () => html`
<carousel-layout radius="200">
${photos.map((photo, i) => html`
<lume-rounded-rectangle
size="80 80"
corner-radius="10"
thickness="0.1"
mount-point="0.5 0.5"
has="projected-material"
texture-projectors=${".projector"+i}
cast-shadow="false"
receive-shadow="false"
roughness="0.5"
>
<lume-texture-projector
class=${"projector"+i}
src=${photo}
fitment="contain"
size-mode="p p"
size="1.1 1.1"
align-point="0.5 0.5"
mount-point="0.5 0.5"
position="0 0 150"
></lume-texture-projector>
</lume-rounded-rectangle>
`)}
</carousel-layout>
`
})
element('carousel-layout')(class extends Element3D {
static observedAttributes = {
radius: attribute.string(),
}
radius = 200
hasShadow = true
childrenSignal = []
constructor() {
super()
signalify(this, 'childrenSignal')
}
connectedCallback() {
super.connectedCallback()
this.createEffect(() => {
console.log('children length: ', this.childrenSignal.length)
let i = -1
for (const child of this.childrenSignal) {
i++
child.slot = "slot" + i
}
})
}
#queued = false
childConnectedCallback(...args) {
super.childConnectedCallback(...args)
if (this.#queued) return
this.#queued = true
// return
requestAnimationFrame(() => {
console.log('handle children', this.children)
this.#queued = false
this.childrenSignal = Array.from(this.children)
})
}
template = () => html`
<${Index} each=${() => this.childrenSignal}>
${(_, index) => html`
<lume-element3d rotation=${() => [0, (360 / this.childrenSignal.length) * index]}>
<lume-element3d position=${() => [0, 0, this.radius]} mount-point="0.5 0.5">
<slot name=${() => "slot" + index}></slot>
</lume-element3d>
</lume-element3d>
`}
</>
`
})
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.