You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

496 lines
14 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?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: 1300px;
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: 1300px;
}
/* 动画效果 */
.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>