GSAP - ProcessWire - UIKit: Unterschied zwischen den Versionen
| Zeile 16: | Zeile 16: | ||
site/templates/fields/animations/myAnimationTemplate.php | site/templates/fields/animations/myAnimationTemplate.php | ||
site/templates/scripts/animations.js | site/templates/scripts/animations.js | ||
| − | Box.php | + | Box.php (Optional) |
| − | _init.php | + | '''_init.php''' |
<syntaxhighlight lang="php"> | <syntaxhighlight lang="php"> | ||
// ANIMATION CODE | // ANIMATION CODE | ||
| Zeile 84: | Zeile 84: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| − | Die Klasse Animation bekommt von der Klasse Box alle Funktionen zum einfachen erstellen von HTML Containern mit Klassen und Attributen. Wichtig ist aber die '''renderAnimationTemplate''' Funktion. Diese holt ein Template welches im Ordner | + | Die Klasse Animation bekommt von der Klasse Box alle Funktionen zum einfachen erstellen von HTML Containern mit Klassen und Attributen. Das kann man auch selbst machen. Wichtig ist aber die '''renderAnimationTemplate''' Funktion. Diese holt ein Template welches im Ordner |
site/templates/fields/animations/meinAnimationsName.php | site/templates/fields/animations/meinAnimationsName.php | ||
| − | liegt. | + | liegt. |
| − | animations.inc | + | '''animations.inc''' |
<syntaxhighlight lang="php"> | <syntaxhighlight lang="php"> | ||
/** | /** | ||
| Zeile 119: | Zeile 119: | ||
Im Backend kann der User über ein Dropdown Feld (section_animation) eine Animation auswählen. Hat er das getan wird über $page->fp_section->section_animation der Wert des Feldes ausgelesen. Unsere Animationstemplates entsprechen diesem Namen. Wir erstellen ein Animations Objekt und übergeben diesen an Animation->renderAnimatioinTemplate(). Daraufhin wird uns der benötigte code zurückgegeben. Da das Animation Objekt auch alle Box Funktionen beinhaltet, können wir es auch gleich nutzen um einen Wrapper drumrum zu legen. | Im Backend kann der User über ein Dropdown Feld (section_animation) eine Animation auswählen. Hat er das getan wird über $page->fp_section->section_animation der Wert des Feldes ausgelesen. Unsere Animationstemplates entsprechen diesem Namen. Wir erstellen ein Animations Objekt und übergeben diesen an Animation->renderAnimatioinTemplate(). Daraufhin wird uns der benötigte code zurückgegeben. Da das Animation Objekt auch alle Box Funktionen beinhaltet, können wir es auch gleich nutzen um einen Wrapper drumrum zu legen. | ||
| − | + | ||
| + | '''myTemplate.php''' | ||
| + | <syntaxhighlight lang="php"> | ||
| + | $parent = getRepeaterParent($page); // Helper function to get parent page if we are in a repeaterMatrix (see below) | ||
| + | if($parent->opt_2){ | ||
| + | $out = renderAnimationCode($page,$out); | ||
| + | } | ||
| + | return $out; | ||
| + | </syntaxhighlight> | ||
| + | Dies ist unser Haupttemplate. Hier starte ich den Vorgang. | ||
| + | Wichtig ist hier nur, dass wir lediglich die Helferfunktion renderAnimationCode aufrufen müssen. Der Rest geht durch unsere Vorarbeiten automatisch. | ||
| + | |||
| + | Optional: Ich starte das nur, falls der User für die Seite Animationen (hier im Feld opt_2 aktiviert hat. Da ich oft eine RepeaterMatrix benutze müssen wir noch die Elternseite finden. Das machen wir mit einer kleinen Hilfefunktion. | ||
| + | |||
| + | '''site/fields/animations/myAnimationTemplate.php''' | ||
| + | |||
<syntaxhighlight lang="php"> | <syntaxhighlight lang="php"> | ||
| + | // Note: $value contains all values we need as an array | ||
| + | $out = ''; | ||
| + | $i1 = $value['assetPath'].'/Cloud1-S.png'; | ||
| + | ob_start(); | ||
| + | ?> | ||
| + | <div class="ani-item cloud1"> | ||
| + | <img src="<?=$i1?>"> | ||
| + | </div> | ||
| + | <?php | ||
| + | $out = ob_get_clean(); | ||
| + | echo $out; | ||
| + | </syntaxhighlight> | ||
| + | Dieses Template gibt uns das zusätzliche Markup für die Animation. Da wir in der Animation.php die ProcessWire Funktion $page->renderValue() verwendet haben konnten wir im ersten Parameter unsere $options an das Template weitergeben. Im Template steht und das automatisch in der Variable $value zur Verfügung. | ||
| + | |||
| + | site/templates/scripts/animations.js | ||
| + | <syntaxhighlight lang="javascript"> | ||
| + | // Todo event listeners für Browserfenster Größenänderungen | ||
| + | |||
| + | gsap.registerPlugin("ScrollTrigger"); | ||
| + | gsap.defaults({ | ||
| + | ease: "expo.in.out", | ||
| + | duration: 1.3 | ||
| + | }); | ||
| + | // COMMON VARS | ||
| + | var screenWidth = window.innerWidth | ||
| + | |||
| + | $(document).ready(function(){ | ||
| + | // ANI-CLOUD1 | ||
| + | var cloud = $(".ani-cloud1 .cloud1") | ||
| + | var wCloud = cloud.outerWidth(); | ||
| + | var hCloud = cloud.outerHeight(); | ||
| + | var tlCloud1 = gsap.timeline({ | ||
| + | scrollTrigger: { | ||
| + | trigger: cloud, | ||
| + | pin: false, // pin the trigger element while active? | ||
| + | start: "top bottom", // when the top of the trigger hits the top of the viewport | ||
| + | end: "top top", | ||
| + | scrub: 0, // smooth scrubbing (seconds) | ||
| + | }, | ||
| + | repeat: 0 | ||
| + | }) | ||
| + | tlCloud1.fromTo(cloud, {x:0, y:hCloud/2},{x:screenWidth-wCloud, duration: 2}) | ||
| + | |||
| + | // ANI TREES1 | ||
| + | // ... | ||
| + | |||
| + | |||
| + | }); | ||
| + | |||
</syntaxhighlight> | </syntaxhighlight> | ||
| + | Zu guter Letzt müssen wir in unserer JavaScript Dateien die eigentlichen Animationen hinterlegen. In unserem Fall mit GSAP. | ||
Version vom 20. April 2024, 13:47 Uhr
Beispielszenarien wie man Animationen mit ProcessWire als CMS, UIKit als CSS/JS Framework und GSAP einsetzen kann.
Beispiele
Beispielszenario 1 - Section Animationen mit ScrollTrigger und ProcessWire
Hier möchten wir Animationen abspielen, die beim Scrollen abgespielt werden, wenn der Benutzer die Section erreicht.
- Die Animationen sollen für den Redakteur wählbar sein.
- Die Animationen an sich sind vorgefertigt
- Wenn sie nicht benötigt werden soll der Code nicht eingebunden werden.
Übersicht
Benötigte Dateien
_init.php site/templates/includes/Animation.php site/templates/includes/animations.inc site/templates/fields/animations/myAnimationTemplate.php site/templates/scripts/animations.js Box.php (Optional)
_init.php
// ANIMATION CODE
if($page->opt_2){
include_once('includes/Animation.php'); // include Animation Class
include_once('includes/animations.inc'); // include additional animation helper functions
page()->additionalHeaderData .= '
<link rel="stylesheet" href="'.urls()->templates.'styles/animations.css" />
<script src="'.urls()->templates.'vendor/gsap/gsap.min.js"></script>
<script src="'.urls()->templates.'vendor/gsap/gsap.min.js"></script>
<script src="'.urls()->templates.'vendor/gsap/ScrollTrigger.min.js"></script>
';
}
In der _init.php laden wir die benötigten Skripte:
Über das Feld $page->opt_2 (Checkbox) kann der User festlegen ob für die Seite die benötigten Skripte geladen werden.
page()->additionalHeaderData wird in einem späteren Template eingefügt. Man könnte auch über einen Hook arbeiten, dies ist aber eine einfache effektive Lösung.
Animation.php liefert die Klasse Animation, die im wesentlichen Funktionen bietet um Code aus einem Template zu laden und in den aktuellen Markup einzubetten.
animations.inc liefert Helferfunktionen für die Layoutblocks.
Animation.php
<?php namespace ProcessWire;
class Animation extends Box
{
public $classes = array();
public $styles = array();
public $classesMarkup = '';
public $stylesMarkup = '';
public $attributes = array();
// init section with page values aka layout_block values
function __construct($classes = array('ani-box'), $styles = array(), $attributes = array()){
}
/**
* Uses a template file to create the animation markup inside a wrapper box
* @param String template filename (without suffix)
* @param Array associative Array containing rendering options
*/
function renderAnimationTemplate($animationName,$options=array()){
$defaults = array(
'box'=>false, // wrap the animation template content in a container?
'classes'=>'ani-box', // classes for the container (if used)
'assetPath'=>urls()->templates.'assets/animations', // path to animation assets - can be used by templates
'templatePath'=>'animations/'.$animationName // render templates starting at /site/templates/
);
$options = array_merge($defaults, $options);
$options['animationName'] = $animationName;
$animationBoxContent = page()->renderValue($options,$options['templatePath']);
$animationBox = new Box();
if($options['classes']) $animationBox->addClasses(preg_replace("/[^a-zA-Z0-9-\s]+/", "", $options['classes']));
$animationBox->addClasses($animationName);
if($options['box']) $animationBoxContent = $animationBox->wrap($animationBoxContent,'div');
return $animationBoxContent;
}
}
Die Klasse Animation bekommt von der Klasse Box alle Funktionen zum einfachen erstellen von HTML Containern mit Klassen und Attributen. Das kann man auch selbst machen. Wichtig ist aber die renderAnimationTemplate Funktion. Diese holt ein Template welches im Ordner
site/templates/fields/animations/meinAnimationsName.php
liegt.
animations.inc
/**
* animations.inc
* Helperfunctions for animations with gsap and processwire
* needs Animation Class from Animation.php
* mainly used in layoutblocks to render animation markup if nessecary
*/
/**
* renderAnimationCode
* @param Page
* @param String - Markup we need to expand with animation markup
* @return String
*/
function renderAnimationCode($page,$out){
$ani = new Animation();
if($page->fp_section->section_animation && $animationName = $page->fp_section->section_animation->value){
// get animation markup
$animationContent = $ani->renderAnimationTemplate($animationName,array('box'=>true));
// as animation object extends Box we can use it to add additional wrapper
$ani->addClasses('ani-wrapper');
$ani->addClasses('ani-wrapper-'.$animationName);
$out = $ani->wrap($out.$animationContent); // wrap section markup + animation markup in a container
}
return $out;
}
Diese kann von unseren Seitentemplates (wir nutzen eigene Templates für verschiedene Inhaltstypen) um jeweils am Ende den Code für die gewünschte Animation einzufügen.
Im Backend kann der User über ein Dropdown Feld (section_animation) eine Animation auswählen. Hat er das getan wird über $page->fp_section->section_animation der Wert des Feldes ausgelesen. Unsere Animationstemplates entsprechen diesem Namen. Wir erstellen ein Animations Objekt und übergeben diesen an Animation->renderAnimatioinTemplate(). Daraufhin wird uns der benötigte code zurückgegeben. Da das Animation Objekt auch alle Box Funktionen beinhaltet, können wir es auch gleich nutzen um einen Wrapper drumrum zu legen.
myTemplate.php
$parent = getRepeaterParent($page); // Helper function to get parent page if we are in a repeaterMatrix (see below)
if($parent->opt_2){
$out = renderAnimationCode($page,$out);
}
return $out;
Dies ist unser Haupttemplate. Hier starte ich den Vorgang. Wichtig ist hier nur, dass wir lediglich die Helferfunktion renderAnimationCode aufrufen müssen. Der Rest geht durch unsere Vorarbeiten automatisch.
Optional: Ich starte das nur, falls der User für die Seite Animationen (hier im Feld opt_2 aktiviert hat. Da ich oft eine RepeaterMatrix benutze müssen wir noch die Elternseite finden. Das machen wir mit einer kleinen Hilfefunktion.
site/fields/animations/myAnimationTemplate.php
// Note: $value contains all values we need as an array
$out = '';
$i1 = $value['assetPath'].'/Cloud1-S.png';
ob_start();
?>
<div class="ani-item cloud1">
<img src="<?=$i1?>">
</div>
<?php
$out = ob_get_clean();
echo $out;
Dieses Template gibt uns das zusätzliche Markup für die Animation. Da wir in der Animation.php die ProcessWire Funktion $page->renderValue() verwendet haben konnten wir im ersten Parameter unsere $options an das Template weitergeben. Im Template steht und das automatisch in der Variable $value zur Verfügung.
site/templates/scripts/animations.js
// Todo event listeners für Browserfenster Größenänderungen
gsap.registerPlugin("ScrollTrigger");
gsap.defaults({
ease: "expo.in.out",
duration: 1.3
});
// COMMON VARS
var screenWidth = window.innerWidth
$(document).ready(function(){
// ANI-CLOUD1
var cloud = $(".ani-cloud1 .cloud1")
var wCloud = cloud.outerWidth();
var hCloud = cloud.outerHeight();
var tlCloud1 = gsap.timeline({
scrollTrigger: {
trigger: cloud,
pin: false, // pin the trigger element while active?
start: "top bottom", // when the top of the trigger hits the top of the viewport
end: "top top",
scrub: 0, // smooth scrubbing (seconds)
},
repeat: 0
})
tlCloud1.fromTo(cloud, {x:0, y:hCloud/2},{x:screenWidth-wCloud, duration: 2})
// ANI TREES1
// ...
});
Zu guter Letzt müssen wir in unserer JavaScript Dateien die eigentlichen Animationen hinterlegen. In unserem Fall mit GSAP.