WebGL 액체 왜곡 이미지 호버 효과 - 세 부분 설정
10818 단어 tutorialwebdevjavascriptprogramming
시작하기
계속해서 CodePen playground을 사용하여 새 프로젝트를 초기화하거나 src 폴더 아래에 다음 파일 구조를 사용하여 Visual Studio Code에서 자신의 프로젝트를 설정하십시오.
WebGL Image Hover Master
|- Images
|- Image1.png
|- Image2.png
|- dist.png
|- Js
|- hover.js
|- script.js
|- /src
|- index.html
|- style.css
파트 1: HTML
index.html을 편집하여 시작하고 다음 코드로 바꿉니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-with, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="./style.css" />
<title>WebGl| Liquid Distortion Effect</title>
</head>
<body>
<div class="landing">
<div class="distortion"></div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js" integrity="sha256-lPE3wjN2a7ABWHbGz7+MKBJaykyzqCbU96BJWjio86U=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/106/three.min.js" integrity="sha256-tAVw6WRAXc3td2Esrjd28l54s3P2y7CDFu1271mu5LE=" crossorigin="anonymous"></script>
<script>!(function (f, l) {
"object" == typeof exports && "undefined" != typeof module
? (module.exports = l(require("three"), require("gsap/TweenMax")))
: "function" == typeof define && define.amd
? define(["three", "gsap/TweenMax"], l)
: (f.hoverEffect = l(f.THREE, f.TweenMax));
})(this, function (f, l) {
return (
(l = l && l.hasOwnProperty("default") ? l.default : l),
function (h) {
function F() {
for (var f = arguments, l = 0; l < arguments.length; l++)
if (void 0 !== f[l]) return f[l];
}
console.log(
"%c Hover effect by Robin Delaporte: https://github.com/robin-dela/hover-effect ",
"color: #bada55; font-size: 0.8rem"
);
var w = h.parent,
L = h.displacementImage,
M = h.image1,
P = h.image2,
U = F(h.intensity1, h.intensity, 1),
V = F(h.intensity2, h.intensity, 1),
C = F(h.angle, Math.PI / 4),
D = F(h.angle1, C),
S = F(h.angle2, 3 * -C),
W = F(h.speedIn, h.speed, 1.6),
_ = F(h.speedOut, h.speed, 1.2),
z = F(h.hover, !0),
q = F(h.easing, Expo.easeOut),
G = F(h.video, !1);
if (w)
if (M && P && L) {
var A = new f.Scene(),
B = new f.OrthographicCamera(
w.offsetWidth / -2,
w.offsetWidth / 2,
w.offsetHeight / 2,
w.offsetHeight / -2,
1,
1e3
);
B.position.z = 1;
var k = new f.WebGLRenderer({ antialias: !1, alpha: !0 });
k.setPixelRatio(window.devicePixelRatio),
k.setClearColor(16777215, 0),
k.setSize(w.offsetWidth, w.offsetHeight),
w.appendChild(k.domElement);
var J = function () {
k.render(A, B);
},
K = new f.TextureLoader();
K.crossOrigin = "";
var N = K.load(L, J);
if (((N.wrapS = N.wrapT = f.RepeatWrapping), G)) {
var Q = function () {
requestAnimationFrame(Q), k.render(A, B);
};
Q(),
((G = document.createElement("video")).autoplay = !0),
(G.loop = !0),
(G.src = M),
G.load();
var X = document.createElement("video");
(X.autoplay = !0), (X.loop = !0), (X.src = P), X.load();
var Y = new f.VideoTexture(G),
Z = new f.VideoTexture(X);
(Y.magFilter = Z.magFilter = f.LinearFilter),
(Y.minFilter = Z.minFilter = f.LinearFilter),
X.addEventListener(
"loadeddata",
function () {
X.play(),
((Z = new f.VideoTexture(X)).magFilter = f.LinearFilter),
(Z.minFilter = f.LinearFilter),
($.uniforms.texture2.value = Z);
},
!1
),
G.addEventListener(
"loadeddata",
function () {
G.play(),
((Y = new f.VideoTexture(G)).magFilter = f.LinearFilter),
(Y.minFilter = f.LinearFilter),
($.uniforms.texture1.value = Y);
},
!1
);
} else
(Y = K.load(M, J)),
(Z = K.load(P, J)),
(Y.magFilter = Z.magFilter = f.LinearFilter),
(Y.minFilter = Z.minFilter = f.LinearFilter);
var $ = new f.ShaderMaterial({
uniforms: {
intensity1: { type: "f", value: U },
intensity2: { type: "f", value: V },
dispFactor: { type: "f", value: 0 },
angle1: { type: "f", value: D },
angle2: { type: "f", value: S },
texture1: { type: "t", value: Y },
texture2: { type: "t", value: Z },
disp: { type: "t", value: N },
},
vertexShader:
"\nvarying vec2 vUv;\nvoid main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}\n",
fragmentShader:
"\nvarying vec2 vUv;\n\nuniform float dispFactor;\nuniform sampler2D disp;\n\nuniform sampler2D texture1;\nuniform sampler2D texture2;\nuniform float angle1;\nuniform float angle2;\nuniform float intensity1;\nuniform float intensity2;\n\nmat2 getRotM(float angle) {\n float s = sin(angle);\n float c = cos(angle);\n return mat2(c, -s, s, c);\n}\n\nvoid main() {\n vec4 disp = texture2D(disp, vUv);\n vec2 dispVec = vec2(disp.r, disp.g);\n vec2 distortedPosition1 = vUv + getRotM(angle1) * dispVec * intensity1 * dispFactor;\n vec2 distortedPosition2 = vUv + getRotM(angle2) * dispVec * intensity2 * (1.0 - dispFactor);\n vec4 _texture1 = texture2D(texture1, distortedPosition1);\n vec4 _texture2 = texture2D(texture2, distortedPosition2);\n gl_FragColor = mix(_texture1, _texture2, dispFactor);\n}\n",
transparent: !0,
opacity: 1,
}),
y = new f.PlaneBufferGeometry(w.offsetWidth, w.offsetHeight, 1),
b = new f.Mesh(y, $);
A.add(b),
z &&
(w.addEventListener("mouseenter", j),
w.addEventListener("touchstart", j),
w.addEventListener("mouseleave", O),
w.addEventListener("touchend", O)),
window.addEventListener("resize", function (f) {
k.setSize(w.offsetWidth, w.offsetHeight);
}),
(this.next = j),
(this.previous = O);
} else console.warn("One or more images are missing");
else console.warn("Parent missing");
function j() {
l.to($.uniforms.dispFactor, W, {
value: 1,
ease: q,
onUpdate: J,
onComplete: J,
});
}
function O() {
l.to($.uniforms.dispFactor, _, {
value: 0,
ease: q,
onUpdate: J,
onComplete: J,
});
}
}
);
});
//# sourceMappingURL=hover-effect.umd.js.map
</script>
<script src="./script.js"></script>
</body>
</html>
파트 2: CSS
다음 단계는 다음 스타일을 추가하고 style.css 파일을 완성하는 것입니다. 캔버스를 감싸는 div가 문서에 맞는지 확인하고 평면 div 요소에 원하는 크기를 적용하십시오.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
background: white;
}
.landing {
display: flex;
align-items: center;
justify-content: center;
width: 50%;
height: 50vh;
box-shadow: 0 32px 32px -8px rgba(0, 0, 0, 0.5);
}
.distortion {
position: fixed;
width: 50vw;
height: 50vh;
}
파트 3: 자바스크립트
이제 우리는 JavaScript 로직을 ThreeJS 설정에 구현할 수 있습니다.
new hoverEffect({
parent: document.querySelector('.distortion'),
intensity: 0.2,
image1: 'https://images.unsplash.com/photo-1608501078713-8e445a709b39?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8d2FsbHBhcGVyJTIwNGt8ZW58MHx8MHx8&auto=format&fit=crop&w=600&q=60',
image2: 'https://images.unsplash.com/photo-1580617971627-cffa74e39d1d?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwcm9maWxlLXBhZ2V8OTR8fHxlbnwwfHx8fA%3D%3D&auto=format&fit=crop&w=600&q=60',
speedIn: 2,
speedOut: 5,
angle1 : Math.PI / 6,
angle2 : -Math.PI / 6 * 3,
displacementImage: 'https://i.postimg.cc/QNTRDRks/4.png',
//displacementImage: 'https://i.ibb.co/tbSbc6k/clouds.jpg',
});
시원한! 이제 저장하면 브라우저에 표시됩니다.
요약
따라했다면 프로젝트를 완료하고 액체 왜곡 효과를 마무리했을 것입니다.
이제 여기까지 했다면 코드를 내Sandbox에 연결하여 포크하거나 복제하면 작업이 완료됩니다.
라이선스: 📝
이 프로젝트는 MIT 라이선스(MIT)에 따릅니다. 자세한 내용은 라이센스를 참조하십시오.
기여
기여는 언제나 환영합니다...
🔹 저장소 포크
🔹 현재 프로그램 개선
🔹 기능 개선
🔹 새로운 기능 추가
🔹 버그 수정
🔹 작업 푸시 및 풀 리퀘스트 생성
유용한 리소스
https://cdnjs.com/libraries/three.js/
https://cdnjs.com/libraries/gsap
Reference
이 문제에 관하여(WebGL 액체 왜곡 이미지 호버 효과 - 세 부분 설정), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/hr21don/webgl-liquid-distortion-image-hover-effect-three-part-setup-5640텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)