Animieren Sie Bilder und Videos mit curtains.js

0
10

Beim durchstöbern der neuesten preisgekrönten websites, können Sie feststellen, eine Menge Phantasie Bildverzerrungen, Animationen, nette 3D-Effekte. Die meisten von Ihnen werden erstellt, mit WebGL, eine API ermöglicht GPU-beschleunigte Bild-processing-Effekte und Animationen. Sie neigen auch dazu zu verwenden, – Bibliotheken basiert auf der WebGL-wie three.js oder pixi.js. Beide sind sehr mächtige Werkzeuge zum erstellen beziehungsweise 2D-und 3D-Szenen.

Aber Sie sollten im Hinterkopf behalten, dass diejenigen Bibliotheken, die nicht ursprünglich entwickelt wurden, um Diashows zu erstellen oder zu animieren DOM-Elemente. Es gibt eine Bibliothek entwickelt, die nur für diese, aber, und wir sind in Deckung zu gehen, wie zu verwenden es hier in diesem Beitrag.

WebGL, CSS-Positionierung und Reaktionsfähigkeit

Sagen, Sie arbeiten mit einer Bibliothek, wie three.js oder pixi.js und Sie wollen es verwenden, um die Erstellung von Interaktionen, wie mouseover-und scroll-Ereignisse auf Elemente. Sie vielleicht in Schwierigkeiten! Wie Sie position Ihre WebGL-Elemente relativ zu dem Dokument und anderen DOM-Elemente? Wie handhaben würde, Reaktionsfähigkeit?

Das ist genau das, was ich im Sinn hatte, als die Schaffung curtains.js.

Curatins.js ermöglicht Ihnen das erstellen von Ebenen mit Fotos und videos in WebGL-wir nennen Sie Texturen), die wirken wie einfache HTML-Elemente, die mit position und Größe definiert werden, die durch CSS-Regeln. Aber diese Flächen können erhöht werden, mit den unendlichen Möglichkeiten von WebGL und Shader.

Warten, Shader?

Shader sind kleine Programme, geschrieben in GLSL, die sagen, Ihre GPU Rendern kann, Ihre Flugzeuge. Zu wissen, wie Shader-Arbeit ist obligatorisch, denn dies ist hier, wie wir mit Animationen. Wenn Sie noch nie von Ihnen gehört, möchten Sie vielleicht lernen Sie zuerst die Grundlagen. Es gibt viele gute websites, die mit dem lernen zu beginnen, wie Das Buch von Shadern.

Nun, dass Sie auf die Idee kommen, erstellen wir unser erstes Flugzeug!

Aufbau einer grundlegenden Ebene

Anzeigen unsere erste Flugzeug, wir müssen ein wenig HTML -, CSS-und JavaScript-erstellen der Ebene. Dann ist unser Shader animieren.

HTML

Der HTML-Code wirklich einfach hier. Erstellen wir einen <div>, das halten wird, ist unsere Leinwand, und ein div-Element, das unser Bild.

<body>
<!– div, halten unsere WebGL-canvas –>
<div id=”canvas”></div>

<!– div erstellen unser Flugzeug –>
<div class=”Ebene”>

<!– Bild, das verwendet wird, als eine textur, die von unserem Flugzeug –>
<img src=”path/to/my-image.jpg” />

</div>

</body>
CSS

Wir verwenden CSS, um sicherzustellen, dass die <div> – Element umschließt, die Leinwand wird größer sein, als unser Flugzeug, und wenden Sie eine beliebige Größe auf die Ebene div. (Unsere WebGL Ebene haben genau die gleiche Größe und die Positionen dieser div.)

body {
/* stellen Sie den Körper passen unsere viewport */
position: relative;
width: 100%;
height: 100vh;
margin: 0;

/* ausblenden von Bildlaufleisten */
overflow: hidden;
}

#canvas {
/* stellen Sie die Leinwand wrapper Passform des Dokuments */
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.Flugzeug {
/* definieren Sie die Größe Ihrer Ebene */
width: 80%;
max-width: 1400px;
Höhe: 80vh;
position: relative;
top: 10vh;
margin: 0 auto;
}

.Flugzeug img {
/* ausblenden des img-Elements */
display: none;
}
JavaScript

Es ist ein bisschen mehr Arbeit in das JavaScript. Wir müssen instanziieren unsere WebGL-Kontext, erstellen Sie eine Ebene mit einheitlichen Parametern, und verwenden Sie es.

