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 Demo2 from './components/demos/Demo2.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';
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
Demo1, Demo2, Demo3, Demo4, DemoGLTF,
|
||||
Demo1, Demo2, Demo3, Slider1, DemoGLTF,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tests: ['Demo1', 'Demo2', 'Demo3', 'Demo4', 'DemoGLTF'],
|
||||
tests: ['Demo1', 'Demo2', 'Demo3', 'Slider1', 'DemoGLTF'],
|
||||
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.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