xref: /plugin/combo/ComboStrap/TagAttribute/Animation.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
1*04fd306cSNickeau<?php
2*04fd306cSNickeau/**
3*04fd306cSNickeau * Copyright (c) 2021. ComboStrap, Inc. and its affiliates. All Rights Reserved.
4*04fd306cSNickeau *
5*04fd306cSNickeau * This source code is licensed under the GPL license found in the
6*04fd306cSNickeau * COPYING  file in the root directory of this source tree.
7*04fd306cSNickeau *
8*04fd306cSNickeau * @license  GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html)
9*04fd306cSNickeau * @author   ComboStrap <support@combostrap.com>
10*04fd306cSNickeau *
11*04fd306cSNickeau */
12*04fd306cSNickeau
13*04fd306cSNickeaunamespace ComboStrap\TagAttribute;
14*04fd306cSNickeau
15*04fd306cSNickeauuse ComboStrap\ExceptionBadArgument;
16*04fd306cSNickeauuse ComboStrap\ExceptionBadSyntax;
17*04fd306cSNickeauuse ComboStrap\ExceptionNotFound;
18*04fd306cSNickeauuse ComboStrap\LogUtility;
19*04fd306cSNickeauuse ComboStrap\PluginUtility;
20*04fd306cSNickeauuse ComboStrap\TagAttributes;
21*04fd306cSNickeau
22*04fd306cSNickeau/**
23*04fd306cSNickeau * Class Animation
24*04fd306cSNickeau * Manage the animation
25*04fd306cSNickeau * @package ComboStrap
26*04fd306cSNickeau */
27*04fd306cSNickeauclass Animation
28*04fd306cSNickeau{
29*04fd306cSNickeau
30*04fd306cSNickeau    const ON_VIEW_ATTRIBUTE = "onview";
31*04fd306cSNickeau    const ON_VIEW_SNIPPET_ID = "onview";
32*04fd306cSNickeau    const ANIMATE_CLASS = "animate__animated";
33*04fd306cSNickeau    const CANONICAL = "animation";
34*04fd306cSNickeau
35*04fd306cSNickeau    /**
36*04fd306cSNickeau     * Based on https://wowjs.uk/
37*04fd306cSNickeau     * @param TagAttributes $attributes
38*04fd306cSNickeau     */
39*04fd306cSNickeau    public static function processOnView(TagAttributes &$attributes)
40*04fd306cSNickeau    {
41*04fd306cSNickeau        if ($attributes->hasComponentAttribute(self::ON_VIEW_ATTRIBUTE)) {
42*04fd306cSNickeau            $onView = $attributes->getValueAndRemove(self::ON_VIEW_ATTRIBUTE);
43*04fd306cSNickeau
44*04fd306cSNickeau            $animateClass = self::ANIMATE_CLASS;
45*04fd306cSNickeau            $attributes->addClassName($animateClass);
46*04fd306cSNickeau
47*04fd306cSNickeau            $animationClass = "animate__" . $onView;
48*04fd306cSNickeau            $attributes->addOutputAttributeValue("data-animated-class", $animationClass);
49*04fd306cSNickeau
50*04fd306cSNickeau            // TODO: Add attributes
51*04fd306cSNickeau            //$delay = "animate__delay-2s";
52*04fd306cSNickeau            //PluginUtility::addClass2Attributes($delay, $attributes);
53*04fd306cSNickeau
54*04fd306cSNickeau            $snippetManager = PluginUtility::getSnippetManager();
55*04fd306cSNickeau
56*04fd306cSNickeau            self::scrollMagicInit();
57*04fd306cSNickeau
58*04fd306cSNickeau            try {
59*04fd306cSNickeau                $snippetManager
60*04fd306cSNickeau                    ->attachRemoteCssStyleSheet(
61*04fd306cSNickeau                        self::ON_VIEW_SNIPPET_ID,
62*04fd306cSNickeau                        "https://cdn.jsdelivr.net/npm/animate.css@4.1.1/animate.min.css",
63*04fd306cSNickeau                        "sha256-X7rrn44l1+AUO65h1LGALBbOc5C5bOstSYsNlv9MhT8="
64*04fd306cSNickeau                    )
65*04fd306cSNickeau                    ->setCritical(false);
66*04fd306cSNickeau            } catch (ExceptionBadArgument|ExceptionBadSyntax|ExceptionNotFound $e) {
67*04fd306cSNickeau                // should not happen
68*04fd306cSNickeau                LogUtility::internalError("Error while trying to add the animate css stylesheet",self::CANONICAL,$e);
69*04fd306cSNickeau            }
70*04fd306cSNickeau
71*04fd306cSNickeau        }
72*04fd306cSNickeau
73*04fd306cSNickeau    }
74*04fd306cSNickeau
75*04fd306cSNickeau    /**
76*04fd306cSNickeau     * https://www.delac.io/wow/docs.html
77*04fd306cSNickeau     * Offset: Define the distance between the bottom of browser viewport and the top of hidden box.
78*04fd306cSNickeau     *         When the user scrolls and reach this distance the hidden box is revealed.
79*04fd306cSNickeau     * Live  : Constantly check for new WOW elements on the page.
80*04fd306cSNickeau     * @param $attributes
81*04fd306cSNickeau     * @deprecated - wow permits only one trigger by animation
82*04fd306cSNickeau     */
83*04fd306cSNickeau    private static function wowInit(&$attributes)
84*04fd306cSNickeau    {
85*04fd306cSNickeau        $snippetManager = PluginUtility::getSnippetManager();
86*04fd306cSNickeau        $wowClass = "wow";
87*04fd306cSNickeau        $wowSnippetId = "wow";
88*04fd306cSNickeau        PluginUtility::addClass2Attributes($wowClass, $attributes);
89*04fd306cSNickeau        $snippetManager->attachCssInternalStyleSheet($wowSnippetId);
90*04fd306cSNickeau
91*04fd306cSNickeau
92*04fd306cSNickeau        $animateClass = self::ANIMATE_CLASS;
93*04fd306cSNickeau        $js = <<<EOF
94*04fd306cSNickeauwindow.addEventListener("load", function(event) {
95*04fd306cSNickeau    var wow = new WOW(
96*04fd306cSNickeau      {
97*04fd306cSNickeau        boxClass:     '$wowClass',      // animated element css class (default is wow)
98*04fd306cSNickeau        animateClass: '$animateClass', // animation css class (default is animated)
99*04fd306cSNickeau        offset:       0,          // distance to the element when triggering the animation (default is 0)
100*04fd306cSNickeau        mobile:       true,       // trigger animations on mobile devices (default is true)
101*04fd306cSNickeau        live:         false,       // act on asynchronously loaded content (default is true)
102*04fd306cSNickeau        callback:     function(box) {
103*04fd306cSNickeau          // the callback is fired every time an animation is started
104*04fd306cSNickeau          // the argument that is passed in is the DOM node being animated
105*04fd306cSNickeau        },
106*04fd306cSNickeau        scrollContainer: null // optional scroll container selector, otherwise use window
107*04fd306cSNickeau      }
108*04fd306cSNickeau    );
109*04fd306cSNickeau    wow.init();
110*04fd306cSNickeau});
111*04fd306cSNickeauEOF;
112*04fd306cSNickeau        $snippetManager->attachJavascriptFromComponentId($wowSnippetId, $js);
113*04fd306cSNickeau        $snippetManager->attachRemoteJavascriptLibrary(
114*04fd306cSNickeau            $wowSnippetId,
115*04fd306cSNickeau            "https://cdn.jsdelivr.net/npm/wowjs@1.1.3/dist/wow.min.js",
116*04fd306cSNickeau            "sha256-gHiUEskgBO+3ccSDRM+c5+nEwTGp64R99KYPfITpnuo="
117*04fd306cSNickeau        );
118*04fd306cSNickeau    }
119*04fd306cSNickeau
120*04fd306cSNickeau    /**
121*04fd306cSNickeau     * https://scrollmagic.io/docs/index.html
122*04fd306cSNickeau     */
123*04fd306cSNickeau    private static function scrollMagicInit()
124*04fd306cSNickeau    {
125*04fd306cSNickeau        $snippetManager = PluginUtility::getSnippetManager();
126*04fd306cSNickeau
127*04fd306cSNickeau        $scrollMagicSnippetId = "scroll-magic";
128*04fd306cSNickeau        $snippetManager->attachJavascriptFromComponentId($scrollMagicSnippetId);
129*04fd306cSNickeau        $snippetManager->attachRemoteJavascriptLibrary(
130*04fd306cSNickeau            $scrollMagicSnippetId,
131*04fd306cSNickeau            "https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.8/ScrollMagic.min.js",
132*04fd306cSNickeau            "sha512-8E3KZoPoZCD+1dgfqhPbejQBnQfBXe8FuwL4z/c8sTrgeDMFEnoyTlH3obB4/fV+6Sg0a0XF+L/6xS4Xx1fUEg=="
133*04fd306cSNickeau        );
134*04fd306cSNickeau        $snippetManager->attachRemoteJavascriptLibrary(
135*04fd306cSNickeau            $scrollMagicSnippetId,
136*04fd306cSNickeau            "https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.8/plugins/debug.addIndicators.min.js",
137*04fd306cSNickeau            "sha512-RvUydNGlqYJapy0t4AH8hDv/It+zKsv4wOQGb+iOnEfa6NnF2fzjXgRy+FDjSpMfC3sjokNUzsfYZaZ8QAwIxg=="
138*04fd306cSNickeau        );
139*04fd306cSNickeau    }
140*04fd306cSNickeau
141*04fd306cSNickeau}
142