Fenster.onload = function() {
// übergeben Sie die id des div, wickeln Sie die Leinwand, bis wir unsere WebGL-Kontext und fügen die canvas-Bereich, um unsere wrapper
var webGLCurtain = neue Vorhänge(“canvas”);

// Holen Sie sich unsere Flugzeug-element
var planeElement = document.getElementsByClassName(“Flugzeug”)[0];

// unsere erste Parameter (basic Uniformen)
var params = {
vertexShaderID: “Flugzeug-vs”, // unser vertex-shader ID
fragmentShaderID: “Flugzeug-fs”, // unsere framgent shader ID
Uniformen: {
Zeit: {
name: “uTime”, // uniform-name übergeben wird, um unsere Shader
Typ: “1f”, // das bedeutet, dass unsere uniform ist ein float
Wert: 0,
},
}
}

// erstellen unsere mesh-plane
var Ebene = webGLCurtain.addPlane(planeElement, params);

// verwenden Sie die onRender-Methode der unser Flugzeug feuerte auf jeden requestAnimationFrame nennen
Flugzeug.onRender(function() {
Flugzeug.Uniformen.Zeit.Wert++; // aktualisieren unsere Zeit einheitlicher Wert
});

}
Shader

Wir müssen schreiben die vertex-shader. Es wird nicht viel tun, außer position unser Flugzeug basiert auf dem model-view-und projection-matrix und pass varyings an den Fragmentshader:

<!– vertex shader –>
<script id=”Flugzeug-vs” type=”x-shader/x-vertex”>
#ifdef GL_ES
Präzision mediump float;
#endif

// das sind die obligatorischen Attribute, die lib-sets
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord;

// sind diese verbindlich Uniformen, dass die lib-sets und enthalten unsere model-view-und projection-matrix
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;

// wenn Sie möchten, übergeben Sie Ihre vertex-und textur-Koordinaten in den fragment shader
varying vec3 vVertexPosition;
varying vec2 vTextureCoord;

void main() {
// die vertex-position von seinem Attribut
vec3 vertexPosition = aVertexPosition;
// legen Sie seine position auf der Projektions-und model-view-matrix
gl_Position = uPMatrix * uMVMatrix * vec4(vertexPosition, 1.0);

// legen Sie die varyings
vTextureCoord = aTextureCoord;
vVertexPosition = vertexPosition;
}
</script>

Nun unser fragment shader. Dies ist, wo wir fügen Sie ein wenig displacement-Effekt basierend auf unsere Zeit, die uniform und die textur-Koordinaten.

<!– fragment-shader –>
<script id=”Flugzeug-fs” type=”x-shader/x-fragment”>
#ifdef GL_ES
Präzision mediump float;
#endif

// Holen Sie sich unsere varyings
varying vec3 vVertexPosition;
varying vec2 vTextureCoord;

// der einheitliche erklärten wir in unserem javascript
uniform float uTime;

// unsere textur-sampler (das ist der Standard-lib-Namen, aber es könnte geändert werden)
uniform sampler2D uSampler0;

void main() {
// unsere textur coords
vec2 textureCoord = vTextureCoord;

// verdrängen unsere Pixel entlang der beiden Achsen, basierend auf einheitlichen und textur UVs
// dies erstellt eine Art von Wasser-Oberflächen-Effekt
// versuchen, den Kommentar zu einer Linie oder ändern Sie die Konstanten zu sehen, wie es ändert die Wirkung
// Erinnerung : Texturen coords sind im Bereich von 0,0 bis 1,0 auf beiden Achsen
const float PI = 3.141592;

textureCoord.x += (
sin(textureCoord.x * 10.0 + ((uTime * (PI / 3.0)) * 0.031))
+ sin(textureCoord.y * 10.0 + ((uTime * (PI / 2.489)) * 0.017))
) * 0,0075 notiert wird;

textureCoord.y += (
sin(textureCoord.y * 20.0 + ((uTime * (PI / 2.023)) * 0.023))
+ sin(textureCoord.x * 20.0 + ((uTime * (PI / 3.1254)) * 0.037))
) * 0.0125;

gl_FragColor = texture2D(uSampler0, textureCoord);
}
</script>

Et voilà! Sie sind fertig, und wenn alles gut ging, sollten Sie eine Seite wie diese sehen.

Siehe Stift curtains.js grundlegende Flugzeug von Martin Laxenaire (@martinlaxenaire) auf CodePen.

