mirror of
https://github.com/troisjs/trois.git
synced 2024-11-24 04:12:02 +08:00
add slider1
This commit is contained in:
parent
d698324272
commit
d504046f1b
@ -11,17 +11,17 @@
|
|||||||
import Demo1 from './components/demos/Demo1.vue';
|
import Demo1 from './components/demos/Demo1.vue';
|
||||||
import Demo2 from './components/demos/Demo2.vue';
|
import Demo2 from './components/demos/Demo2.vue';
|
||||||
import Demo3 from './components/demos/Demo3.vue';
|
import Demo3 from './components/demos/Demo3.vue';
|
||||||
import Demo4 from './components/demos/Demo4.vue';
|
import Slider1 from './components/demos/Slider1.vue';
|
||||||
import DemoGLTF from './components/demos/DemoGLTF.vue';
|
import DemoGLTF from './components/demos/DemoGLTF.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
components: {
|
components: {
|
||||||
Demo1, Demo2, Demo3, Demo4, DemoGLTF,
|
Demo1, Demo2, Demo3, Slider1, DemoGLTF,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tests: ['Demo1', 'Demo2', 'Demo3', 'Demo4', 'DemoGLTF'],
|
tests: ['Demo1', 'Demo2', 'Demo3', 'Slider1', 'DemoGLTF'],
|
||||||
test: 'Demo1',
|
test: 'Demo1',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
23
src/components/demos/Slider1.vue
Normal file
23
src/components/demos/Slider1.vue
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<template>
|
||||||
|
<Slider1 :images="images" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Slider1 from '../sliders/Slider1.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { Slider1 },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
images: [
|
||||||
|
{ src: 'https://assets.codepen.io/33787/img1.jpg' },
|
||||||
|
{ src: 'https://assets.codepen.io/33787/img2.jpg' },
|
||||||
|
{ src: 'https://assets.codepen.io/33787/img3.jpg' },
|
||||||
|
{ src: 'https://assets.codepen.io/33787/img4.jpg' },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
151
src/components/sliders/Slider1.vue
Normal file
151
src/components/sliders/Slider1.vue
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
<template>
|
||||||
|
<Renderer ref="renderer">
|
||||||
|
<Camera ref="camera" :position="{ z: 150 }"></Camera>
|
||||||
|
<Scene ref="scene">
|
||||||
|
</Scene>
|
||||||
|
</Renderer>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Object3D } from 'three';
|
||||||
|
import { gsap, Power4 } from 'gsap';
|
||||||
|
import { lerp, limit } from '../../tools.js';
|
||||||
|
import AnimatedPlane from './AnimatedPlane.js';
|
||||||
|
import useTextures from './useTextures';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
images: Array,
|
||||||
|
events: { type: Object, default: () => { return { wheel: true, click: true, keyup: true }; } },
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
const { textures, loadTextures } = useTextures();
|
||||||
|
return {
|
||||||
|
textures,
|
||||||
|
loadTextures,
|
||||||
|
progress: 0,
|
||||||
|
targetProgress: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.three = this.$refs.renderer.three;
|
||||||
|
|
||||||
|
if (this.images.length < 2) {
|
||||||
|
console.error('This slider needs at least 2 images.');
|
||||||
|
} else {
|
||||||
|
this.loadTextures(this.images, this.init);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
unmounted() {
|
||||||
|
document.removeEventListener('click', this.onClick);
|
||||||
|
document.removeEventListener('keyup', this.onKeyup);
|
||||||
|
window.removeEventListener('wheel', this.onWheel);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
this.initScene();
|
||||||
|
|
||||||
|
gsap.fromTo(this.plane1.uProgress,
|
||||||
|
{
|
||||||
|
value: -2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
duration: 2.5,
|
||||||
|
ease: Power4.easeOut,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (this.events.click) document.addEventListener('click', this.onClick);
|
||||||
|
if (this.events.keyup) document.addEventListener('keyup', this.onKeyup);
|
||||||
|
if (this.events.wheel) window.addEventListener('wheel', this.onWheel);
|
||||||
|
this.three.onBeforeRender(this.updateProgress);
|
||||||
|
this.three.onAfterResize(this.onResize);
|
||||||
|
},
|
||||||
|
initScene() {
|
||||||
|
const renderer = this.three.renderer;
|
||||||
|
const scene = this.$refs.scene.scene;
|
||||||
|
|
||||||
|
this.plane1 = new AnimatedPlane({
|
||||||
|
renderer, screen: this.three.size,
|
||||||
|
size: 10,
|
||||||
|
anim: 1,
|
||||||
|
texture: this.textures[0],
|
||||||
|
});
|
||||||
|
|
||||||
|
this.plane2 = new AnimatedPlane({
|
||||||
|
renderer, screen: this.three.size,
|
||||||
|
size: 10,
|
||||||
|
anim: 2,
|
||||||
|
texture: this.textures[1],
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setPlanesProgress(0);
|
||||||
|
this.planes = new Object3D();
|
||||||
|
this.planes.add(this.plane1.o3d);
|
||||||
|
this.planes.add(this.plane2.o3d);
|
||||||
|
scene.add(this.planes);
|
||||||
|
},
|
||||||
|
onResize() {
|
||||||
|
this.plane1.resize();
|
||||||
|
this.plane2.resize();
|
||||||
|
},
|
||||||
|
onWheel(e) {
|
||||||
|
// e.preventDefault();
|
||||||
|
if (e.deltaY > 0) {
|
||||||
|
this.targetProgress = limit(this.targetProgress + 1 / 20, 0, this.images.length - 1);
|
||||||
|
} else {
|
||||||
|
this.targetProgress = limit(this.targetProgress - 1 / 20, 0, this.images.length - 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onClick(e) {
|
||||||
|
if (e.clientY < this.three.size.height / 2) {
|
||||||
|
this.navPrevious();
|
||||||
|
} else {
|
||||||
|
this.navNext();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onKeyup(e) {
|
||||||
|
if (e.keyCode === 37 || e.keyCode === 38) {
|
||||||
|
this.navPrevious();
|
||||||
|
} else if (e.keyCode === 39 || e.keyCode === 40) {
|
||||||
|
this.navNext();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
navNext() {
|
||||||
|
if (Number.isInteger(this.targetProgress)) this.targetProgress += 1;
|
||||||
|
else this.targetProgress = Math.ceil(this.targetProgress);
|
||||||
|
this.targetProgress = limit(this.targetProgress, 0, this.images.length - 1);
|
||||||
|
},
|
||||||
|
navPrevious() {
|
||||||
|
if (Number.isInteger(this.targetProgress)) this.targetProgress -= 1;
|
||||||
|
else this.targetProgress = Math.floor(this.targetProgress);
|
||||||
|
this.targetProgress = limit(this.targetProgress, 0, this.images.length - 1);
|
||||||
|
},
|
||||||
|
updateProgress() {
|
||||||
|
const progress1 = lerp(this.progress, this.targetProgress, 0.1);
|
||||||
|
const pdiff = progress1 - this.progress;
|
||||||
|
if (pdiff === 0) return;
|
||||||
|
|
||||||
|
const p0 = this.progress % 1;
|
||||||
|
const p1 = progress1 % 1;
|
||||||
|
if ((pdiff > 0 && p1 < p0) || (pdiff < 0 && p0 < p1)) {
|
||||||
|
const i = Math.floor(progress1);
|
||||||
|
this.plane1.setTexture(this.textures[i]);
|
||||||
|
this.plane2.setTexture(this.textures[i + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.progress = progress1;
|
||||||
|
this.setPlanesProgress(this.progress % 1);
|
||||||
|
},
|
||||||
|
setPlanesProgress(progress) {
|
||||||
|
this.plane1.uProgress.value = progress;
|
||||||
|
this.plane2.uProgress.value = -1 + progress;
|
||||||
|
this.plane1.material.opacity = 1 - progress;
|
||||||
|
this.plane2.material.opacity = progress;
|
||||||
|
this.plane1.o3d.position.z = progress;
|
||||||
|
this.plane2.o3d.position.z = progress - 1;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
28
src/components/sliders/useTextures.js
Normal file
28
src/components/sliders/useTextures.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { TextureLoader } from 'three';
|
||||||
|
|
||||||
|
export default function useTextures() {
|
||||||
|
const loader = new TextureLoader();
|
||||||
|
const textures = [];
|
||||||
|
|
||||||
|
const loadTexture = (img, index) => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
loader.load(
|
||||||
|
img.src,
|
||||||
|
texture => {
|
||||||
|
textures[index] = texture;
|
||||||
|
resolve(texture);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const loadTextures = (images, cb) => {
|
||||||
|
textures.splice(0);
|
||||||
|
Promise.all(images.map(loadTexture)).then(cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
textures,
|
||||||
|
loadTextures,
|
||||||
|
};
|
||||||
|
};
|
@ -17,3 +17,7 @@ export function lerpv3(v1, v2, amount) {
|
|||||||
v1.y = lerp(v1.y, v2.y, amount);
|
v1.y = lerp(v1.y, v2.y, amount);
|
||||||
v1.z = lerp(v1.z, v2.z, amount);
|
v1.z = lerp(v1.z, v2.z, amount);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function limit(val, min, max) {
|
||||||
|
return val < min ? min : (val > max ? max : val);
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user