Анимация JavaScript
Есть анимация
window.onload = function() {
// track the mouse positions to send it to the shaders
var mousePosition = {
x: 0,
y: 0,
};
// pass the id of the div that will wrap the canvas to set up our WebGL context and append the canvas to our wrapper
var webGLCurtain = new Curtains({
container: "canvas"
});
// get our plane element
var planeElement = document.getElementsByClassName("plane")[0];
// set our initial parameters (basic uniforms)
var params = {
vertexShaderID: "plane-vs", // our vertex shader ID
fragmentShaderID: "plane-fs", // our framgent shader ID
widthSegments: 20,
heightSegments: 20, // we now have 20*20*6 = 2400 vertices !
uniforms: {
time: {
name: "uTime", // uniform name that will be passed to our shaders
type: "1f", // this means our uniform is a float
value: 0,
},
mousePosition: { // our mouse position
name: "uMousePosition",
type: "2f", // notice this is a length 2 array of floats
value: [mousePosition.x, mousePosition.y],
},
mouseStrength: { // the strength of the effect (we will attenuate it if the mouse stops moving)
name: "uMouseStrength", // uniform name that will be passed to our shaders
type: "1f", // this means our uniform is a float
value: 0,
},
}
}
// create our plane mesh
var plane = webGLCurtain.addPlane(planeElement, params);
// if our plane has been successfully created we could start listening to mouse/touch events and update its uniforms
plane && plane.onReady(function() {
// set a field of view of 35 to exagerate perspective
// we could have done it directly in the initial params
plane.setPerspective(0);
// listen our mouse/touch events on the whole document
// we will pass the plane as second argument of our function
// we could be handling multiple planes that way
document.body.addEventListener("mousemove", function(e) {
handleMovement(e, plane);
});
document.body.addEventListener("touchmove", function(e) {
handleMovement(e, plane);
});
}).onRender(function() {
// update our time uniform value
plane.uniforms.time.value++;
// continually decrease mouse strength
plane.uniforms.mouseStrength.value = Math.max(0.1, plane.uniforms.mouseStrength.value - .7075);
});
// handle the mouse move event
function handleMovement(e, plane) {
// touch event
if(e.targetTouches) {
mousePosition.x = e.targetTouches[0].clientX;
mousePosition.y = e.targetTouches[0].clientY;
}
// mouse event
else {
mousePosition.x = e.clientX;
mousePosition.y = e.clientY;
}
// convert our mouse/touch position to coordinates relative to the vertices of the plane
var mouseCoords = plane.mouseToPlaneCoords(mousePosition.x, mousePosition.y);
// update our mouse position uniform
plane.uniforms.mousePosition.value = [mouseCoords.x, mouseCoords.y];
// reassign mouse strength
plane.uniforms.mouseStrength.value = 1;
}
}
#canvas {
/* make the canvas wrapper fits the window */
height: 100vh;
width: 100%;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
overflow: hidden;
}
.plane {
/* define the size of your plane */
width: 100%;
height: 100vh;
position: absolute;
top: 0;
left: 0;
}
.plane img {
width: 100%;
display: block;
background-size: cover;
opacity: 0;
position: absolute;
}
body {
margin: 0;
font-family: "Sporting Grotesque_Bold", sans-serif;
background-color: #000;
min-width: 1200px;
position: relative;
width: 100%;
height: 100vh;
/* hide scrollbars */
overflow: hidden;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/parallax/3.1.0/parallax.min.js"></script>
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<div id="canvas" ></div>
<!-- div used to create our plane -->
<div class="plane">
<!-- image that will be used as a texture by our plane -->
<img src="https://www.martin-laxenaire.fr/csstricks/images/second-example-texture.jpg" crossorigin="anonymous" />
</div>
<script id="plane-vs" type="x-shader/x-vertex">
#ifdef GL_ES
precision mediump float;
#endif
// those are the mandatory attributes that the lib sets
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord;
// those are mandatory uniforms that the lib sets and that contain our model view and projection matrix
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
// our texture matrix uniform (this is the lib default name, but it could be changed)
uniform mat4 uTextureMatrix0;
// our time uniform
uniform float uTime;
// our mouse position uniform
uniform vec2 uMousePosition;
// our mouse strength
uniform float uMouseStrength;
// if you want to pass your vertex and texture coords to the fragment shader
varying vec3 vVertexPosition;
varying vec2 vTextureCoord;
void main() {
vec3 vertexPosition = aVertexPosition;
// get the distance between our vertex and the mouse position
float distanceFromMouse = distance(uMousePosition, vec2(vertexPosition.x, vertexPosition.y));
// this will define how close the ripples will be from each other. The bigger the number, the more ripples you'll get
float rippleFactor = 6.0;
// calculate our ripple effect
float rippleEffect = cos(rippleFactor * (distanceFromMouse - (uTime / 120.0)));
// calculate our distortion effect
float distortionEffect = rippleEffect * uMouseStrength;
// apply it to our vertex position
vertexPosition += distortionEffect / 30.0;
gl_Position = uPMatrix * uMVMatrix * vec4(vertexPosition, 1.0);
// varyings
// thanks to the texture matrix we will be able to calculate accurate texture coords
// so that our texture will always fit our plane without being distorted
vTextureCoord = (uTextureMatrix0 * vec4(aTextureCoord, 0.0, 1.0)).xy;
vVertexPosition = vertexPosition;
}
</script>
<script id="plane-fs" type="x-shader/x-fragment">
#ifdef GL_ES
precision mediump float;
#endif
// get our varyings
varying vec3 vVertexPosition;
varying vec2 vTextureCoord;
// our texture sampler (this is the lib default name, but it could be changed)
uniform sampler2D uSampler0;
void main() {
// get our texture coords
vec2 textureCoords = vTextureCoord;
// apply our texture
vec4 finalColor = texture2D(uSampler0, textureCoords);
// fake shadows based on vertex position along Z axis
finalColor.rgb -= clamp(-vVertexPosition.z, 0.0, 1.0);
// fake lights based on vertex position along Z axis
finalColor.rgb += clamp(vVertexPosition.z, 0.0, 1.0);
// handling premultiplied alpha (useful if we were using a png with transparency)
finalColor = vec4(finalColor.rgb * finalColor.a, finalColor.a);
gl_FragColor = finalColor;
}
</script>
<script src="script.js"></script>
<script src="https://www.curtainsjs.com/build/curtains.min.js" type="text/javascript"></script>
</body>
</html>
Как сделать так, чтобы боковые и верхняя, нижняя сторона не двигались? Пример - https://unitk.ai/ Может как-то скрыть при увеличении или есть другие варианты?
Ответы (1 шт):
Автор решения: tomato-magnet-regulato
→ Ссылка
.plane {
/* define the size of your plane */
width: 120%;
height: 120vh;
position: absolute;
top: -10vh;
left: -10vh;
}
Костылек конечно, но идея в том чтобы расширить картинку за видимость страницы и разместить +- в центре. На верный ответ не претендую, так чисто идея.