Hinzufügen von 3D und Interaktionen

Okay, das ist ziemlich cool bisher, aber wir haben diese post im Gespräch über 3D und Interaktionen, so lassen Sie uns schauen, wie wir könnten, fügen Sie diese in.

Über Eckpunkte

Hinzufügen, um einen 3D-Effekt wir ändern müssen das Flugzeug Eckpunkte position innerhalb der vertex-shader. Aber in unserem ersten Beispiel, werden wir nicht angeben, wie viele Eckpunkte unserer Ebene haben sollten, also es wurde mit einem Standard-geometrie mit sechs Eckpunkte bilden zwei Dreiecke :

Um anständige 3D-Animationen, wir müssten mehr Dreiecke, also mehrere Eckpunkte:

Dieses Flugzeug hat fünf Segmente entlang seiner Breite und fünf Segmente entlang der Höhe. Als Ergebnis haben wir 50 Dreiecke und insgesamt 150 Punkten.

Die Umgestaltung unserer JavaScript

Zum Glück ist es leicht zu spezifizieren unsere Flugzeug-definition festgelegt werden konnte, der in unserem ursprünglichen Parameter.

Wir sind auch zu hören auf Maus-position um ein bisschen Interaktion. Um es richtig zu tun, wir müssen warten, bis das Flugzeug bereit zu sein, wandeln unsere Maus Dokument-Koordinaten auf unserer WebGL-clip-space Koordinaten und senden Sie Sie an den Shader als uniform.

// wir sind mit Fenster onload-Ereignis hier, aber das ist nicht zwingend
Fenster.onload = function() {
// verfolgen Sie die Maus-Positionen, senden Sie es an den Shadern
var mousePosition = {
x: 0,
y: 0,
};

// übergeben Sie die id des div, wickeln Sie die Leinwand, bis wir unsere WebGL-Kontext und fügen die canvas-Bereich, um unsere wrapper
var webGLCurtain = neue Vorhänge(“canvas”);

// Holen Sie sich unsere Flugzeug-element
var planeElement = document.getElementsByClassName(“Flugzeug”)[0];

// unsere erste Parameter (basic Uniformen)
var params = {
vertexShaderID: “Flugzeug-vs”, // unser vertex-shader ID
fragmentShaderID: “Flugzeug-fs”, // unsere framgent shader ID
widthSegments: 20,
heightSegments: 20, // wir haben jetzt 20*20*6 = 2400 Eckpunkte !
Uniformen: {
Zeit: {
name: “uTime”, // uniform-name übergeben wird, um unsere Shader
Typ: “1f”, // das bedeutet, dass unsere uniform ist ein float
Wert: 0,
},
mousePosition: { // unsere Maus position
name: “uMousePosition”,
Typ: “2f”, // Achtung: dies ist eine Länge von 2-array von floats
Wert: [mousePosition.x, mousePosition.y],
},
mouseStrength: { // die Stärke des Effekts (wir werden dämpfen, wenn die Maus nicht mehr bewegen)
name: “uMouseStrength”, // uniform-name übergeben wird, um unsere Shader
Typ: “1f”, // das bedeutet, dass unsere uniform ist ein float
Wert: 0,
},

}
}

// erstellen unsere mesh-plane
var Ebene = webGLCurtain.addPlane(planeElement, params);

// sobald unser Flugzeug fertig ist, könnten wir beginnen, hören Maus/touch-events, und aktualisieren Sie Ihre Uniformen
Flugzeug.onReady(function() {
// setze ein Sichtfeld von 35 bis exagerate Perspektive
// wir hätten es direkt in der ersten params
Flugzeug.setPerspective(35);
// listen unserer Maus/touch-events auf das gesamte Dokument
// wir übergeben der Ebene, als zweites argument an die Funktion
// wir könnten Umgang mit mehreren Ebenen, dass die Art und Weise
Dokument.Körper.addEventListener(“mousemove”, function(e) {
handleMovement(e, Ebene);
});
Dokument.Körper.addEventListener(“touchmove”, function(e) {
handleMovement(e, Ebene);
});
}).onRender(function() {
// update unserer Zeit einheitlicher Wert
Flugzeug.Uniformen.Zeit.Wert++;
// kontinuierlich verringern Maus-Stärke
Flugzeug.Uniformen.mouseStrength.Wert = Math.max(0, Ebene.Uniformen.mouseStrength.Wert – 0,0075 notiert wird);
});

// behandeln der mouse-move-Ereignis
function handleMovement(e, Ebene) {
// touch event
if (- e.targetTouches) {
mousePosition.x = e ist.targetTouches[0].clientX;
mousePosition.y = e ist.targetTouches[0].clientY;
}
// Maus-event
else {
mousePosition.x = e ist.clientX;
mousePosition.y = e ist.clientY;
}
// konvertieren der Maus/touch-position auf die Koordinaten relativ zu den Eckpunkten der Ebene
var mouseCoords = Flugzeug.mouseToPlaneCoords(mousePosition.x, mousePosition.y);
// update unserer Maus position uniform
Flugzeug.Uniformen.mousePosition.Wert = [mouseCoords.x, mouseCoords.y];

// zuweisen Maus-Stärke
Flugzeug.Uniformen.mouseStrength.Wert = 1;
}

}

