Skip to content

Commit

Permalink
롤오버 이미지 샘플 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
강태희 committed Jan 8, 2025
1 parent 379dbf2 commit 4e8567f
Show file tree
Hide file tree
Showing 12 changed files with 6,377 additions and 0 deletions.
105 changes: 105 additions & 0 deletions sample-html/smoke.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mouse Reactive Smoke</title>
<style>
body {
margin: 0;
overflow: hidden;
}
canvas {
display: block;
}
</style>
</head>
<body>
<!-- <script src="" integrity="sha512-1Ta3TNpk5OD+XKlVMaJY7dC5Tu/Lx4jd2BPu8kxUZ/+hAHpxawrvSiRN0cvBU+oDmSwWVzK8FbILwudcZF6KEQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> -->
<script type="module">
import * as THREE from 'https://cdnjs.cloudflare.com/ajax/libs/three.js/0.172.0/three.module.min.js';

// Scene, Camera, Renderer
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// Particle System
const particleCount = 50;
const particles = new THREE.BufferGeometry();
const positions = new Float32Array(particleCount * 3); // x, y, z for each particle
const velocities = new Float32Array(particleCount * 3); // velocity for each axis

for (let i = 0; i < particleCount; i++) {
positions[i * 3] = (Math.random() - 0.5) * 20; // x
positions[i * 3 + 1] = (Math.random() - 0.5) * 20; // y
positions[i * 3 + 2] = (Math.random() - 0.5) * 20; // z

velocities[i * 3] = 0;
velocities[i * 3 + 1] = 0;
velocities[i * 3 + 2] = 0;
}

particles.setAttribute('position', new THREE.BufferAttribute(positions, 3));
particles.setAttribute('velocity', new THREE.BufferAttribute(velocities, 3));

const material = new THREE.PointsMaterial({
color: 0xffffff,
size: 0.2,
transparent: true,
opacity: 0.8,
blending: THREE.AdditiveBlending,
});
const particleSystem = new THREE.Points(particles, material);
scene.add(particleSystem);

// Camera position
camera.position.z = 10;

// Mouse interaction
const mouse = new THREE.Vector2();
window.addEventListener('mousemove', (event) => {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
});

// Animation loop
function animate() {
const positions = particles.getAttribute('position');
const velocities = particles.getAttribute('velocity');

for (let i = 0; i < particleCount; i++) {
// Add mouse influence
const dx = mouse.x * 10 - positions.array[i * 3];
const dy = mouse.y * 10 - positions.array[i * 3 + 1];
const distance = Math.sqrt(dx * dx + dy * dy);

const force = Math.min(1 / distance, 0.02);

velocities.array[i * 3] += force * dx * 0.1;
velocities.array[i * 3 + 1] += force * dy * 0.1;

// Update positions with velocity
positions.array[i * 3] += velocities.array[i * 3];
positions.array[i * 3 + 1] += velocities.array[i * 3 + 1];
positions.array[i * 3 + 2] += velocities.array[i * 3 + 2] * 0.95; // Slow Z-axis

// Fade out effect
velocities.array[i * 3] *= 0.95;
velocities.array[i * 3 + 1] *= 0.95;
velocities.array[i * 3 + 2] *= 0.95;
}

particles.getAttribute('position').needsUpdate = true;
particles.getAttribute('velocity').needsUpdate = true;

renderer.render(scene, camera);
requestAnimationFrame(animate);
}

animate();
</script>
</body>
</html>
66 changes: 66 additions & 0 deletions scroll/locomotive-scroll.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*! locomotive-scroll v4.1.3 | MIT License | https://github.com/locomotivemtl/locomotive-scroll */
html.has-scroll-smooth {
overflow: hidden; }

html.has-scroll-dragging {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none; }

.has-scroll-smooth body {
overflow: hidden; }

.has-scroll-smooth [data-scroll-container] {
min-height: 100vh; }

[data-scroll-direction="horizontal"] [data-scroll-container] {
height: 100vh;
display: inline-block;
white-space: nowrap; }

[data-scroll-direction="horizontal"] [data-scroll-section] {
display: inline-block;
vertical-align: top;
white-space: nowrap;
height: 100%; }

