|
|
<?php
|
|
|
/**
|
|
|
* Banner Title 区块模板
|
|
|
* 现代化的页面标题横幅组件
|
|
|
*
|
|
|
* @package Nenghui_Energy_Theme
|
|
|
* @version 2.0.0
|
|
|
*/
|
|
|
|
|
|
// 防止直接访问
|
|
|
if (!defined('ABSPATH')) {
|
|
|
exit;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取配置参数
|
|
|
*/
|
|
|
if (!class_exists('BannerTitleConfig')) {
|
|
|
class BannerTitleConfig {
|
|
|
private $shortcode_atts;
|
|
|
|
|
|
public function __construct() {
|
|
|
global $banner_title_shortcode_atts;
|
|
|
// 确保 $banner_title_shortcode_atts 是数组
|
|
|
if (!isset($banner_title_shortcode_atts) || !is_array($banner_title_shortcode_atts)) {
|
|
|
$banner_title_shortcode_atts = array();
|
|
|
}
|
|
|
$this->shortcode_atts = $banner_title_shortcode_atts;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取标题
|
|
|
*/
|
|
|
public function getTitle() {
|
|
|
$title = !empty($this->shortcode_atts['title'])
|
|
|
? $this->shortcode_atts['title']
|
|
|
: get_theme_mod('banner_title_main_title', 'ABOUT US');
|
|
|
|
|
|
// 根据title参数返回合适的显示文本
|
|
|
switch (strtolower($title)) {
|
|
|
case 'cases':
|
|
|
return 'CASES';
|
|
|
case 'news':
|
|
|
return 'NEWS';
|
|
|
case 'about':
|
|
|
return 'ABOUT US';
|
|
|
case 'contact':
|
|
|
return 'CONTACT US';
|
|
|
default:
|
|
|
return strtoupper($title);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取描述
|
|
|
*/
|
|
|
public function getDescription() {
|
|
|
return !empty($this->shortcode_atts['description'])
|
|
|
? $this->shortcode_atts['description']
|
|
|
: get_theme_mod('banner_title_description', 'Powering Sustainable Futures with Advanced Energy Storage Solutions');
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取背景图片
|
|
|
*/
|
|
|
public function getBackgroundImage() {
|
|
|
$bg_image = !empty($this->shortcode_atts['bg_image'])
|
|
|
? $this->shortcode_atts['bg_image']
|
|
|
: get_theme_mod('banner_title_bg_image', '');
|
|
|
|
|
|
// 如果没有设置背景图片或图片无效,使用默认图片
|
|
|
if (empty($bg_image)) {
|
|
|
$bg_image = get_template_directory_uri() . '/assets/images/about-bg.webp';
|
|
|
} else {
|
|
|
// 验证图片路径
|
|
|
$is_valid_url = filter_var($bg_image, FILTER_VALIDATE_URL);
|
|
|
$is_valid_file = false;
|
|
|
|
|
|
// 只对本地路径进行文件存在性检查
|
|
|
if (!$is_valid_url && is_string($bg_image)) {
|
|
|
$file_path = str_replace(get_site_url(), ABSPATH, $bg_image);
|
|
|
$is_valid_file = file_exists($file_path);
|
|
|
}
|
|
|
|
|
|
// 如果既不是有效URL也不是有效文件,使用默认图片
|
|
|
if (!$is_valid_url && !$is_valid_file) {
|
|
|
$bg_image = get_template_directory_uri() . '/assets/images/about-bg.webp';
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return $bg_image;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取元素ID
|
|
|
*/
|
|
|
public function getElementId() {
|
|
|
return !empty($this->shortcode_atts['id'])
|
|
|
? $this->shortcode_atts['id']
|
|
|
: 'banner-title-' . uniqid();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取CSS类
|
|
|
*/
|
|
|
public function getCssClasses() {
|
|
|
$classes = array('nenghui-banner-title', 'banner-title-modern');
|
|
|
|
|
|
if (!empty($this->shortcode_atts['class']) && is_string($this->shortcode_atts['class'])) {
|
|
|
// 清理CSS类名,移除潜在的危险字符
|
|
|
$custom_class = preg_replace('/[^a-zA-Z0-9\-_\s]/', '', $this->shortcode_atts['class']);
|
|
|
if (!empty($custom_class)) {
|
|
|
$classes[] = $custom_class;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 动画类
|
|
|
$show_animation = isset($this->shortcode_atts['show_animation'])
|
|
|
? $this->shortcode_atts['show_animation']
|
|
|
: 'true';
|
|
|
|
|
|
if ($show_animation === 'true' || $show_animation === true) {
|
|
|
$classes[] = 'has-animation';
|
|
|
}
|
|
|
|
|
|
return implode(' ', array_filter($classes));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取高度设置
|
|
|
*/
|
|
|
public function getHeight() {
|
|
|
$height = !empty($this->shortcode_atts['height'])
|
|
|
? $this->shortcode_atts['height']
|
|
|
: get_theme_mod('banner_title_height', '60vh');
|
|
|
|
|
|
// 验证高度值格式
|
|
|
if (!preg_match('/^\d+(\.\d+)?(px|vh|vw|%|em|rem)$/', $height)) {
|
|
|
$height = '70vh'; // 默认值
|
|
|
}
|
|
|
|
|
|
return $height;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 获取遮罩透明度
|
|
|
*/
|
|
|
public function getOverlayOpacity() {
|
|
|
$opacity = !empty($this->shortcode_atts['overlay_opacity'])
|
|
|
? $this->shortcode_atts['overlay_opacity']
|
|
|
: get_theme_mod('banner_title_overlay_opacity', '0.4');
|
|
|
|
|
|
// 验证透明度值(0-1之间的数字)
|
|
|
$opacity = floatval($opacity);
|
|
|
if ($opacity < 0 || $opacity > 1) {
|
|
|
$opacity = 0.4; // 默认值
|
|
|
}
|
|
|
|
|
|
return $opacity;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 初始化配置
|
|
|
try {
|
|
|
$config = new BannerTitleConfig();
|
|
|
$element_id = $config->getElementId();
|
|
|
$title = $config->getTitle();
|
|
|
$description = $config->getDescription();
|
|
|
$bg_image = $config->getBackgroundImage();
|
|
|
$css_classes = $config->getCssClasses();
|
|
|
$height = $config->getHeight();
|
|
|
$overlay_opacity = $config->getOverlayOpacity();
|
|
|
} catch (Exception $e) {
|
|
|
// 错误处理:使用默认值
|
|
|
$element_id = 'banner-title-' . uniqid();
|
|
|
$title = 'ABOUT US';
|
|
|
$description = 'Powering Sustainable Futures with Advanced Energy Storage Solutions';
|
|
|
$bg_image = get_template_directory_uri() . '/assets/images/about-bg.webp';
|
|
|
$css_classes = 'nenghui-banner-title banner-title-modern';
|
|
|
$height = '60vh';
|
|
|
$overlay_opacity = '0.4';
|
|
|
|
|
|
// 记录错误(如果错误处理器可用)
|
|
|
if (function_exists('nenghui_log_foreach_error')) {
|
|
|
nenghui_log_foreach_error('BannerTitleConfig initialization error: ' . $e->getMessage(), __FILE__, __LINE__);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 验证输出变量
|
|
|
$element_id = !empty($element_id) ? $element_id : 'banner-title-' . uniqid();
|
|
|
$title = !empty($title) ? $title : 'ABOUT US';
|
|
|
$description = is_string($description) ? $description : '';
|
|
|
$bg_image = !empty($bg_image) ? $bg_image : get_template_directory_uri() . '/assets/images/about-bg.webp';
|
|
|
$css_classes = !empty($css_classes) ? $css_classes : 'nenghui-banner-title banner-title-modern';
|
|
|
$height = !empty($height) ? $height : '60vh';
|
|
|
$overlay_opacity = is_numeric($overlay_opacity) ? $overlay_opacity : '0.4';
|
|
|
|
|
|
?>
|
|
|
|
|
|
<section id="<?php echo esc_attr($element_id); ?>" class="<?php echo esc_attr($css_classes); ?>" data-bg-image="<?php echo esc_url($bg_image); ?>">
|
|
|
<!-- 背景容器 -->
|
|
|
<div class="banner-background">
|
|
|
<div class="banner-image" style="background-image: url('<?php echo esc_url($bg_image); ?>')"></div>
|
|
|
<div class="banner-overlay" style="opacity: <?php echo esc_attr($overlay_opacity); ?>"></div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 内容容器 -->
|
|
|
<div class="banner-container">
|
|
|
<div class="banner-content">
|
|
|
<div class="banner-text" data-aos="fade-up" data-aos-delay="200">
|
|
|
<h1 class="banner-title"><?php echo esc_html($title); ?></h1>
|
|
|
<?php if (!empty($description)): ?>
|
|
|
<p class="banner-description"><?php echo esc_html($description); ?></p>
|
|
|
<?php endif; ?>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</section>
|
|
|
<style>
|
|
|
/* ===== Banner Title 现代化样式 ===== */
|
|
|
.nenghui-banner-title {
|
|
|
position: relative;
|
|
|
height: <?php echo esc_attr($height); ?>;
|
|
|
min-height: 600px;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
overflow: hidden;
|
|
|
color: #ffffff;
|
|
|
}
|
|
|
|
|
|
/* 背景层 */
|
|
|
.nenghui-banner-title .banner-background {
|
|
|
position: absolute;
|
|
|
top: 0;
|
|
|
left: 0;
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
z-index: 1;
|
|
|
}
|
|
|
|
|
|
.nenghui-banner-title .banner-image {
|
|
|
position: absolute;
|
|
|
top: 0;
|
|
|
left: 0;
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
background-size: cover;
|
|
|
background-position: center;
|
|
|
background-repeat: no-repeat;
|
|
|
background-attachment: scroll;
|
|
|
}
|
|
|
|
|
|
.nenghui-banner-title .banner-overlay {
|
|
|
position: absolute;
|
|
|
top: 0;
|
|
|
left: 0;
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
background: linear-gradient(135deg, rgba(44, 62, 80, 0.8) 0%, rgba(52, 73, 94, 0.6) 100%);
|
|
|
transition: opacity 0.3s ease;
|
|
|
}
|
|
|
|
|
|
/* 内容容器 */
|
|
|
.nenghui-banner-title .banner-container {
|
|
|
position: relative;
|
|
|
z-index: 3;
|
|
|
width: 100%;
|
|
|
max-width: 1320px;
|
|
|
padding: 0 20px;
|
|
|
}
|
|
|
|
|
|
.nenghui-banner-title .banner-content {
|
|
|
text-align: left;
|
|
|
}
|
|
|
|
|
|
/* 文字样式 */
|
|
|
.nenghui-banner-title .banner-title {
|
|
|
font-size: clamp(2.5rem, 5vw, 4rem);
|
|
|
font-weight: 700;
|
|
|
line-height: 1.2;
|
|
|
margin: 0 0 1.5rem 0;
|
|
|
letter-spacing: 3px;
|
|
|
color: #ffffff;
|
|
|
text-shadow: 2px 2px 8px rgba(0, 0, 0, 0.5);
|
|
|
}
|
|
|
|
|
|
.nenghui-banner-title .banner-description {
|
|
|
font-size: clamp(1rem, 2vw, 1.3rem);
|
|
|
line-height: 1.6;
|
|
|
margin: 0;
|
|
|
color: #ffffff;
|
|
|
text-shadow: 1px 1px 4px rgba(0, 0, 0, 0.5);
|
|
|
font-weight: 300;
|
|
|
max-width: 1320px;
|
|
|
}
|
|
|
/* 动画效果 */
|
|
|
.nenghui-banner-title.has-animation {
|
|
|
opacity: 0;
|
|
|
transform: translateY(50px);
|
|
|
transition: all 1s ease-out;
|
|
|
}
|
|
|
|
|
|
.nenghui-banner-title.has-animation.animated {
|
|
|
opacity: 1;
|
|
|
transform: translateY(0);
|
|
|
}
|
|
|
|
|
|
.nenghui-banner-title.has-animation .banner-title {
|
|
|
animation: fadeInUp 1.2s ease-out 0.3s both;
|
|
|
}
|
|
|
|
|
|
.nenghui-banner-title.has-animation .banner-description {
|
|
|
animation: fadeInUp 1.2s ease-out 0.6s both;
|
|
|
}
|
|
|
|
|
|
/* 响应式设计 */
|
|
|
@media (max-width: 768px) {
|
|
|
.nenghui-banner-title {
|
|
|
height: 50vh;
|
|
|
min-height: 350px;
|
|
|
}
|
|
|
|
|
|
.nenghui-banner-title .banner-title {
|
|
|
letter-spacing: 2px;
|
|
|
}
|
|
|
|
|
|
.nenghui-cases-section .container {
|
|
|
width: 100% !important;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@media (max-width: 480px) {
|
|
|
.nenghui-banner-title {
|
|
|
height: 40vh;
|
|
|
min-height: 300px;
|
|
|
}
|
|
|
|
|
|
.nenghui-banner-title .banner-container {
|
|
|
padding: 0 15px;
|
|
|
margin-top: 10rem;
|
|
|
}
|
|
|
|
|
|
.nenghui-banner-title .banner-title {
|
|
|
letter-spacing: 1px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 动画关键帧 */
|
|
|
@keyframes fadeInUp {
|
|
|
from {
|
|
|
opacity: 0;
|
|
|
transform: translateY(40px);
|
|
|
}
|
|
|
to {
|
|
|
opacity: 1;
|
|
|
transform: translateY(0);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 图片加载失败时的备用样式 */
|
|
|
.nenghui-banner-title.no-image .banner-image {
|
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
}
|
|
|
|
|
|
/* 高对比度模式支持 */
|
|
|
@media (prefers-contrast: high) {
|
|
|
.nenghui-banner-title .banner-overlay {
|
|
|
opacity: 0.8;
|
|
|
}
|
|
|
|
|
|
.nenghui-banner-title .banner-title {
|
|
|
text-shadow: 3px 3px 6px rgba(0, 0, 0, 0.8);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* 减少动画模式支持 */
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
|
.nenghui-banner-title .banner-image,
|
|
|
.nenghui-banner-title .banner-overlay,
|
|
|
.nenghui-banner-title.has-animation,
|
|
|
.nenghui-banner-title .banner-title,
|
|
|
.nenghui-banner-title .banner-description {
|
|
|
animation: none;
|
|
|
transition: none;
|
|
|
}
|
|
|
}
|
|
|
</style>
|
|
|
|
|
|
<script>
|
|
|
(function() {
|
|
|
'use strict';
|
|
|
|
|
|
// 检查基本环境
|
|
|
if (typeof document === 'undefined' || typeof window === 'undefined') {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 获取元素
|
|
|
const elementId = '<?php echo esc_js($element_id); ?>';
|
|
|
if (!elementId) {
|
|
|
console.warn('Banner element ID is missing');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
const bannerElement = document.getElementById(elementId);
|
|
|
if (!bannerElement) {
|
|
|
console.warn('Banner element not found:', elementId);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
const bgImage = '<?php echo esc_js($bg_image); ?>';
|
|
|
|
|
|
/**
|
|
|
* 图片预加载和错误处理
|
|
|
*/
|
|
|
function handleImageLoading() {
|
|
|
if (!bgImage || typeof Image === 'undefined') {
|
|
|
bannerElement.classList.add('no-image');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
const img = new Image();
|
|
|
|
|
|
img.onload = function() {
|
|
|
if (bannerElement) {
|
|
|
bannerElement.classList.remove('no-image');
|
|
|
}
|
|
|
};
|
|
|
|
|
|
img.onerror = function() {
|
|
|
if (bannerElement) {
|
|
|
bannerElement.classList.add('no-image');
|
|
|
}
|
|
|
console.warn('Banner background image failed to load:', bgImage);
|
|
|
};
|
|
|
|
|
|
img.src = bgImage;
|
|
|
} catch (error) {
|
|
|
console.warn('Error in image loading:', error);
|
|
|
bannerElement.classList.add('no-image');
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 滚动动画处理
|
|
|
*/
|
|
|
function handleScrollAnimation() {
|
|
|
if (!bannerElement.classList.contains('has-animation')) return;
|
|
|
|
|
|
// 检查 IntersectionObserver 兼容性
|
|
|
if (!window.IntersectionObserver) {
|
|
|
// 降级处理:直接添加动画类
|
|
|
bannerElement.classList.add('animated');
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
const observer = new IntersectionObserver(
|
|
|
function(entries) {
|
|
|
entries.forEach(function(entry) {
|
|
|
if (entry.isIntersecting) {
|
|
|
entry.target.classList.add('animated');
|
|
|
observer.unobserve(entry.target);
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
{
|
|
|
threshold: 0.1,
|
|
|
rootMargin: '0px 0px -50px 0px'
|
|
|
}
|
|
|
);
|
|
|
|
|
|
observer.observe(bannerElement);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化函数
|
|
|
function initBanner() {
|
|
|
handleImageLoading();
|
|
|
handleScrollAnimation();
|
|
|
}
|
|
|
|
|
|
// DOM 加载完成后初始化
|
|
|
if (document.readyState === 'loading') {
|
|
|
document.addEventListener('DOMContentLoaded', initBanner);
|
|
|
} else {
|
|
|
// DOM 已经加载完成,直接初始化
|
|
|
initBanner();
|
|
|
}
|
|
|
})();
|
|
|
</script>
|