Nun, dass unser JavaScript-Code fertig ist, haben wir umschreiben unseren Shader, so dass Sie dann verwenden Sie unsere Maus position uniform.

Die Umgestaltung der Shader

Let ‘ s Blick auf unsere vertex-shader-ersten. Wir haben drei Uniformen, die wir nutzen könnten für unseren Effekt:

  1. die Zeit, die stetig steigt
  2. die Maus-position
  3. unsere Maus Kraft, die stetig abnimmt, bis die nächste Maus bewegen

Wir werden alle drei von Ihnen zu erstellen, eine Art von 3D-Wellen-Effekt.

<script id=”Flugzeug-vs” type=”x-shader/x-vertex”>
#ifdef GL_ES
Präzision mediump float;
#endif

// das sind die obligatorischen Attribute, die lib-sets
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord;

// sind diese verbindlich Uniformen, dass die lib-sets und enthalten unsere model-view-und projection-matrix
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;

// unsere Zeit-uniform
uniform float uTime;

// unsere Maus position uniform
uniform vec2 uMousePosition;

// unsere Maus Stärke
uniform float uMouseStrength;

// wenn Sie möchten, übergeben Sie Ihre vertex-und textur-Koordinaten in den fragment shader
varying vec3 vVertexPosition;
varying vec2 vTextureCoord;

void main() {
vec3 vertexPosition = aVertexPosition;

// um den Abstand zwischen unseren vertex-und die Maus-position
float distanceFromMouse = Abstand(uMousePosition, vec2(vertexPosition.x, vertexPosition.y));

// hier wird definiert, wie nah die Wellen werden von einander. Je größer die Zahl, desto mehr Wellen bekommen Sie
float rippleFactor = 6.0;

// berechnen unsere ripple-Effekt
float rippleEffect = cos(rippleFactor * (distanceFromMouse – (uTime / 120.0)));

// berechnen unsere distortion-Effekt
float distortionEffect = rippleEffect * uMouseStrength;

// es gelten unsere vertex-position
vertexPosition += distortionEffect / 15.0;

gl_Position = uPMatrix * uMVMatrix * vec4(vertexPosition, 1.0);

// varyings
vTextureCoord = aTextureCoord;
vVertexPosition = vertexPosition;
}
</script>

Für den fragment-shader, den wir gehen um es einfach zu halten. Wir werden die fake-Lichter und Schatten basierend auf den einzelnen vertex-position:

<script id=”Flugzeug-fs” type=”x-shader/x-fragment”>
#ifdef GL_ES
Präzision mediump float;
#endif

// Holen Sie sich unsere varyings
varying vec3 vVertexPosition;
varying vec2 vTextureCoord;

// unsere textur-sampler (das ist der Standard-lib-Namen, aber es könnte geändert werden)
uniform sampler2D uSampler0;

void main() {
// unsere textur coords
vec2 textureCoords = vTextureCoord;

// unsere textur
vec4 finalColor = texture2D(uSampler0, textureCoords);

// fake-Schatten basierend auf vertex-position entlang der Z-Achse
finalColor.rgb -= clamp(-vVertexPosition.z, 0.0, 1.0);

// fake-Lichter basierend auf vertex-position entlang der Z-Achse
finalColor.rgb += clamp(vVertexPosition.z, 0.0, 1.0);

// Umgang mit vormultiplizierten alpha (nützlich, wenn eine png mit Transparenz)
finalColor = vec4(finalColor.rgb * finalColor.ein, finalColor.a);

gl_FragColor = finalColor;
}
</script>