.c-scrollbar {
position: absolute;
right: 0;
top: 0;
width: 11px;
height: 100%;
transform-origin: center right;
transition: transform 0.3s, opacity 0.3s;
opacity: 0; }
.c-scrollbar:hover {
transform: scaleX(1.45); }
.c-scrollbar:hover, .has-scroll-scrolling .c-scrollbar, .has-scroll-dragging .c-scrollbar {
opacity: 1; }
[data-scroll-direction="horizontal"] .c-scrollbar {
width: 100%;
height: 10px;
top: auto;
bottom: 0;
transform: scaleY(1); }
[data-scroll-direction="horizontal"] .c-scrollbar:hover {
transform: scaleY(1.3); }

.c-scrollbar_thumb {
position: absolute;
top: 0;
right: 0;
background-color: black;
opacity: 0.5;
width: 7px;
border-radius: 10px;
margin: 2px;
cursor: -webkit-grab;
cursor: grab; }
.has-scroll-dragging .c-scrollbar_thumb {
cursor: -webkit-grabbing;
cursor: grabbing; }
[data-scroll-direction="horizontal"] .c-scrollbar_thumb {
right: auto;
bottom: 0; }
43 changes: 43 additions & 0 deletions scroll/scollsample.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<link rel="stylesheet" href="locomotive-scroll.css" />
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/locomotive-scroll@beta/bundled/locomotive-scroll.min.js"></script>
<script>
(function () {
const locomotiveScroll = new LocomotiveScroll();
})();
</script>
<div style="height: 100vh"></div>
<main style="height: 150vh">
<div data-scroll >
<div>
<h1>Hello 👋</h1>
</div>
<div>
<h2>What's up?</h2>
<p>😬</p>
</div>
</div>
</main>

<script >
// import LocomotiveScroll from 'locomotive-scroll';

const scroll = new LocomotiveScroll();

scroll.on('call', (func) => {
// Using modularJS
this.call(...func);
// Using jQuery events
$(document).trigger(func);
// Or do it your own way 😎
});
</script>
</body>
</html>
155 changes: 155 additions & 0 deletions textAnimation/ActivitiesAnimationComponent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
// import {TweenMax, Power2, TimelineLite} from "gsap";
import { TweenMax, TimelineMax, Power2, Power1, TweenLite, Circ } from 'gsap/all';

