基本上遵循基于 ES6 和 TweenMax 的代码,它可以正常工作,但是我想修复滚动事件,例如当鼠标向上滚动滑块从底部动画(更改)时上下滚动鼠标,使滑块从上到下动画。
我也想基于右中心导航更改点击时的滑块!
感谢进阶!
class Slider {
constructor() {
this.bindAll();
this.el = document.querySelector(".js-slider");
this.inner = this.el.querySelector(".js-slider__inner");
this.slides = [...this.el.querySelectorAll(".js-slide")];
this.bullets = [...this.el.querySelectorAll(".js-slider-bullet")];
this.renderer = null;
this.scene = null;
this.clock = null;
this.camera = null;
this.images = [
"https://s3-us-west-2.amazonaws.com/s.cdpn.io/58281/bg1.jpg",
"https://s3-us-west-2.amazonaws.com/s.cdpn.io/58281/bg2.jpg",
"https://s3-us-west-2.amazonaws.com/s.cdpn.io/58281/bg3.jpg"
];
this.data = {
current: 0,
next: 1,
total: this.images.length - 1,
delta: 0
};
this.state = {
animating: false,
text: false,
initial: true
};
this.textures = null;
this.init();
}
bindAll() {
["render", "nextSlide"].forEach(fn => (this[fn] = this[fn].bind(this)));
}
setStyles() {
this.slides.forEach((slide, index) => {
if (index === 0) return;
TweenMax.set(slide, {
autoAlpha: 0
});
});
this.bullets.forEach((bullet, index) => {
if (index === 0) return;
const txt = bullet.querySelector(".js-slider-bullet__text");
const line = bullet.querySelector(".js-slider-bullet__line");
TweenMax.set(txt, {
alpha: 0.25
});
TweenMax.set(line, {
scaleX: 0,
transformOrigin: "left"
});
});
}
cameraSetup() {
this.camera = new THREE.OrthographicCamera(
this.el.offsetWidth / -2,
this.el.offsetWidth / 2,
this.el.offsetHeight / 2,
this.el.offsetHeight / -2,
1,
1000
);
this.camera.lookAt(this.scene.position);
this.camera.position.z = 1;
}
setup() {
this.scene = new THREE.Scene();
this.clock = new THREE.Clock(true);
this.renderer = new THREE.WebGLRenderer({
alpha: true
});
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(this.el.offsetWidth, this.el.offsetHeight);
this.inner.appendChild(this.renderer.domElement);
}
loadTextures() {
const loader = new THREE.TextureLoader();
loader.crossOrigin = "";
this.textures = [];
this.images.forEach(image => {
const texture = loader.load(image + "?v=" + Date.now(), this.render);
texture.minFilter = THREE.LinearFilter;
this.textures.push(texture);
});
this.disp = loader.load(
"https://s3-us-west-2.amazonaws.com/s.cdpn.io/58281/rock-_disp.png",
this.render
);
this.disp.magFilter = this.disp.minFilter = THREE.LinearFilter;
this.disp.wrapS = this.disp.wrapT = THREE.RepeatWrapping;
}
createMesh() {
this.mat = new THREE.ShaderMaterial({
uniforms: {
dispPower: {
type: "f",
value: 0.0
},
intensity: {
type: "f",
value: 0.5
},
texture1: {
type: "t",
value: this.textures[0]
},
texture2: {
type: "t",
value: this.textures[1]
},
disp: {
type: "t",
value: this.disp
}
},
transparent: true,
vertexShader: document.querySelector("#vertexShader").textContent,
fragmentShader: document.querySelector("#fragmentShader").textContent
});
const geometry = new THREE.PlaneBufferGeometry(
this.el.offsetWidth,
this.el.offsetHeight,
1
);
const mesh = new THREE.Mesh(geometry, this.mat);
this.scene.add(mesh);
}
transitionNext() {
TweenMax.to(this.mat.uniforms.dispPower, 2.5, {
value: 1,
ease: Expo.easeInOut,
onUpdate: this.render,
onComplete: () => {
this.mat.uniforms.dispPower.value = 0.0;
this.changeTexture();
this.render.bind(this);
this.state.animating = false;
}
});
const current = this.slides[this.data.current];
const next = this.slides[this.data.next];
const currentImages = current.querySelectorAll(".js-slide__img");
const nextImages = next.querySelectorAll(".js-slide__img");
const currentText = current.querySelectorAll(".js-slider__text-line div");
const nextText = next.querySelectorAll(".js-slider__text-line div");
const currentBullet = this.bullets[this.data.current];
const nextBullet = this.bullets[this.data.next];
const currentBulletTxt = currentBullet.querySelectorAll(
".js-slider-bullet__text"
);
const nextBulletTxt = nextBullet.querySelectorAll(
".js-slider-bullet__text"
);
const currentBulletLine = currentBullet.querySelectorAll(
".js-slider-bullet__line"
);
const nextBulletLine = nextBullet.querySelectorAll(
".js-slider-bullet__line"
);
const tl = new TimelineMax({
paused: true
});
if (this.state.initial) {
TweenMax.to(".js-scroll", 1.5, {
yPercent: 100,
alpha: 0,
ease: Power4.easeInOut
});
this.state.initial = false;
}
tl
.staggerFromTo(
currentImages,
1.5, {
yPercent: 0,
scale: 1
}, {
yPercent: -185,
scaleY: 1.5,
ease: Expo.easeInOut
},
0.075
)
.to(
currentBulletTxt,
1.5, {
alpha: 0.25,
ease: Linear.easeNone
},
0
)
.set(
currentBulletLine, {
transformOrigin: "right"
},
0
)
.to(
currentBulletLine,
1.5, {
scaleX: 0,
ease: Expo.easeInOut
},
0
);
if (currentText) {
tl.fromTo(
currentText,
2, {
yPercent: 0
}, {
yPercent: -100,
ease: Power4.easeInOut
},
0
);
}
tl
.set(current, {
autoAlpha: 0
})
.set(
next, {
autoAlpha: 1
},
1
);
if (nextText) {
tl.fromTo(
nextText,
2, {
yPercent: 100
}, {
yPercent: 0,
ease: Power4.easeOut
},
1.5
);
}
tl
.staggerFromTo(
nextImages,
1.5, {
yPercent: 150,
scaleY: 1.5
}, {
yPercent: 0,
scaleY: 1,
ease: Expo.easeInOut
},
0.075,
1
)
.to(
nextBulletTxt,
1.5, {
alpha: 1,
ease: Linear.easeNone
},
1
)
.set(
nextBulletLine, {
transformOrigin: "left"
},
1
)
.to(
nextBulletLine,
1.5, {
scaleX: 1,
ease: Expo.easeInOut
},
1
);
tl.play();
}
prevSlide() {}
nextSlide() {
if (this.state.animating) return;
this.state.animating = true;
this.transitionNext();
this.data.current =
this.data.current === this.data.total ? 0 : this.data.current + 1;
this.data.next =
this.data.current === this.data.total ? 0 : this.data.current + 1;
}
changeTexture() {
this.mat.uniforms.texture1.value = this.textures[this.data.current];
this.mat.uniforms.texture2.value = this.textures[this.data.next];
}
listeners() {
window.addEventListener("wheel", this.nextSlide, {
passive: true
});
}
render() {
this.renderer.render(this.scene, this.camera);
}
init() {
this.setup();
this.cameraSetup();
this.loadTextures();
this.createMesh();
this.setStyles();
this.render();
this.listeners();
}
}
// Toggle active link
const links = document.querySelectorAll(".js-nav a");
links.forEach(link => {
link.addEventListener("click", e => {
e.preventDefault();
links.forEach(other => other.classList.remove("is-active"));
link.classList.add("is-active");
});
});
// Init classes
const slider = new Slider();
@font-face {
font-family: 'font';
src: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/58281/OakesGrotesk-Semi-Bold.woff2") format("woff2");
src: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/58281/OakesGrotesk-Semi-Bold.woff") format("woff");
font-weight: 600;
font-style: normal;
}
@font-face {
font-family: 'font-2';
src: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/58281/MaisonNeue-Book.woff2") format("woff2");
src: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/58281/MaisonNeue-Book.woff") format("woff");
font-weight: normal;
font-style: normal;
}
html {
font-size: 16px;
}
html,
body {
height: 100%;
}
body {
display: flex;
align-items: center;
justify-content: center;
background-color: #111;
font-family: 'font';
overflow: hidden;
}
a {
color: #fff;
text-decoration: none;
}
.scroll {
position: absolute;
bottom: 2rem;
left: 50%;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
color: rgba(255, 255, 255, 0.5);
font-family: 'font-2';
font-size: calc(0.5rem + 0.35vw);
z-index: 10;
}
.logo {
position: absolute;
top: 2rem;
left: 50%;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
padding: 0;
margin: 0;
z-index: 10;
}
.logo img {
display: block;
height: 1rem;
width: auto;
}
ul,
li {
list-style: none;
padding: 0;
margin: 0;
}
.nav {
position: absolute;
top: 2rem;
z-index: 10;
}
.nav--left {
left: 1rem;
}
.nav--right {
right: 1rem;
}
.nav ul {
display: flex;
align-items: center;
height: 1rem;
}
.nav li {
display: block;
margin: 0 1rem;
padding: 0;
}
.nav a {
position: relative;
display: flex;
align-items: center;
font-size: calc(0.5rem + 0.35vw);
font-family: 'font-2';
}
.nav a span {
position: relative;
}
.nav a span:before {
content: '';
position: absolute;
left: 0;
bottom: -0.35rem;
width: 100%;
height: 1px;
background-color: rgba(255, 255, 255, 0.25);
transition: -webkit-transform .75s ease;
transition: transform .75s ease;
transition: transform .75s ease, -webkit-transform .75s ease;
-webkit-transform-origin: right;
transform-origin: right;
-webkit-transform: scaleX(0);
transform: scaleX(0);
}
.nav a:hover span:before,
.nav a.is-active span:before {
-webkit-transform: scaleX(1);
transform: scaleX(1);
-webkit-transform-origin: left;
transform-origin: left;
}
.vert-text {
position: absolute;
bottom: 2rem;
right: 2rem;
width: 15rem;
display: flex;
align-items: center;
z-index: 10;
}
.vert-text span {
display: block;
color: #fff;
text-transform: uppercase;
line-height: 1.1;
-webkit-transform: rotate(-90deg) translateY(15rem);
transform: rotate(-90deg) translateY(15rem);
-webkit-transform-origin: bottom left;
transform-origin: bottom left;
font-size: 1.35rem;
}
.cart-total {
display: block;
height: 2rem;
width: 2rem;
background-color: rgba(255, 255, 255, 0.25);
border-radius: 50%;
text-align: center;
line-height: 2rem;
margin-left: 1rem;
}
.slider {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.slider__text {
position: absolute;
bottom: calc(2rem + 3vw);
left: calc(2rem + 3vw);
z-index: 10;
font-size: calc(1rem + 4vw);
text-transform: uppercase;
-webkit-transform-origin: top;
transform-origin: top;
line-height: 1.075;
color: #fff;
}
.slider__text-line {
overflow: hidden;
}
.slider__inner {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.slider__nav {
position: absolute;
top: 50%;
right: 0;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
z-index: 10;
}
.slider-bullet {
display: flex;
align-items: center;
padding: 1rem 0;
}
.slider-bullet__text {
color: #fff;
font-size: 0.65rem;
margin-right: 1rem;
}
.slider-bullet__line {
background-color: #fff;
height: 1px;
width: 1rem;
}
.slider canvas {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.slide {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
.slide__content {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.slide__img {
position: relative;
width: 25vw;
height: 70vh;
padding: 0;
margin: 0;
min-width: 12.5rem;
-webkit-transform-origin: top;
transform-origin: top;
}
.slide__img:first-child {
top: -1.5rem;
}
.slide__img:last-child {
bottom: -1.5rem;
}
.slide__img img {
display: block;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
-o-object-fit: cover;
object-fit: cover;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/97/three.min.js"></script>
<nav class="nav nav--left js-nav">
<ul>
<li>
<a href="#"><span>Mens</span></a>
</li>
<li>
<a href="#"><span>Womens</span></a>
</li>
<li>
<a href="#" class="is-active"><span>Collections</span></a>
</li>
</ul>
</nav>
<figure class="logo">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/58281/logo_copy_copy.svg">
</figure>
<nav class="nav nav--right">
<ul>
<li>
<a href="https://twitter.com/Jesper_Landberg?lang=en" target="_blank"><span>Say hi</span></a>
</li>
<li>
<a href="#">
<span>Cart</span>
<div class="cart-total">0</div>
</a>
</li>
</ul>
</nav>
<div class="slider js-slider">
<div class="slider__inner js-slider__inner"></div>
<div class="slide js-slide">
<div class="slide__content">
<figure class="slide__img js-slide__img">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/58281/photo1.jpg">
</figure>
<figure class="slide__img js-slide__img">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/58281/photo2.jpg">
</figure>
</div>
<div class="slider__text js-slider__text">
<div class="slider__text-line js-slider__text-line">
<div>Black is</div>
</div>
<div class="slider__text-line js-slider__text-line">
<div>timeless. Black is</div>
</div>
<div class="slider__text-line js-slider__text-line">
<div>the colour of</div>
</div>
<div class="slider__text-line js-slider__text-line">
<div>Eternity.</div>
</div>
</div>
</div>
<div class="slide js-slide">
<div class="slide__content">
<figure class="slide__img js-slide__img">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/58281/photo3.jpg">
</figure>
<figure class="slide__img js-slide__img">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/58281/photo4.jpg">
</figure>
</div>
</div>
<div class="slide js-slide">
<div class="slide__content">
<figure class="slide__img js-slide__img">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/58281/photo5.jpg">
</figure>
<figure class="slide__img js-slide__img">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/58281/photo6.jpg">
</figure>
</div>
</div>
<nav class="slider__nav js-slider__nav">
<div class="slider-bullet js-slider-bullet">
<span class="slider-bullet__text js-slider-bullet__text">01</span>
<span class="slider-bullet__line js-slider-bullet__line"></span>
</div>
<div class="slider-bullet js-slider-bullet">
<span class="slider-bullet__text js-slider-bullet__text">02</span>
<span class="slider-bullet__line js-slider-bullet__line"></span>
</div>
<div class="slider-bullet js-slider-bullet">
<span class="slider-bullet__text js-slider-bullet__text">03</span>
<span class="slider-bullet__line js-slider-bullet__line"></span>
</div>
</nav>
<div class="scroll js-scroll">Scroll</div>
</div>
<div class="vert-text">
<span>
Wings+Horns<br>
X Kyoto Black
</span>
</div>
<script id="vertexShader" type="x-shader/x-vertex">
varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
varying vec2 vUv; uniform sampler2D texture1; uniform sampler2D texture2; uniform sampler2D disp; uniform float dispPower; uniform float intensity; void main() { vec2 uv = vUv; vec4 disp = texture2D(disp, uv); vec2 dispVec = vec2(disp.x, disp.y); vec2
distPos1 = uv + (dispVec * intensity * dispPower); vec2 distPos2 = uv + (dispVec * -(intensity * (1.0 - dispPower))); vec4 _texture1 = texture2D(texture1, distPos1); vec4 _texture2 = texture2D(texture2, distPos2); gl_FragColor = mix(_texture1, _texture2,
dispPower); }
</script>
答案 0 :(得分:1)
您已经在nextSlide函数中捕获了wheel
事件。您现在所要做的就是阅读其event.deltaY
value,以确定滚动是向上还是向下。这是一些伪代码:
var prevY = 0;
var newY = 0;
nextSlide(event) {
newY = event.deltaY;
if(newY > prevY){
slideDown();
}else if(newY < prevY) {
slideUp();
}
// Store deltaY into prevY for comparison on next scroll
prevY = event.deltaY;
}