Und dort gehen Sie!

Siehe Stift curtains.js ripple-Effekt Beispiel von Martin Laxenaire (@martinlaxenaire) auf CodePen.

Mit diesen zwei einfachen Beispielen, die wir gesehen haben, wie um eine Schnittebene zu erstellen und mit Ihr zu interagieren.

Videos und displacement-Shader

Unser letztes Beispiel wird das erstellen einer einfachen Vollbild-video-slideshow mit einer Verschiebungs-shader zur Verbesserung der übergänge.

Displacement-shader-Konzept

Der displacement-shader erstellen eine schöne distortion-Effekt. Es wird geschrieben, der in unserem fragment-shader mit einem Graustufen-Bild und ausgeglichen die pixel-Koordinaten des videos auf die textur RGB-Werte. Hier ist das Bild, das wir verwenden werden:

Der Effekt wird berechnet, basierend auf den einzelnen pixel-RGB-Wert, mit einem schwarzen pixels [0, 0, 0] und ein weißer pixel [1, 1, 1] (GLSL äquivalent für [255, 255, 255]). Zu vereinfachen, nutzen wir nur den roten Kanal mit dem Wert, als mit einem Graustufen-Bild rot, grün und blau sind immer gleich.

Sie können versuchen, zu erstellen Ihre eigenen Graustufen-Bild (er arbeitet hervorragend mit der geometrischen Form ), um Ihre einzigartige übergangseffekte.

Mehrere Texturen und videos

Ein Flugzeug kann mehr als eine textur, indem Sie einfach mehrere image-tags. Dieses mal, statt der Bilder, die wir verwenden wollen videos. Wir müssen nur ersetzen Sie das <img / > – tags mit einem <video /> ein. Allerdings gibt es zwei Dinge zu wissen, wenn es um video:

  • Das video wird immer passen die genaue Größe der Fläche, was bedeutet, dass Ihr Flugzeug hat die gleiche Breite/Höhe-Verhältnis als video. Dies ist keine große Sache, tho, denn es ist leicht zu handhaben mit CSS.
  • Auf mobilen Geräten können wir nicht die autoplay-videos ohne eine Benutzeraktion, wie ein click-Ereignis. Es ist daher sicherer, fügen Sie eine “enter-site” – Taste, um die Anzeige und starten unsere videos.

HTML

Das HTML ist immer noch ziemlich einfach. Wir erstellen unsere Leinwand div wrapper, unser Flugzeug div mit den Texturen und eine Taste zum auslösen der video-autoplay. Nur beachten Sie die Verwendung der Daten-sampler-Attribut des image-und video-tags—es wird nützlich sein, in unserem fragment-shader.

<body>
<div id=”canvas”></div>
<!– das div um die Vollbild-video-Größen und-Positionen –>
<div class=”Flugzeug-wrapper”>
<div class=”Ebene”>
<!– beachten Sie hier, wir sind mit dem Daten-sampler Attribut name unserer sampler-Uniformen –>
<img src=”path/to/displacement.jpg” Daten-sampler=”Hubraum” />
<video src=”Pfad/zum/video.mp4″ data-sampler=”firstTexture”></video>
<video src=”Pfad/zu/video-2.mp4″ data-sampler=”secondTexture”></video>
</div>
</div>

<div id=”enter-site-wrapper”>
<span id=”enter-site”>
Click to enter Website
</span>
</div>
</body>
CSS

Der stylesheet Griff ein paar Dinge: – Anzeige der Taste und blenden Sie die Leinwand, bevor der Benutzer eingegeben hat, der Standort, die Größe und die position unser Flugzeug-wrapper-div zu behandeln fullscreen responsive videos.

@media screen {

body {
margin: 0;
font-size: 18px;
font-family: ‘PT Sans’, Verdana, sans-serif;
background: #212121;
line-height: 1.4;
height: 100vh;
Breite: 100vw;
overflow: hidden;
}

/*** canvas ***/

#canvas {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 10;

/* ausblenden der Leinwand, bis der Benutzer auf die Schaltfläche klickt */
Deckkraft: 0;
übergang: Opazität 0,5 s Leichtigkeit-in;
}

/* Anzeige der Leinwand */
.video-fing #canvas {
opacity: 1;
}

.Flugzeug-wrapper {
position: absolute;

/* center unser Flugzeug wrapper */
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 15;
}

.Flugzeug {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;

/* den Benutzer informiert, er kann auf der Ebene */
cursor: pointer;
}