class ActivitiesAnimationComponent {
constructor(options) {
console.log(options)
this.el = options.el;
this._setup();
this._setupEventListener();
}

_setup() {
this._ui = {
animationContainer: this.el.querySelector('.section-activites__content'),
imageAnimationContainer: this.el.querySelector('.section-activites__images-container'),
nextImageContainer: this.el.querySelector(".section-activites__next-image"),
currentImageContainer: this.el.querySelector(".section-activites__current-image"),
nextImage: this.el.querySelector(".section-activites__next-image .section-activites__image"),
currentImage: this.el.querySelector(".section-activites__current-image .section-activites__image"),
listActivities: this.el.querySelector(".section-activites__list"),
activity: this.el.querySelectorAll(".section-activites__list-item"),
activityLinks: this.el.querySelectorAll(".section-activites__list-item a"),
activityLinksSpan: this.el.querySelectorAll(".section-activites__list-item a span")

}
this.mouse = { x: 0, y: 0 };
this._setupTween();


}

_setupTween() {
this.timelineIntro = new TimelineMax({ paused: true, onComplete: () => { this._onCompleteIntro() } });
this.timelineIntro
.fromTo(this._ui.nextImageContainer, 1, { height: 0 }, { height: 500, ease: Power2.easeInOut }, 0)
.fromTo(this._ui.nextImage, 1.1, { autoAlpha: 0, scale: 1.3 }, { autoAlpha: 1, scale: 1, ease: Power1.easeOut }, 0)
}

_setupEventListener() {
this._ui.animationContainer.addEventListener('mousemove', () => this._mouseFollow());

for (let index = 0; index < this._ui.activity.length; index++) {
this._ui.activity[index].addEventListener('mouseenter', () => { this._mouseEnterFunction(index) });
}

this._ui.listActivities.addEventListener('mouseleave', () => this._leaveContainer());

}

_mouseEnterFunction(index) {
TweenMax.to(this._ui.imageAnimationContainer, .5, { autoAlpha: 1, ease: Power1.easeInOut });
if (this._ui.currentImage.src === "") {
this._firstImageAnimation(index);
} else {
this._imageAnimation(index);
this._textAnimation(index);
}
}

_textAnimation(index) {
let textBounds = this._ui.activityLinks[index].getBoundingClientRect();
let imageAnimationContainerBounds = this._ui.imageAnimationContainer.getBoundingClientRect();
this._ui.activityLinks[index].addEventListener('mousemove', () => {

let positionMouse = event.clientX - textBounds.left,
minPositionPath = positionMouse - imageAnimationContainerBounds.width / 2,
maxPositionPath = positionMouse + imageAnimationContainerBounds.width / 2;

TweenMax.to(this._ui.activityLinksSpan[index], 0.7, { webkitClipPath: `polygon(${minPositionPath}px 0, ${maxPositionPath}px 0, ${maxPositionPath}px 100%, ${minPositionPath}px 100%)`, ease: Power2.easeInCubic });
TweenMax.to(this._ui.activityLinksSpan[index], 0.7, { clipPath: `polygon(${minPositionPath}px 0, ${maxPositionPath}px 0, ${maxPositionPath}px 100%, ${minPositionPath}px 100%)`, ease: Power2.easeInCubic });

});
}

_firstImageAnimation(index) {
this._ui.currentImage.style.opacity = 0;
this._ui.nextImage.src = this._ui.activity[index].dataset.image;
this.currentImageLink = this._ui.activity[index].dataset.image;
this._ui.currentImage.src = this.currentImageLink;

this.timelineIntro.play();
}

_leaveContainer() {
TweenMax.to(this._ui.imageAnimationContainer, .5,
{
autoAlpha: 0,
onComplete: () => {
this._ui.currentImage.src = "";
this._ui.nextImage.src = "";
},
ease: Power1.easeInOut
}
);
}

_onCompleteIntro() {
this._ui.currentImage.src = this.currentImageLink;
this._ui.currentImage.style.opacity = 1
}

_onCompleteImageChange() {
this._ui.currentImage.src = this.currentImageLink
}

_imageAnimation(index) {
this.currentImageLink = this._ui.activity[index].dataset.image;
this._ui.nextImage.src = this._ui.activity[index].dataset.image;
TweenLite.fromTo(this._ui.nextImageContainer, 1, { height: 0, ease: Power2.easeInOut }, { height: 500, ease: Power2.easeInOut, onComplete: () => this._onCompleteImageChange() }, 0)
TweenLite.fromTo(this._ui.nextImage, 1.1, { scale: 1.3 }, { scale: 1, ease: Power1.easeOut }, 0)
}

_mouseFollow() {
let imageAnimationContainerBounds = this._ui.imageAnimationContainer.getBoundingClientRect();

this.mouse.x = event.clientX;
this.mouse.y = event.clientY - this.el.getBoundingClientRect().y;


TweenMax.to(this._ui.imageAnimationContainer, 0.7, { x: this.mouse.x - (imageAnimationContainerBounds.width / 2), y: this.mouse.y - (imageAnimationContainerBounds.height / 2), ease: Power2.easeInCubic })
}

}
// const instance = new ActivitiesAnimationComponent();
// instance._setup()
// export default ActivitiesAnimationComponent;


const COMPONENTS = {
'activities-animation': ActivitiesAnimationComponent
}

class ComponentFactory {
constructor() {
this._selector = 'data-component';
this._elements = document.querySelectorAll(`[${this._selector}]`);
this._components = {};
}

start() {
for (let i = 0, limit = this._elements.length; i < limit; i++) {
const element = this._elements[i];
const componentName = element.getAttribute(this._selector);
if (COMPONENTS[componentName]) {
const Component = COMPONENTS[componentName];
new Component({ el: element });
} else {
console.log(`Component: '${componentName}' not found`);
}
}
}
}

const instance = new ComponentFactory();
instance.start()
Loading

0 comments on commit 4e8567f

Please sign in to comment.