✏️ 正在编辑: animate.php
路径:
/home/qyel0117/public_html/wp-content/themes/semplice7/editor/animate.php
提示:
您可以编辑任何文件(包括二进制文件),但请注意不当修改可能导致文件损坏。
<?php // namespace namespace Semplice\Editor; // use use Semplice\Helper\Basic; use Semplice\Helper\Get; use Semplice\Editor\AnimateStyles; use Semplice\Editor\AnimateGet; // ----------------------------------------- // semplice animate // ----------------------------------------- class Animate { // public vars public $animate; public $post_id; public $script_execution; // ----------------------------------------- // get motion output // ----------------------------------------- public static function get($atts, $id, $post_id) { // vars $output = array( 'js' => '', 'css' => '' ); $presets = Get::animate_presets(); $is_lottie = self::is_lottie($atts); $mobile = isset($atts['motions']['mobile']) ? $atts['motions']['mobile'] : 'on'; $event = isset($atts['motions']['event']) ? $atts['motions']['event'] : 'on_load'; // check if id is cover and change it if($id == 'cover') { $id = 'cover-' . $post_id; } // are there motions to mirgrate or is a preset attached?? if(!empty($atts['motions']['active'])) { $atts['motions'] = self::migrate_motions($id, $atts); } else if(!empty($atts['motions']['preset']) && isset($presets['custom'][$atts['motions']['preset']])) { $atts['motions'] = $presets['custom'][$atts['motions']['preset']]; // add back event $atts['motions']['event'] = $event; } // remove z-index if set if(isset($atts['motions']['initial']) && isset($atts['motions']['initial']['z-index'])) { unset($atts['motions']['initial']['z-index']); } // mobile detect $mobile_detect = Basic::mobile_detect(); // get motion css and js if($mobile_detect->isMobile() && $mobile == 'on' || !$mobile_detect->isMobile()) { if(!empty($atts['motions']['timeline']) || $is_lottie || isset($atts['motions']['event']) && isset($atts['motions']['initial']) && $atts['motions']['event'] == 'on_scroll') { // get css if(!$is_lottie) { $output['css'] .= AnimateStyles::get('css', $atts, $atts['motions'], $id); } // add to output $output['js'] .= self::motion_js($atts, $id, $is_lottie, $post_id); } } // return return $output; } // ----------------------------------------- // is lottie? // ----------------------------------------- public static function is_lottie($atts) { // default $is_lottie = false; if(isset($atts['module']) && $atts['module'] == 'lottie') { // get content $content = $atts['content']['xl']; // get lottie url if(isset($content['id'])) { $url = wp_get_attachment_url($content['id']); // has content + width and height defined? if($url && isset($content['width']) && isset($content['height'])) { $is_lottie = true; } } } return $is_lottie; } // ----------------------------------------- // get motion js // ----------------------------------------- public static function motion_js($atts, $id, $is_lottie, $post_id) { // output $output = 'var playRepeat = [];'; $selector = AnimateGet::selector($id, $atts); $options = false; // splitText config $split_text = (!$is_lottie) ? AnimateGet::split_text($atts) : false; $split_selector = $selector; // init splitText if enabled if($split_text) { $split_selector = AnimateGet::split_text_sel($id, $atts, $split_text); // parent is visibility:hidden in head CSS to avoid flicker; reveal after splitting // (always — even if SplitText is unavailable, so the content doesn't stay hidden) $output .= ' if(typeof SplitText !== "undefined") { var options = { type: "' . $split_text['type'] . '", charsClass: "smp-split-char", wordsClass: "smp-split-word", linesClass: "smp-split-line" }; ' . ($split_text['mask'] ? 'options.mask = "' . $split_text['type'] . '";' : '') . ' semplice.animate.splitText["' . $id . '"] = new SplitText("' . $selector . '", options); } gsap.set("' . $selector . '", { visibility: "visible" }); '; } // get gsap element or lottie $lottiePlayback = array( 'onStart' => '', 'play' => '', 'pause' => '' ); if($is_lottie) { $motions = $atts['options']; $gsap_props = AnimateGet::lottie_element($id, $atts['options']); // call lottie $lottie = $atts['content']['xl']; $url = wp_get_attachment_url($lottie['id']); $output = 'semplice.lottie("' . $id . '", "' . $url . '", JSON.parse(\'' . json_encode($atts['options']) . '\'), ' . $lottie['width'] . ', ' . $lottie['height'] . ');'; // lottie play for gsap $lottiePlayback = array( 'onStart' => ' onStart: function() { // start lottie animation semplice.animate.lottie["' . $id . '"].play(); } ', 'play' => 'semplice.animate.lottie["' . $id . '"].play();', 'pause' => 'semplice.animate.lottie["' . $id . '"].pause();' ); } else { $motions = $atts['motions']; $gsap_props = AnimateGet::gsap_element($id, $atts); } // event $event = $gsap_props['event']; // is looped $is_looped = ($gsap_props['repeat'] == -1 || intval($gsap_props['repeat']) > 0); switch ($event) { case 'on_scroll': // default trigger settings $trigger = array('start_trigger' => 'top', 'start_scroller' => 'bottom', 'end_trigger' => 'bottom', 'end_scroller' => 'top'); // iterate triggers foreach ($trigger as $attr => $dir) { // has value in ram? if(isset($motions['migrated']) && $attr == 'end_trigger') { // add to js output if(isset($motions[$attr])) { $output .= 'var endDuration = ' . $motions[$attr] . ';'; } else { $output .= 'var endDuration = 50;'; } $trigger[$attr] = 'migrated'; } else if(isset($motions[$attr]) && $motions[$attr] != 0) { $prefix = '+'; if($motions[$attr] < 0) { $prefix = '-'; } $trigger[$attr] = $trigger[$attr] . $prefix . '=' . abs($motions[$attr]) . '%'; } else { $trigger[$attr] = $trigger[$attr]; } } // start and end $start = $trigger['start_trigger'] . ' ' . $trigger['start_scroller']; $end = $trigger['end_trigger'] . ' ' . $trigger['end_scroller']; if(isset($motions['pin']) && Basic::boolval($motions['pin'])) { if(isset($motions['pin_duration'])) { $end = '+=' . $motions['pin_duration'] . '%'; } else { $end = '+=50%'; } } // options $options = array( 'id' => $id, 'trigger' => $selector, 'start' => $start, 'end' => $end, 'pin' => false, 'markers' => false, 'pinSpacing' => false, 'scrub' => 0 ); // numeric $numeric = array('scrub'); // iterate defaults and add values from motions foreach ($options as $attr => $default_val) { if(isset($motions[$attr])) { $val = $motions[$attr]; // true false and numeric? if(is_string($val) && $val == 'true' || is_string($val) && $val == 'false') { $val = Basic::boolval($val); } else if(in_array($attr, $numeric)) { $val = floatval($val); } $options[$attr] = $val; } } // encode options $output .= 'var options = JSON.parse(\'' . json_encode($options) . '\');'; // migrated end trigger if(isset($motions['migrated']) && isset($motions['end_trigger'])) { // calculate end trigger $output .= ' if(typeof endDuration !== "undefined") { var vpHeight = parseInt($(window).height()); var content = document.getElementById("' . $id . '"); var contentRect = content.getBoundingClientRect(); var contentHeight = contentRect.height; var newEnd = Math.round(((endDuration * (vpHeight / 100)) - contentHeight) / (contentHeight / 100)); // changing end if(false !== newEnd && null !== newEnd) { options["end"] = options["end"].replace("migrated", "bottom+=" + newEnd + "%"); } } '; } // add on update if(true === $is_lottie) { $output .= ' var timeObj = { currentFrame: 0 }; options["onUpdate"] = function(self) { gsap.to(timeObj, { duration: 0, currentFrame:(Math.floor(self.progress * (semplice.animate.lottie["' . $id . '"].totalFrames - 1))), onUpdate: function() { semplice.animate.lottie["' . $id . '"].goToAndStop(timeObj.currentFrame, true); }, }); } '; } $output .= ' if(options.pin === true) { if("' . $id . '".indexOf("section_") > -1 || "' . $id . '".indexOf("cover") > -1) { $("#' . $id . '").wrap("<smp-section-pin class=\'sp_' . $id . '\'></smp-section-pin>"); options["trigger"] = ".sp_' . $id . '"; } else if("' . $id . '".indexOf("column_") > -1) { $("#' . $id . '").wrap("<smp-column-pin class=\'cpo_' . $id . '\'><smp-column-pin-inner class=\'cpi_' . $id . ' \'></smp-column-pin-inner></smp-column-pin>"); options["trigger"] = ".cpi_' . $id . '"; var atts = $("#' . $id . '").prop("attributes"); $.each(atts, function(key, attr) { if(attr.name.indexOf("width") > -1) { $(".cpo_' . $id . '").attr(attr.name, attr.value); } }); } else if("' . $id . '".indexOf("content_") > -1) { options["trigger"] = "#' . $id . '"; } ' . AnimateGet::zindex($atts, $id) . ' } semplice.animate.gsap["' . $id . '"] = gsap.timeline({ scrollTrigger: options, }); '; break; case 'on_load': $toggle_actions = $is_looped ? '"play pause resume pause"' : '"play none none none"'; $output .= ' semplice.animate.gsap["' . $id . '"] = gsap.timeline({ scrollTrigger: { trigger: "' . $selector . '", toggleActions: ' . $toggle_actions . ' }, repeat: ' . $gsap_props['repeat'] . ', ' . $lottiePlayback['onStart'] . ' }); '; break; case 'on_intro': $output .= ' semplice.animate.gsap["' . $id . '"] = gsap.timeline({ repeat: ' . $gsap_props['repeat'] . ', ' . $lottiePlayback['onStart'] . ' }); '; // looped on_intro animations only make sense during the intro phase — pause once intro is done so they stop burning the main thread if($is_looped) { $output .= ' window.addEventListener("sempliceIntroDone", function() { if(semplice.animate.gsap["' . $id . '"]) { semplice.animate.gsap["' . $id . '"].pause(); } }, { once: true }); '; } break; case 'on_click': case 'on_hover': $output .= ' semplice.animate.gsap["' . $id . '"] = gsap.timeline({ repeat: ' . $gsap_props['repeat'] . ', onRepeat: function() { if(playRepeat["' . $id . '"] !== true) { semplice.animate.gsap["' . $id . '"].pause(); } }, ' . $lottiePlayback['onStart'] . ' }); '; break; } // event handler if($event == 'on_click') { $output .= ' $(document).on("click", "' . $selector . '", function() { semplice.animate.gsap["' . $id . '"].play(); }); // add pointer $("' . $selector . '").css("cursor", "pointer"); '; } else if($event == 'on_hover') { $lottie_start = ''; $lottie_pause = ''; if(true === $is_lottie) { $lottie_start = 'semplice.animate.lottie["' . $id . '"].play();'; $lottie_pause = 'semplice.animate.lottie["' . $id . '"].pause();'; } $output .= ' $(document).on("mouseenter", "' . $selector . '", function() { semplice.animate.gsap["' . $id . '"].play(); playRepeat["' . $id . '"] = true; ' . $lottiePlayback['play'] . ' }); $(document).on("mouseleave", "' . $selector . '", function() { semplice.animate.gsap["' . $id . '"].reverse(); playRepeat["' . $id . '"] = false; ' . $lottiePlayback['pause'] . ' }); '; } // check for layout-shifting effects (border-width changes element dimensions) $has_layout_shift = self::has_layout_shift($atts['motions']); // check if timeline is defined and add steps to timeline if(isset($gsap_props['timeline']) && !empty($gsap_props['timeline'])) { foreach ($gsap_props['timeline'] as $step => $step_animation) { // is there transform to set? if(isset($step_animation['css'])) { if($split_text && isset($step_animation['css']['split'])) { // separated gsap.set for splitText $split_css = json_encode($step_animation['css']['split']); $container_css = json_encode($step_animation['css']['container']); if(!empty(json_decode($split_css, true))) { $output .= 'gsap.set("' . $split_selector . '", JSON.parse(\'' . $split_css . '\'));'; } if(!empty(json_decode($container_css, true))) { $output .= 'gsap.set("' . $selector . '", JSON.parse(\'' . $container_css . '\'));'; } } else { $css = json_encode($step_animation['css']); if(!empty(json_decode($css, true))) { $output .= 'gsap.set("' . $selector . '", JSON.parse(\'' . $css . '\'));'; } } } $output .= ' // parse props var props = JSON.parse(\'' . json_encode($step_animation['props']) . '\'); // add to timeline semplice.animate.gsap["' . $id . '"].to("' . $split_selector . '", props); '; // if split text animate container props seperately (after split, overlapping with "<") if($split_text && isset($step_animation['containerProps']) && !empty($step_animation['containerProps'])) { $output .= ' // container props var containerProps = JSON.parse(\'' . json_encode($step_animation['containerProps']) . '\'); // add to timeline semplice.animate.gsap["' . $id . '"].to("' . $selector . '", containerProps, "<"); '; } $output .= ' // pause timeline if(intro) { semplice.animate.gsap["' . $id . '"].play(); } else { semplice.animate.gsap["' . $id . '"].pause(); } '; } } // refresh ScrollTrigger after animation completes if layout-shifting props are animated if($has_layout_shift) { $output .= ' semplice.animate.gsap["' . $id . '"].call(function() { if(typeof ScrollTrigger !== "undefined") { ScrollTrigger.refresh(); } }); '; } // return return $output; } // ----------------------------------------- // check for layout-shifting effects // ----------------------------------------- public static function has_layout_shift($motions) { $prop = 'border-width'; // check initial if(isset($motions['initial']) && isset($motions['initial'][$prop]) && $motions['initial'][$prop] != 0) { return true; } // check timeline steps if(isset($motions['timeline'])) { foreach($motions['timeline'] as $step) { if(isset($step['effects']) && isset($step['effects'][$prop])) { return true; } } } return false; } // ----------------------------------------- // migrate old motions // ----------------------------------------- public static function migrate_motions($id, $atts) { // motions $motions = $atts['motions']; // event $event = isset($motions['event']) ? $motions['event'] : 'on_load'; // get initial styles $initial = AnimateStyles::initial($atts); // init new motion structure $migrated = array( 'event' => $event, 'initial' => $initial, 'timeline' => array(), 'migrated' => true ); // old defaults $defaults = array( 'duration' => 800, 'delay' => 0, 'easing' => 'Power0.easeNone', ); // add global options timeline $migrated['timeline'][0] = array( 'duration' => isset($motions['duration']) ? $motions['duration'] : $defaults['duration'], 'delay' => isset($motions['delay']) ? $motions['delay'] : $defaults['delay'], 'ease' => isset($motions['easing']) ? $motions['easing'] : $defaults['easing'], 'effects' => array() ); // add effects to timeline foreach ($motions['active'] as $key => $effect) { // initial values if(isset($motions['start'][$effect]) && $effect != 'scale' && $effect != 'move') { if($effect == 'rotate') { $motions['start'][$effect] = intval($motions['start'][$effect]); } $migrated['initial'][$effect] = $motions['start'][$effect]; } else if(isset($motions['start'][$effect]) && $effect == 'scale') { $migrated['initial']['scaleX'] = $motions['start'][$effect]; $migrated['initial']['scaleY'] = $motions['start'][$effect]; } else if($effect == 'move') { $migrated['initial']['translateX'] = $motions['start']['translateX']; $migrated['initial']['translateY'] = $motions['start']['translateY']; } // add to effects if(isset($motions['end'][$effect]) && $effect != 'scale' && $effect != 'move') { if($effect == 'rotate') { $motions['end'][$effect] = intval($motions['end'][$effect]); } $migrated['timeline'][0]['effects'][$effect] = $motions['end'][$effect]; } else if(isset($motions['end'][$effect]) && $effect == 'scale') { $migrated['timeline'][0]['effects']['scaleX'] = $motions['end'][$effect]; $migrated['timeline'][0]['effects']['scaleY'] = $motions['end'][$effect]; } else if($effect == 'move') { $migrated['timeline'][0]['effects']['translateX'] = $motions['end']['translateX']; $migrated['timeline'][0]['effects']['translateY'] = $motions['end']['translateY']; } } // on scroll if($event == 'on_scroll') { // on scroll atts $on_scroll_atts = array('onscroll_duration', 'onscroll_movement', 'push_followers'); // iterate atts foreach ($on_scroll_atts as $key => $attribute) { if(isset($motions[$attribute])) { switch($attribute) { case 'onscroll_duration': // use as pin duration if sticky if(isset($motions['onscroll_movement']) && $motions['onscroll_movement'] == 'sticky') { $migrated['pin_duration'] = intval($motions[$attribute]); } else { $migrated['end_trigger'] = intval($motions[$attribute]); } break; case 'onscroll_movement': $migrated['pin'] = ($motions[$attribute] == 'sticky') ? 'true' : 'false'; break; case 'push_followers': $migrated['pinSpacing'] = ($motions[$attribute] == 'enabled') ? 'true' : 'false'; break; }; } } // if no pin duration or end trigger, add the 50% end trigger default if(!isset($migrated['pin_duration']) && !isset($migrated['end_trigger'])) { if(isset($motions['onscroll_movement']) && $motions['onscroll_movement'] == 'sticky') { $migrated['pin_duration'] = 50; } else { $migrated['end_trigger'] = 50; } } // trigger hook $migrated['start_scroller'] = -50; if(isset($motions['trigger_hook']) && $motions['trigger_hook'] != 'custom') { $triggerHook = array( '.5' => -50, 'onLeave' => -100, 'onEnter' => 0 ); $migrated['start_scroller'] = $triggerHook[$motions['trigger_hook']]; } else if(isset($motions['trigger_hook_custom'])) { $value = 100 - intval($motions['trigger_hook_custom']); if($value > 0) { $value = -1 * abs($value); } $migrated['start_scroller'] = $value; } // set the end to start since in scrollMagic there was only 1 trigger $migrated['end_scroller'] = $migrated['start_scroller'] + 100; } return $migrated; } } // instance new Animate; ?>
💾 保存文件
← 返回文件管理器