/* ausblenden das ursprüngliche Bild und videos */
.Flugzeug-img .Flugzeug video – {
display: none;
}

/* zentrieren Sie die Taste */
#enter-site-wrapper {
display: flex;
justify-content: center;
align-items: center;
align-content: center;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 30;

/* ausblenden der Schaltfläche, bis alles fertig ist */
Deckkraft: 0;
übergang: Opazität 0,5 s Leichtigkeit-in;
}

/* die Taste */
.Vorhänge-fertig #eingeben-Ort-wrapper {
opacity: 1;
}

/* ausblenden der button nach dem klicken auf event */
.Vorhänge-fertig.video-fing #eingeben-Ort-wrapper {
Deckkraft: 0;
pointer-events: none;
}

#enter-site {
padding: 20px;
Farbe: weiß;
background: #ee6557;
max-width: 200px;
text-align: center;
cursor: pointer;
}

}

/* Vollbild-video-responsive */
@media screen and (max-aspect-ratio: 1920/1080) {
.Flugzeug-wrapper {
height: 100vh;
Breite: 177vh;
}
}

@media screen and (min-aspect-ratio: 1920/1080) {
.Flugzeug-wrapper {
Breite: 100vw;
Höhe: der 56,25 vw;
}
}
JavaScript

Für das JavaScript, wir gehen wie folgt:

  • Legen Sie ein paar Variablen zum speichern unserer slideshow Zustand
  • Erstellen Sie die Vorhänge Objekt, und fügen Sie die Ebene, um es
  • Wenn das Flugzeug fertig ist, hören Sie ein Klick-Ereignis auf unsere videos-Wiedergabe (beachten Sie die Verwendung der playVideos () – Methode). Fügen Sie ein weiteres click-Ereignis zum Umschalten zwischen den beiden videos.
  • Update unser übergang timer uniform innerhalb der onRender () – Methode

Fenster.onload = function() {

// hier kümmern wir uns um die textur ist sichtbar, und der timer für den übergang zwischen den Bildern
var activeTexture = 1;
var transitionTimer = 0;

// Aufbau der WebGL-Kontext und fügen die canvas-Bereich, um unsere wrapper
var webGLCurtain = neue Vorhänge(“canvas”);

// Holen Sie sich unsere Flugzeug-element
var planeElements = document.getElementsByClassName(“Flugzeug”);

// einige grundlegende Parameter
var params = {
vertexShaderID: “Flugzeug-vs”,
fragmentShaderID: “Flugzeug-fs”,
imageCover: false, // unsere displacement-textur passen muss das Flugzeug
Uniformen: {
transitionTimer: {
name: “uTransitionTimer”,
Typ: “1f”,
Wert: 0,
},
},
}

var Ebene = webGLCurtain.addPlane(planeElements[0], params);

// erstellen unser Flugzeug
Flugzeug.onReady(function() {
// Anzeige der Taste
Dokument.Körper.classList.add(“Vorhänge-fertig”);

// wenn unser Flugzeug bereit ist, die wir hinzufügen eine click-Ereignis-listener, wird das wechseln der aktiven textur Wert
planeElements[0].addEventListener(“click”, function() {
wenn(activeTexture == 1) {
activeTexture = 2;
}
else {
activeTexture = 1;
}
});

// klicken Sie zum Abspielen der videos
Dokument.getElementById(“enter-site”).addEventListener(“click”, function() {
// Anzeige von canvas-und ausblenden der Schaltfläche
Dokument.Körper.classList.add(“video – -gestartet”);

// spielen Sie unsere videos
Flugzeug.playVideos();
}, false);

}).onRender(function() {
// erhöhen oder verringern unsere timer, basierend auf der aktiven textur Wert
// bei 60fps sollte dies letzten Sekunde
wenn(activeTexture == 2) {
transitionTimer = Math.min(60, transitionTimer + 1);
}
else {
transitionTimer = Math.max(0, transitionTimer – 1);
}
// update unser übergang timer uniform
Flugzeug.Uniformen.transitionTimer.Wert = transitionTimer;
});
}
Shader

Dies ist, wo die Magie auftreten. Wie in unserem ersten Beispiel, wird der vertex-shader wird nicht viel tun, und Sie müssen, um den Fokus auf die fragment-shader zu schaffen, der eine “dive in” – Effekt:

<script id=”Flugzeug-vs” type=”x-shader/x-vertex”>
#ifdef GL_ES
Präzision mediump float;
#endif

// Standard obligatorische Variablen
attribute vec3 aVertexPosition;
attribute vec2 aTextureCoord;

uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;

// varyings
varying vec3 vVertexPosition;
varying vec2 vTextureCoord;

// kundenspezifische Uniformen
uniform float uTransitionTimer;

void main() {

vec3 vertexPosition = aVertexPosition;

gl_Position = uPMatrix * uMVMatrix * vec4(vertexPosition, 1.0);

// varyings
vTextureCoord = aTextureCoord;
vVertexPosition = vertexPosition;
}
</script>

<script id=”Flugzeug-fs” type=”x-shader/x-fragment”>
#ifdef GL_ES
Präzision mediump float;
#endif

varying vec3 vVertexPosition;
varying vec2 vTextureCoord;

// kundenspezifische Uniformen
uniform float uTransitionTimer;

// unsere Texturen Sampler
// beachten Sie, wie es entspricht unserer Daten-sampler-Parametern
uniform sampler2D firstTexture;
uniform sampler2D secondTexture;
uniform sampler2D Verschiebung;

void main( void ) {
// unsere textur coords
vec2 textureCoords = vec2(vTextureCoord.x, vTextureCoord.y);

// unsere displacement-textur
vec4 displacementTexture = texture2D(Hubraum, textureCoords);

// unser Verschiebungs-Faktor ist ein float-variierend von 1 bis 0 auf der Basis der timer
float displacementFactor = 1.0 – (cos(uTransitionTimer / (60.0 / 3.141592)) + 1.0) / 2.0;

// der Wirkfaktor sagen, welchen Weg wollen wir verdrängen unsere Pixel
// die weiter von der Mitte des videos ist, desto stärker wird es werden
vec2 effectFactor = vec2((textureCoords.x – 0.5) * 0.75, (textureCoords.y – 0.5) * 0.75);

// berechnen unsere vertriebenen Koordinaten zu unserem ersten video
vec2 firstDisplacementCoords = vec2(textureCoords.x – displacementFactor * (displacementTexture.r * effectFactor.x), textureCoords.y – displacementFactor * (displacementTexture.r * effectFactor.y));
// das Gegenteil ist / Verdrängung Auswirkung auf das zweite video
vec2 secondDisplacementCoords = vec2(textureCoords.x – (1.0 – displacementFactor) * (displacementTexture.r * effectFactor.x), textureCoords.y – (1.0 – displacementFactor) * (displacementTexture.r * effectFactor.y));

// wenden Sie die Texturen
vec4 firstDistortedColor = texture2D(firstTexture, firstDisplacementCoords);
vec4 secondDistortedColor = texture2D(secondTexture, secondDisplacementCoords);

// Mischung beide Texturen basierend auf unserer Verschiebungs-Faktor
vec4 finalColor = mix(firstDistortedColor, secondDistortedColor, displacementFactor);

// Umgang mit vormultiplizierten alpha
finalColor = vec4(finalColor.rgb * finalColor.ein, finalColor.a);

// gelten unsere shader
gl_FragColor = finalColor;
}
</script>

Hier ist unsere kleine video-Diashow mit coolen übergangseffekten:

Siehe Stift curtains.js video-Diashow von Martin Laxenaire (@martinlaxenaire) auf CodePen.

Dieses Beispiel ist eine große Weise, zu zeigen, wie Sie eine Diashow erstellen mit curtains.js: Sie möchten möglicherweise verwenden Sie Bilder statt videos, ändern des displacement-textur-ändern Sie den fragment-shader oder sogar mehr Seiten hinzuzufügen…

Tiefer gehen

Wir haben nur der Oberfläche gekratzt, was möglich ist, mit curtains.js. Sie könnte versuchen, erstellen Sie mehrere Ebenen mit einem kühlen mouse-over-Effekt für Ihren Artikel, Daumen zum Beispiel. Die Möglichkeiten sind fast endlos.

Wenn Sie sehen wollen, mehr Beispiele, die alle diese Grundlagen Verwendungen, können Sie die Bibliotheks-website oder auf der GitHub-repo.

Das Jetpack WordPress-plugin läuft auf dieser Website, indem Sie nicht nur die verwandten Beiträge unten, aber die Sicherheit und backups, Markdown-support, site-Suche, Kommentar-Formularen, social-network-verbindungen und vieles mehr!