var/cache/dev/twig/01/01e79143cf092d4c3d60a2ae714410cc.php line 40

Open in your IDE?
  1. <?php
  2. use Twig\Environment;
  3. use Twig\Error\LoaderError;
  4. use Twig\Error\RuntimeError;
  5. use Twig\Extension\SandboxExtension;
  6. use Twig\Markup;
  7. use Twig\Sandbox\SecurityError;
  8. use Twig\Sandbox\SecurityNotAllowedTagError;
  9. use Twig\Sandbox\SecurityNotAllowedFilterError;
  10. use Twig\Sandbox\SecurityNotAllowedFunctionError;
  11. use Twig\Source;
  12. use Twig\Template;
  13. /* index.twig */
  14. class __TwigTemplate_1288a8c934165619861e7a1b14d9faa4 extends \Eccube\Twig\Template
  15. {
  16.     private $source;
  17.     private $macros = [];
  18.     public function __construct(Environment $env)
  19.     {
  20.         parent::__construct($env);
  21.         $this->source $this->getSourceContext();
  22.         $this->blocks = [
  23.             'main' => [$this'block_main'],
  24.             'stylesheet' => [$this'block_stylesheet'],
  25.             'javascript' => [$this'block_javascript'],
  26.         ];
  27.     }
  28.     protected function doGetParent(array $context)
  29.     {
  30.         // line 1
  31.         return "default_frame.twig";
  32.     }
  33.     protected function doDisplay(array $context, array $blocks = [])
  34.     {
  35.         $macros $this->macros;
  36.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  37.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""index.twig"));
  38.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  39.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""index.twig"));
  40.         // line 2
  41.         $context["body_class"] = "front_page";
  42.         // line 1
  43.         $this->parent $this->loadTemplate("default_frame.twig""index.twig"1);
  44.         $this->parent->display($contextarray_merge($this->blocks$blocks));
  45.         
  46.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  47.         
  48.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  49.     }
  50.     // line 3
  51.     public function block_main($context, array $blocks = [])
  52.     {
  53.         $macros $this->macros;
  54.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  55.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""main"));
  56.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  57.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""main"));
  58.         // line 4
  59.         echo "<div class=\"mycarousel-wrapper\">
  60.     <div class=\"mycarousel-slider\">
  61.         ";
  62.         // line 7
  63.         echo "        ";
  64.         $context["pc_images"] = [=> "main-visual.jpg"=> "S__23207939.jpg"=> "NaiPC.jpg"=> "caPC.jpg"=> "panPC.jpg"];
  65.         // line 14
  66.         echo "        
  67.         ";
  68.         // line 16
  69.         echo "        ";
  70.         $context["sp_images"] = [=> "sp-topImages.jpg"=> "S__23224325.jpg"=> "NaiSP.jpg"=> "caSP.jpg"=> "panSP.jpg"];
  71.         // line 23
  72.         echo "        
  73.         ";
  74.         // line 25
  75.         echo "        ";
  76.         $context["link_urls"] = [=> "https://iseyabread.com/"=> "https://iseyabread.com/"=> "https://iseyabread.com/products/detail/10"=> "https://iseyabread.com/products/detail/7"=> "https://iseyabread.com/products/detail/9"];
  77.         // line 33
  78.         echo "        
  79.         ";
  80.         // line 35
  81.         echo "        ";
  82.         $context["link_targets"] = [=> "_self"=> "_self"=> "_self"=> "_self"=> "_self"];
  83.         // line 42
  84.         echo "        
  85.         ";
  86.         // line 44
  87.         echo "        ";
  88.         $context["display_images"] = [=> 0=> 1=> 2=> 3=> 4];
  89.         // line 45
  90.         echo "        
  91.         ";
  92.         // line 46
  93.         $context['_parent'] = $context;
  94.         $context['_seq'] = twig_ensure_traversable((isset($context["display_images"]) || array_key_exists("display_images"$context) ? $context["display_images"] : (function () { throw new RuntimeError('Variable "display_images" does not exist.'46$this->source); })()));
  95.         foreach ($context['_seq'] as $context["_key"] => $context["index"]) {
  96.             // line 47
  97.             echo "            <div class=\"mycarousel-slide\">
  98.                 ";
  99.             // line 48
  100.             if (twig_get_attribute($this->env$this->source, (isset($context["link_urls"]) || array_key_exists("link_urls"$context) ? $context["link_urls"] : (function () { throw new RuntimeError('Variable "link_urls" does not exist.'48$this->source); })()), $context["index"], [], "array"falsefalsefalse48)) {
  101.                 // line 49
  102.                 echo "                    <a href=\"";
  103.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, (isset($context["link_urls"]) || array_key_exists("link_urls"$context) ? $context["link_urls"] : (function () { throw new RuntimeError('Variable "link_urls" does not exist.'49$this->source); })()), $context["index"], [], "array"falsefalsefalse49), "html"nulltrue);
  104.                 echo "\" target=\"";
  105.                 (((twig_get_attribute($this->env$this->source, ($context["link_targets"] ?? null), $context["index"], [], "array"truetruefalse49) &&  !(null === twig_get_attribute($this->env$this->source, ($context["link_targets"] ?? null), $context["index"], [], "array"falsefalsefalse49)))) ? (print (twig_escape_filter($this->envtwig_get_attribute($this->env$this->source, ($context["link_targets"] ?? null), $context["index"], [], "array"falsefalsefalse49), "html"nulltrue))) : (print ("_self")));
  106.                 echo "\" class=\"carousel-link\">
  107.                         <img class=\"desktop-image\" src=\"";
  108.                 // line 50
  109.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl(("/html/user_data/ContentImg/" twig_get_attribute($this->env$this->source, (isset($context["pc_images"]) || array_key_exists("pc_images"$context) ? $context["pc_images"] : (function () { throw new RuntimeError('Variable "pc_images" does not exist.'50$this->source); })()), $context["index"], [], "array"falsefalsefalse50))), "html"nulltrue);
  110.                 echo "\" alt=\"スライド画像\">
  111.                         <img class=\"mobile-image\" src=\"";
  112.                 // line 51
  113.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl(("/html/user_data/ContentImg/" twig_get_attribute($this->env$this->source, (isset($context["sp_images"]) || array_key_exists("sp_images"$context) ? $context["sp_images"] : (function () { throw new RuntimeError('Variable "sp_images" does not exist.'51$this->source); })()), $context["index"], [], "array"falsefalsefalse51))), "html"nulltrue);
  114.                 echo "\" alt=\"スライド画像\">
  115.                     </a>
  116.                 ";
  117.             } else {
  118.                 // line 54
  119.                 echo "                    <img class=\"desktop-image\" src=\"";
  120.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl(("/html/user_data/ContentImg/" twig_get_attribute($this->env$this->source, (isset($context["pc_images"]) || array_key_exists("pc_images"$context) ? $context["pc_images"] : (function () { throw new RuntimeError('Variable "pc_images" does not exist.'54$this->source); })()), $context["index"], [], "array"falsefalsefalse54))), "html"nulltrue);
  121.                 echo "\" alt=\"スライド画像\">
  122.                     <img class=\"mobile-image\" src=\"";
  123.                 // line 55
  124.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl(("/html/user_data/ContentImg/" twig_get_attribute($this->env$this->source, (isset($context["sp_images"]) || array_key_exists("sp_images"$context) ? $context["sp_images"] : (function () { throw new RuntimeError('Variable "sp_images" does not exist.'55$this->source); })()), $context["index"], [], "array"falsefalsefalse55))), "html"nulltrue);
  125.                 echo "\" alt=\"スライド画像\">
  126.                 ";
  127.             }
  128.             // line 57
  129.             echo "            </div>
  130.         ";
  131.         }
  132.         $_parent $context['_parent'];
  133.         unset($context['_seq'], $context['_iterated'], $context['_key'], $context['index'], $context['_parent'], $context['loop']);
  134.         $context array_intersect_key($context$_parent) + $_parent;
  135.         // line 59
  136.         echo "    </div>
  137. </div>
  138. ";
  139.         
  140.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  141.         
  142.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  143.     }
  144.     // line 62
  145.     public function block_stylesheet($context, array $blocks = [])
  146.     {
  147.         $macros $this->macros;
  148.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  149.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""stylesheet"));
  150.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  151.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""stylesheet"));
  152.         // line 63
  153.         echo "<style>
  154. /* slickのデフォルト黒丸(before擬似要素)を無効化 */
  155. .mycarousel-slider .slick-dots li button::before {
  156.     display: none;
  157.     content: '';
  158. }
  159. .slick-dots li {
  160.     position:unset;
  161.     display: inline-block;
  162.     width: 20px;
  163.     height: 20px;
  164.     margin: 0 5px;
  165.     padding: 0;
  166.     cursor: pointer;
  167. }
  168. .mycarousel-slider .slick-dots li {
  169.     width: 10px;
  170.     height: 10px;
  171. }
  172. .mycarousel-slider .slick-dots li button {
  173.     width: 100%;
  174.     height: 100%;
  175.     padding: 0;
  176.     border: none;
  177.     border-radius: 50%;
  178.     background-color: #ccc;
  179.     opacity: 0.7;
  180.     transition: all 0.3s ease;
  181.     font-size: 0;
  182.     cursor: pointer;
  183. }
  184. .mycarousel-slider .slick-dots li.slick-active button {
  185.     background-color: #b8860b;
  186.     transform: scale(1.3);
  187.     opacity: 1;
  188. }
  189. /* カルーセルリンクのスタイル */
  190. .carousel-link {
  191.     display: block;
  192.     position: relative;
  193.     width: 100%;
  194.     height: 100%;
  195.     text-decoration: none;
  196.     cursor: pointer;
  197.     transition: opacity 0.3s ease;
  198. }
  199. .carousel-link:hover {
  200.     opacity: 0.9;
  201. }
  202. .mycarousel-wrapper {
  203.     width: 100vw;
  204.     max-width: none;
  205.     margin-left: calc(-50vw + 50%);
  206.     margin-right: calc(-50vw + 50%);
  207.     overflow: hidden;
  208.     padding: 0;
  209.     /* 初期化時のちらつき防止 */
  210.     visibility: hidden;
  211. }
  212. .slick-track {
  213.     display: flex !important;
  214.     align-items: center;
  215. }
  216. .slick-slide {
  217.     padding: 0 !important;
  218.     margin: 0 !important;
  219. }
  220. /* スライド本体(動的高さ対応) */
  221. .mycarousel-slide {
  222.     box-sizing: border-box;
  223.     padding: 0 !important;
  224.     margin: 0 !important;
  225.     position: relative;
  226.     transition: all 0.5s ease;
  227.     overflow: hidden;
  228.     height: 60vh; /* 初期値:JavaScript で調整される */
  229. }
  230. /* 画像の基本スタイル */
  231. .desktop-image,
  232. .mobile-image {
  233.     position: absolute;
  234.     top: 0;
  235.     left: 0;
  236.     width: 100%;
  237.     height: 100%;
  238.     transition: all 0.5s ease;
  239.     /* object-fit は JavaScript で動的に調整 */
  240.     object-fit: contain;
  241. }
  242. /* デスクトップ時のスタイル(768pxより大きい) */
  243. @media (min-width: 769px) {
  244.     .desktop-image {
  245.         display: block !important;
  246.     }
  247.     .mobile-image {
  248.         display: none !important;
  249.     }
  250. }
  251. /* モバイル時のスタイル(768px以下) */
  252. @media (max-width: 768px) {
  253.     .mycarousel-wrapper {
  254.         width: 100vw;
  255.         margin-left: calc(-50vw + 50%);
  256.         margin-right: calc(-50vw + 50%);
  257.     }
  258.     
  259.     .mycarousel-slide {
  260.         width: 100vw !important;
  261.         height: auto !important;
  262.         padding: 0 !important;
  263.         margin: 0 !important;
  264.         opacity: 1 !important;
  265.         filter: none !important;
  266.     }
  267.     .desktop-image {
  268.         display: none !important;
  269.     }
  270.     
  271.     .mobile-image {
  272.         display: block !important;
  273.         position: relative !important;
  274.         width: 100% !important;
  275.         height: auto !important;
  276.         object-fit: contain !important;
  277.         filter: brightness(1) contrast(1) !important;
  278.     }
  279. }
  280. /* 左右の画像を暗くするエフェクト(デスクトップのみ) */
  281. @media (min-width: 769px) {
  282.     .mycarousel-slide.side-slide {
  283.         opacity: 0.6;
  284.     }
  285.     .mycarousel-slide.side-slide .desktop-image {
  286.         filter: brightness(0.7) contrast(0.9);
  287.     }
  288.     .mycarousel-slide.center-slide {
  289.         opacity: 1;
  290.     }
  291.     .mycarousel-slide.center-slide .desktop-image {
  292.         filter: brightness(1) contrast(1);
  293.     }
  294.     .mycarousel-slide.side-slide:hover {
  295.         opacity: 0.8;
  296.         transform: scale(1.02);
  297.     }
  298.     .mycarousel-slide.side-slide:hover .desktop-image {
  299.         filter: brightness(0.85) contrast(0.95);
  300.     }
  301. }
  302. /* 動的高さ調整用のユーティリティクラス */
  303. .dynamic-fit-contain {
  304.     object-fit: contain;
  305. }
  306. .dynamic-fit-cover {
  307.     object-fit: cover;
  308. }
  309. </style>
  310. ";
  311.         
  312.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  313.         
  314.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  315.     }
  316.     // line 232
  317.     public function block_javascript($context, array $blocks = [])
  318.     {
  319.         $macros $this->macros;
  320.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  321.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""javascript"));
  322.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  323.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""javascript"));
  324.         // line 233
  325.         echo "<script>
  326. \$(function() {
  327.     // 動的レスポンシブ設定
  328.     const RESPONSIVE_CONFIG = {
  329.         desktop: {
  330.             targetAspectRatio: 16/9,
  331.             minHeight: '30vh',
  332.             maxHeight: '60vh',
  333.             marginThreshold: 0.15
  334.         },
  335.         mobile: {
  336.             targetAspectRatio: 4/3,
  337.             minHeight: '35vh',
  338.             maxHeight: '85vh',
  339.             marginThreshold: 0.12
  340.         }
  341.     };
  342.     let isInitialized = false;
  343.     let currentImages = [];
  344.     // 画面幅に応じた動的centerPadding計算
  345.     function calculateCenterPadding() {
  346.         const windowWidth = \$(window).width();
  347.         let padding;
  348.         
  349.         // 画面幅に応じてcenterPaddingを計算(調整可能な閾値)
  350.         if (windowWidth <= 768) {
  351.             // モバイル: 余白なし
  352.             padding = '0';
  353.         } else if (windowWidth <= 1024) {
  354.             // タブレット: 小さめの余白
  355.             padding = '8vw';
  356.         } else if (windowWidth <= 1200) {
  357.             // 小型デスクトップ: 中程度の余白
  358.             padding = '12vw';
  359.         }else if (windowWidth <= 1440) {
  360.             // 小型デスクトップ: 中程度の余白
  361.             padding = '15vw';
  362.         
  363.         } else if (windowWidth <= 1920) {
  364.             // 標準デスクトップ: やや大きめの余白
  365.             padding = '20vw';
  366.         } else {
  367.             // 大型ディスプレイ: 最大余白を制限
  368.             padding = '25vw';
  369.         }
  370.         
  371.         return padding;
  372.     }
  373.     // centerPaddingを動的に更新する関数
  374.     function updateCenterPadding() {
  375.         const newPadding = calculateCenterPadding();
  376.         const windowWidth = \$(window).width();
  377.         
  378.         // モバイルはcenterMode自体を無効にする
  379.         const centerModeEnabled = windowWidth > 768;
  380.         
  381.         if (\$('.mycarousel-slider').hasClass('slick-initialized')) {
  382.             \$('.mycarousel-slider').slick('slickSetOption', 'centerMode', centerModeEnabled, false);
  383.             \$('.mycarousel-slider').slick('slickSetOption', 'centerPadding', newPadding, true);
  384.         }
  385.     }
  386.     // 現在のデバイスに応じた画像を取得
  387.     function getCurrentImages() {
  388.         const isMobile = \$(window).width() <= 768;
  389.         return isMobile ? \$('.mobile-image') : \$('.desktop-image');
  390.     }
  391.     // 画像プリロード関数
  392.     function preloadImages() {
  393.         return new Promise((resolve) => {
  394.             const images = getCurrentImages();
  395.             let loadedCount = 0;
  396.             const totalImages = images.length;
  397.             if (totalImages === 0) {
  398.                 resolve();
  399.                 return;
  400.             }
  401.             images.each(function() {
  402.                 const img = this;
  403.                 
  404.                 if (img.complete && img.naturalWidth > 0) {
  405.                     loadedCount++;
  406.                     if (loadedCount >= totalImages) {
  407.                         resolve();
  408.                     }
  409.                 } else {
  410.                     \$(img).on('load error', function() {
  411.                         loadedCount++;
  412.                         if (loadedCount >= totalImages) {
  413.                             resolve();
  414.                         }
  415.                     });
  416.                     
  417.                     // 強制的に再読み込みをトリガー(キャッシュ対策)
  418.                     if (!img.src) {
  419.                         img.src = img.getAttribute('src');
  420.                     }
  421.                 }
  422.             });
  423.         });
  424.     }
  425.     // スライダー初期化(動的centerPadding対応版)
  426.     function initializeSlider() {
  427.         if (\$('.mycarousel-slider').hasClass('slick-initialized')) {
  428.             \$('.mycarousel-slider').slick('unslick');
  429.         }
  430.         const initialPadding = calculateCenterPadding();
  431.         const windowWidth = \$(window).width();
  432.         const centerModeEnabled = windowWidth > 768;
  433.         \$('.mycarousel-slider').slick({
  434.             centerMode: centerModeEnabled,
  435.             centerPadding: initialPadding,
  436.             slidesToShow: 1,
  437.             autoplay: false, // 初期化時は自動再生を無効にして安定性を確保
  438.             autoplaySpeed: 5000,
  439.             arrows: true,
  440.             dots: true,
  441.             adaptiveHeight: false,
  442.             fade: false,
  443.             speed: 300
  444.             // responsive設定は削除(動的制御に切り替え)
  445.         });
  446.         // スライド変更時にクラスを更新
  447.         \$('.mycarousel-slider').on('afterChange', function(event, slick, currentSlide) {
  448.             updateSlideClasses();
  449.         });
  450.     }
  451.     // 動的な表示最適化メイン関数
  452.     function optimizeCarouselDisplay() {
  453.         const isMobile = \$(window).width() <= 768;
  454.         const config = isMobile ? RESPONSIVE_CONFIG.mobile : RESPONSIVE_CONFIG.desktop;
  455.         const \$currentImages = getCurrentImages();
  456.         
  457.         if (\$currentImages.length === 0) return;
  458.         // モバイル時は簡単な設定にする
  459.         if (isMobile) {
  460.             // モバイル時:width 100vw、height auto
  461.             \$('.mycarousel-slide').css({
  462.                 'height': 'auto',
  463.                 'width': '100vw'
  464.             });
  465.             \$currentImages.css({
  466.                 'width': '100%',
  467.                 'height': 'auto',
  468.                 'object-fit': 'contain',
  469.                 'position': 'relative'
  470.             });
  471.             
  472.             // 初期化完了後に自動再生を開始
  473.             if (isInitialized && \$('.mycarousel-slider').slick('slickGetOption', 'autoplay') === false) {
  474.                 \$('.mycarousel-slider').slick('slickSetOption', 'autoplay', true, true);
  475.             }
  476.             return;
  477.         }
  478.         const \$firstImage = \$currentImages.filter(':visible').first();
  479.         if (\$firstImage.length === 0 || !\$firstImage[0].complete || !\$firstImage[0].naturalWidth) {
  480.             return;
  481.         }
  482.         const imageWidth = \$firstImage[0].naturalWidth;
  483.         const imageHeight = \$firstImage[0].naturalHeight;
  484.         const imageAspectRatio = imageWidth / imageHeight;
  485.         
  486.         const containerWidth = \$('.mycarousel-wrapper').width();
  487.         const containerAspectRatio = config.targetAspectRatio;
  488.         
  489.         const maxRenderWidth = Math.min(imageWidth, containerWidth);
  490.         const maxRenderHeight = maxRenderWidth / imageAspectRatio;
  491.         
  492.         const viewportMinHeightPx = parseFloat(config.minHeight) * \$(window).height() / 100;
  493.         const viewportMaxHeightPx = parseFloat(config.maxHeight) * \$(window).height() / 100;
  494.         
  495.         let optimalHeight;
  496.         let objectFitMode = 'contain';
  497.         const aspectRatioDiff = Math.abs(imageAspectRatio - containerAspectRatio) / containerAspectRatio;
  498.         if (maxRenderHeight <= viewportMaxHeightPx && maxRenderHeight >= viewportMinHeightPx) {
  499.             optimalHeight = maxRenderHeight;
  500.         } else if (maxRenderHeight > viewportMaxHeightPx) {
  501.             if (aspectRatioDiff <= config.marginThreshold) {
  502.                 optimalHeight = viewportMaxHeightPx;
  503.             } else {
  504.                 optimalHeight = Math.min(containerWidth / imageAspectRatio, viewportMaxHeightPx);
  505.             }
  506.         } else {
  507.             if (maxRenderHeight < viewportMinHeightPx) {
  508.                 const scaleUpLimit = Math.min(2.0, viewportMinHeightPx / maxRenderHeight);
  509.                 if (scaleUpLimit <= 1.5) {
  510.                     optimalHeight = viewportMinHeightPx;
  511.                 } else {
  512.                     optimalHeight = maxRenderHeight;
  513.                 }
  514.             } else {
  515.                 optimalHeight = maxRenderHeight;
  516.             }
  517.         }
  518.         // 最終的な制限適用
  519.         optimalHeight = Math.max(viewportMinHeightPx, Math.min(viewportMaxHeightPx, optimalHeight));
  520.         // 画像の品質を考慮したobject-fit調整
  521.         const renderScale = optimalHeight / maxRenderHeight;
  522.         if (renderScale > 1.2) {
  523.             objectFitMode = 'contain';
  524.         } else {
  525.             objectFitMode = 'contain';
  526.         }
  527.         // スタイル適用(デスクトップのみ)
  528.         \$('.mycarousel-slide').css('height', optimalHeight + 'px');
  529.         \$currentImages.css({
  530.             'object-fit': objectFitMode,
  531.             'image-rendering': renderScale > 1.1 ? 'smooth' : 'auto'
  532.         });
  533.         // 初期化完了後に自動再生を開始
  534.         if (isInitialized && \$('.mycarousel-slider').slick('slickGetOption', 'autoplay') === false) {
  535.             \$('.mycarousel-slider').slick('slickSetOption', 'autoplay', true, true);
  536.         }
  537.     }
  538.     // スライドのクラスを更新する関数
  539.     function updateSlideClasses() {
  540.         \$('.mycarousel-slide').removeClass('center-slide side-slide');
  541.         
  542.         if (\$(window).width() > 768) {
  543.             \$('.slick-center .mycarousel-slide').addClass('center-slide');
  544.             \$('.slick-slide:not(.slick-center) .mycarousel-slide').addClass('side-slide');
  545.         } else {
  546.             \$('.mycarousel-slide').addClass('center-slide');
  547.         }
  548.     }
  549.     async function initialize() {
  550.         try {
  551.             // カルーセルを一時的に非表示にしてちらつき防止
  552.             \$('.mycarousel-wrapper').css('visibility', 'hidden');
  553.             
  554.             await preloadImages();
  555.             
  556.             initializeSlider();
  557.             
  558.             optimizeCarouselDisplay();
  559.             
  560.             updateSlideClasses();
  561.             
  562.             isInitialized = true;
  563.             
  564.             // 6. 少し待ってから表示(slickの初期化完了を確実にする)
  565.             setTimeout(() => {
  566.                 \$('.mycarousel-wrapper').css('visibility', 'visible');
  567.                 // 初期化後にもう一度表示を最適化
  568.                 optimizeCarouselDisplay();
  569.                 updateSlideClasses();
  570.             }, 50);
  571.             
  572.             console.log('Carousel initialized successfully');
  573.             
  574.         } catch (error) {
  575.             console.error('Carousel initialization failed:', error);
  576.             // エラー時も表示を戻す
  577.             \$('.mycarousel-wrapper').css('visibility', 'visible');
  578.         }
  579.     }
  580.     let resizeTimer;
  581.     \$(window).on('resize', function() {
  582.         clearTimeout(resizeTimer);
  583.         resizeTimer = setTimeout(async () => {
  584.             // centerPaddingを動的に更新
  585.             updateCenterPadding();
  586.             
  587.             // デバイス切り替わり時は再初期化
  588.             const newImages = getCurrentImages();
  589.             const imagesSwitched = !currentImages.length || 
  590.                 newImages.length !== currentImages.length ||
  591.                 newImages[0] !== currentImages[0];
  592.             
  593.             if (imagesSwitched) {
  594.                 currentImages = newImages;
  595.                 await preloadImages();
  596.             }
  597.             
  598.             optimizeCarouselDisplay();
  599.             updateSlideClasses();
  600.         }, 200);
  601.     });
  602.     
  603.     \$(document).ready(function() {
  604.         currentImages = getCurrentImages();
  605.         initialize();
  606.     });
  607.     
  608.     \$(window).on('load', function() {
  609.         if (!isInitialized) {
  610.             initialize();
  611.         }
  612.     });
  613. });
  614. </script>
  615. ";
  616.         
  617.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  618.         
  619.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  620.     }
  621.     public function getTemplateName()
  622.     {
  623.         return "index.twig";
  624.     }
  625.     public function isTraitable()
  626.     {
  627.         return false;
  628.     }
  629.     public function getDebugInfo()
  630.     {
  631.         return array (  360 => 233,  350 => 232,  172 => 63,  162 => 62,  150 => 59,  143 => 57,  138 => 55,  133 => 54,  127 => 51,  123 => 50,  116 => 49,  114 => 48,  111 => 47,  107 => 46,  104 => 45,  101 => 44,  98 => 42,  95 => 35,  92 => 33,  89 => 25,  86 => 23,  83 => 16,  80 => 14,  77 => 7,  73 => 4,  63 => 3,  52 => 1,  50 => 2,  37 => 1,);
  632.     }
  633.     public function getSourceContext()
  634.     {
  635.         return new Source("{% extends 'default_frame.twig' %}
  636. {% set body_class = 'front_page' %}
  637. {% block main %}
  638. <div class=\"mycarousel-wrapper\">
  639.     <div class=\"mycarousel-slider\">
  640.         {# PC用画像リスト #}
  641.         {% set pc_images = [
  642.             'main-visual.jpg',
  643.             'S__23207939.jpg',
  644.             'NaiPC.jpg',
  645.             'caPC.jpg',
  646.             'panPC.jpg'
  647.         ] %}
  648.         
  649.         {# SP用画像リスト #}
  650.         {% set sp_images = [
  651.             'sp-topImages.jpg',
  652.             'S__23224325.jpg',
  653.             'NaiSP.jpg',
  654.             'caSP.jpg',
  655.             'panSP.jpg'
  656.         ] %}
  657.         
  658.         {# リンク先URLリスト(画像の順番に対応) #}
  659.         {% set link_urls = [
  660.             'https://iseyabread.com/',
  661.             'https://iseyabread.com/',
  662.             'https://iseyabread.com/products/detail/10',
  663.             'https://iseyabread.com/products/detail/7',            
  664.             'https://iseyabread.com/products/detail/9'
  665.         
  666.         ] %}
  667.         
  668.         {# リンクターゲット設定(_self: 同じタブ, _blank: 新しいタブ) #}
  669.         {% set link_targets = [
  670.             '_self',
  671.             '_self',
  672.             '_self',            
  673.             '_self',            
  674.             '_self',
  675.         ] %}
  676.         
  677.         {# 実際に表示する画像を選択(0から始まるインデックス番号で指定) #}
  678.         {% set display_images = [0,1,2,3,4] %}
  679.         
  680.         {% for index in display_images %}
  681.             <div class=\"mycarousel-slide\">
  682.                 {% if link_urls[index] %}
  683.                     <a href=\"{{ link_urls[index] }}\" target=\"{{ link_targets[index] ?? '_self' }}\" class=\"carousel-link\">
  684.                         <img class=\"desktop-image\" src=\"{{ asset('/html/user_data/ContentImg/' ~ pc_images[index]) }}\" alt=\"スライド画像\">
  685.                         <img class=\"mobile-image\" src=\"{{ asset('/html/user_data/ContentImg/' ~ sp_images[index]) }}\" alt=\"スライド画像\">
  686.                     </a>
  687.                 {% else %}
  688.                     <img class=\"desktop-image\" src=\"{{ asset('/html/user_data/ContentImg/' ~ pc_images[index]) }}\" alt=\"スライド画像\">
  689.                     <img class=\"mobile-image\" src=\"{{ asset('/html/user_data/ContentImg/' ~ sp_images[index]) }}\" alt=\"スライド画像\">
  690.                 {% endif %}
  691.             </div>
  692.         {% endfor %}
  693.     </div>
  694. </div>
  695. {% endblock %}
  696. {% block stylesheet %}
  697. <style>
  698. /* slickのデフォルト黒丸(before擬似要素)を無効化 */
  699. .mycarousel-slider .slick-dots li button::before {
  700.     display: none;
  701.     content: '';
  702. }
  703. .slick-dots li {
  704.     position:unset;
  705.     display: inline-block;
  706.     width: 20px;
  707.     height: 20px;
  708.     margin: 0 5px;
  709.     padding: 0;
  710.     cursor: pointer;
  711. }
  712. .mycarousel-slider .slick-dots li {
  713.     width: 10px;
  714.     height: 10px;
  715. }
  716. .mycarousel-slider .slick-dots li button {
  717.     width: 100%;
  718.     height: 100%;
  719.     padding: 0;
  720.     border: none;
  721.     border-radius: 50%;
  722.     background-color: #ccc;
  723.     opacity: 0.7;
  724.     transition: all 0.3s ease;
  725.     font-size: 0;
  726.     cursor: pointer;
  727. }
  728. .mycarousel-slider .slick-dots li.slick-active button {
  729.     background-color: #b8860b;
  730.     transform: scale(1.3);
  731.     opacity: 1;
  732. }
  733. /* カルーセルリンクのスタイル */
  734. .carousel-link {
  735.     display: block;
  736.     position: relative;
  737.     width: 100%;
  738.     height: 100%;
  739.     text-decoration: none;
  740.     cursor: pointer;
  741.     transition: opacity 0.3s ease;
  742. }
  743. .carousel-link:hover {
  744.     opacity: 0.9;
  745. }
  746. .mycarousel-wrapper {
  747.     width: 100vw;
  748.     max-width: none;
  749.     margin-left: calc(-50vw + 50%);
  750.     margin-right: calc(-50vw + 50%);
  751.     overflow: hidden;
  752.     padding: 0;
  753.     /* 初期化時のちらつき防止 */
  754.     visibility: hidden;
  755. }
  756. .slick-track {
  757.     display: flex !important;
  758.     align-items: center;
  759. }
  760. .slick-slide {
  761.     padding: 0 !important;
  762.     margin: 0 !important;
  763. }
  764. /* スライド本体(動的高さ対応) */
  765. .mycarousel-slide {
  766.     box-sizing: border-box;
  767.     padding: 0 !important;
  768.     margin: 0 !important;
  769.     position: relative;
  770.     transition: all 0.5s ease;
  771.     overflow: hidden;
  772.     height: 60vh; /* 初期値:JavaScript で調整される */
  773. }
  774. /* 画像の基本スタイル */
  775. .desktop-image,
  776. .mobile-image {
  777.     position: absolute;
  778.     top: 0;
  779.     left: 0;
  780.     width: 100%;
  781.     height: 100%;
  782.     transition: all 0.5s ease;
  783.     /* object-fit は JavaScript で動的に調整 */
  784.     object-fit: contain;
  785. }
  786. /* デスクトップ時のスタイル(768pxより大きい) */
  787. @media (min-width: 769px) {
  788.     .desktop-image {
  789.         display: block !important;
  790.     }
  791.     .mobile-image {
  792.         display: none !important;
  793.     }
  794. }
  795. /* モバイル時のスタイル(768px以下) */
  796. @media (max-width: 768px) {
  797.     .mycarousel-wrapper {
  798.         width: 100vw;
  799.         margin-left: calc(-50vw + 50%);
  800.         margin-right: calc(-50vw + 50%);
  801.     }
  802.     
  803.     .mycarousel-slide {
  804.         width: 100vw !important;
  805.         height: auto !important;
  806.         padding: 0 !important;
  807.         margin: 0 !important;
  808.         opacity: 1 !important;
  809.         filter: none !important;
  810.     }
  811.     .desktop-image {
  812.         display: none !important;
  813.     }
  814.     
  815.     .mobile-image {
  816.         display: block !important;
  817.         position: relative !important;
  818.         width: 100% !important;
  819.         height: auto !important;
  820.         object-fit: contain !important;
  821.         filter: brightness(1) contrast(1) !important;
  822.     }
  823. }
  824. /* 左右の画像を暗くするエフェクト(デスクトップのみ) */
  825. @media (min-width: 769px) {
  826.     .mycarousel-slide.side-slide {
  827.         opacity: 0.6;
  828.     }
  829.     .mycarousel-slide.side-slide .desktop-image {
  830.         filter: brightness(0.7) contrast(0.9);
  831.     }
  832.     .mycarousel-slide.center-slide {
  833.         opacity: 1;
  834.     }
  835.     .mycarousel-slide.center-slide .desktop-image {
  836.         filter: brightness(1) contrast(1);
  837.     }
  838.     .mycarousel-slide.side-slide:hover {
  839.         opacity: 0.8;
  840.         transform: scale(1.02);
  841.     }
  842.     .mycarousel-slide.side-slide:hover .desktop-image {
  843.         filter: brightness(0.85) contrast(0.95);
  844.     }
  845. }
  846. /* 動的高さ調整用のユーティリティクラス */
  847. .dynamic-fit-contain {
  848.     object-fit: contain;
  849. }
  850. .dynamic-fit-cover {
  851.     object-fit: cover;
  852. }
  853. </style>
  854. {% endblock %}
  855. {% block javascript %}
  856. <script>
  857. \$(function() {
  858.     // 動的レスポンシブ設定
  859.     const RESPONSIVE_CONFIG = {
  860.         desktop: {
  861.             targetAspectRatio: 16/9,
  862.             minHeight: '30vh',
  863.             maxHeight: '60vh',
  864.             marginThreshold: 0.15
  865.         },
  866.         mobile: {
  867.             targetAspectRatio: 4/3,
  868.             minHeight: '35vh',
  869.             maxHeight: '85vh',
  870.             marginThreshold: 0.12
  871.         }
  872.     };
  873.     let isInitialized = false;
  874.     let currentImages = [];
  875.     // 画面幅に応じた動的centerPadding計算
  876.     function calculateCenterPadding() {
  877.         const windowWidth = \$(window).width();
  878.         let padding;
  879.         
  880.         // 画面幅に応じてcenterPaddingを計算(調整可能な閾値)
  881.         if (windowWidth <= 768) {
  882.             // モバイル: 余白なし
  883.             padding = '0';
  884.         } else if (windowWidth <= 1024) {
  885.             // タブレット: 小さめの余白
  886.             padding = '8vw';
  887.         } else if (windowWidth <= 1200) {
  888.             // 小型デスクトップ: 中程度の余白
  889.             padding = '12vw';
  890.         }else if (windowWidth <= 1440) {
  891.             // 小型デスクトップ: 中程度の余白
  892.             padding = '15vw';
  893.         
  894.         } else if (windowWidth <= 1920) {
  895.             // 標準デスクトップ: やや大きめの余白
  896.             padding = '20vw';
  897.         } else {
  898.             // 大型ディスプレイ: 最大余白を制限
  899.             padding = '25vw';
  900.         }
  901.         
  902.         return padding;
  903.     }
  904.     // centerPaddingを動的に更新する関数
  905.     function updateCenterPadding() {
  906.         const newPadding = calculateCenterPadding();
  907.         const windowWidth = \$(window).width();
  908.         
  909.         // モバイルはcenterMode自体を無効にする
  910.         const centerModeEnabled = windowWidth > 768;
  911.         
  912.         if (\$('.mycarousel-slider').hasClass('slick-initialized')) {
  913.             \$('.mycarousel-slider').slick('slickSetOption', 'centerMode', centerModeEnabled, false);
  914.             \$('.mycarousel-slider').slick('slickSetOption', 'centerPadding', newPadding, true);
  915.         }
  916.     }
  917.     // 現在のデバイスに応じた画像を取得
  918.     function getCurrentImages() {
  919.         const isMobile = \$(window).width() <= 768;
  920.         return isMobile ? \$('.mobile-image') : \$('.desktop-image');
  921.     }
  922.     // 画像プリロード関数
  923.     function preloadImages() {
  924.         return new Promise((resolve) => {
  925.             const images = getCurrentImages();
  926.             let loadedCount = 0;
  927.             const totalImages = images.length;
  928.             if (totalImages === 0) {
  929.                 resolve();
  930.                 return;
  931.             }
  932.             images.each(function() {
  933.                 const img = this;
  934.                 
  935.                 if (img.complete && img.naturalWidth > 0) {
  936.                     loadedCount++;
  937.                     if (loadedCount >= totalImages) {
  938.                         resolve();
  939.                     }
  940.                 } else {
  941.                     \$(img).on('load error', function() {
  942.                         loadedCount++;
  943.                         if (loadedCount >= totalImages) {
  944.                             resolve();
  945.                         }
  946.                     });
  947.                     
  948.                     // 強制的に再読み込みをトリガー(キャッシュ対策)
  949.                     if (!img.src) {
  950.                         img.src = img.getAttribute('src');
  951.                     }
  952.                 }
  953.             });
  954.         });
  955.     }
  956.     // スライダー初期化(動的centerPadding対応版)
  957.     function initializeSlider() {
  958.         if (\$('.mycarousel-slider').hasClass('slick-initialized')) {
  959.             \$('.mycarousel-slider').slick('unslick');
  960.         }
  961.         const initialPadding = calculateCenterPadding();
  962.         const windowWidth = \$(window).width();
  963.         const centerModeEnabled = windowWidth > 768;
  964.         \$('.mycarousel-slider').slick({
  965.             centerMode: centerModeEnabled,
  966.             centerPadding: initialPadding,
  967.             slidesToShow: 1,
  968.             autoplay: false, // 初期化時は自動再生を無効にして安定性を確保
  969.             autoplaySpeed: 5000,
  970.             arrows: true,
  971.             dots: true,
  972.             adaptiveHeight: false,
  973.             fade: false,
  974.             speed: 300
  975.             // responsive設定は削除(動的制御に切り替え)
  976.         });
  977.         // スライド変更時にクラスを更新
  978.         \$('.mycarousel-slider').on('afterChange', function(event, slick, currentSlide) {
  979.             updateSlideClasses();
  980.         });
  981.     }
  982.     // 動的な表示最適化メイン関数
  983.     function optimizeCarouselDisplay() {
  984.         const isMobile = \$(window).width() <= 768;
  985.         const config = isMobile ? RESPONSIVE_CONFIG.mobile : RESPONSIVE_CONFIG.desktop;
  986.         const \$currentImages = getCurrentImages();
  987.         
  988.         if (\$currentImages.length === 0) return;
  989.         // モバイル時は簡単な設定にする
  990.         if (isMobile) {
  991.             // モバイル時:width 100vw、height auto
  992.             \$('.mycarousel-slide').css({
  993.                 'height': 'auto',
  994.                 'width': '100vw'
  995.             });
  996.             \$currentImages.css({
  997.                 'width': '100%',
  998.                 'height': 'auto',
  999.                 'object-fit': 'contain',
  1000.                 'position': 'relative'
  1001.             });
  1002.             
  1003.             // 初期化完了後に自動再生を開始
  1004.             if (isInitialized && \$('.mycarousel-slider').slick('slickGetOption', 'autoplay') === false) {
  1005.                 \$('.mycarousel-slider').slick('slickSetOption', 'autoplay', true, true);
  1006.             }
  1007.             return;
  1008.         }
  1009.         const \$firstImage = \$currentImages.filter(':visible').first();
  1010.         if (\$firstImage.length === 0 || !\$firstImage[0].complete || !\$firstImage[0].naturalWidth) {
  1011.             return;
  1012.         }
  1013.         const imageWidth = \$firstImage[0].naturalWidth;
  1014.         const imageHeight = \$firstImage[0].naturalHeight;
  1015.         const imageAspectRatio = imageWidth / imageHeight;
  1016.         
  1017.         const containerWidth = \$('.mycarousel-wrapper').width();
  1018.         const containerAspectRatio = config.targetAspectRatio;
  1019.         
  1020.         const maxRenderWidth = Math.min(imageWidth, containerWidth);
  1021.         const maxRenderHeight = maxRenderWidth / imageAspectRatio;
  1022.         
  1023.         const viewportMinHeightPx = parseFloat(config.minHeight) * \$(window).height() / 100;
  1024.         const viewportMaxHeightPx = parseFloat(config.maxHeight) * \$(window).height() / 100;
  1025.         
  1026.         let optimalHeight;
  1027.         let objectFitMode = 'contain';
  1028.         const aspectRatioDiff = Math.abs(imageAspectRatio - containerAspectRatio) / containerAspectRatio;
  1029.         if (maxRenderHeight <= viewportMaxHeightPx && maxRenderHeight >= viewportMinHeightPx) {
  1030.             optimalHeight = maxRenderHeight;
  1031.         } else if (maxRenderHeight > viewportMaxHeightPx) {
  1032.             if (aspectRatioDiff <= config.marginThreshold) {
  1033.                 optimalHeight = viewportMaxHeightPx;
  1034.             } else {
  1035.                 optimalHeight = Math.min(containerWidth / imageAspectRatio, viewportMaxHeightPx);
  1036.             }
  1037.         } else {
  1038.             if (maxRenderHeight < viewportMinHeightPx) {
  1039.                 const scaleUpLimit = Math.min(2.0, viewportMinHeightPx / maxRenderHeight);
  1040.                 if (scaleUpLimit <= 1.5) {
  1041.                     optimalHeight = viewportMinHeightPx;
  1042.                 } else {
  1043.                     optimalHeight = maxRenderHeight;
  1044.                 }
  1045.             } else {
  1046.                 optimalHeight = maxRenderHeight;
  1047.             }
  1048.         }
  1049.         // 最終的な制限適用
  1050.         optimalHeight = Math.max(viewportMinHeightPx, Math.min(viewportMaxHeightPx, optimalHeight));
  1051.         // 画像の品質を考慮したobject-fit調整
  1052.         const renderScale = optimalHeight / maxRenderHeight;
  1053.         if (renderScale > 1.2) {
  1054.             objectFitMode = 'contain';
  1055.         } else {
  1056.             objectFitMode = 'contain';
  1057.         }
  1058.         // スタイル適用(デスクトップのみ)
  1059.         \$('.mycarousel-slide').css('height', optimalHeight + 'px');
  1060.         \$currentImages.css({
  1061.             'object-fit': objectFitMode,
  1062.             'image-rendering': renderScale > 1.1 ? 'smooth' : 'auto'
  1063.         });
  1064.         // 初期化完了後に自動再生を開始
  1065.         if (isInitialized && \$('.mycarousel-slider').slick('slickGetOption', 'autoplay') === false) {
  1066.             \$('.mycarousel-slider').slick('slickSetOption', 'autoplay', true, true);
  1067.         }
  1068.     }
  1069.     // スライドのクラスを更新する関数
  1070.     function updateSlideClasses() {
  1071.         \$('.mycarousel-slide').removeClass('center-slide side-slide');
  1072.         
  1073.         if (\$(window).width() > 768) {
  1074.             \$('.slick-center .mycarousel-slide').addClass('center-slide');
  1075.             \$('.slick-slide:not(.slick-center) .mycarousel-slide').addClass('side-slide');
  1076.         } else {
  1077.             \$('.mycarousel-slide').addClass('center-slide');
  1078.         }
  1079.     }
  1080.     async function initialize() {
  1081.         try {
  1082.             // カルーセルを一時的に非表示にしてちらつき防止
  1083.             \$('.mycarousel-wrapper').css('visibility', 'hidden');
  1084.             
  1085.             await preloadImages();
  1086.             
  1087.             initializeSlider();
  1088.             
  1089.             optimizeCarouselDisplay();
  1090.             
  1091.             updateSlideClasses();
  1092.             
  1093.             isInitialized = true;
  1094.             
  1095.             // 6. 少し待ってから表示(slickの初期化完了を確実にする)
  1096.             setTimeout(() => {
  1097.                 \$('.mycarousel-wrapper').css('visibility', 'visible');
  1098.                 // 初期化後にもう一度表示を最適化
  1099.                 optimizeCarouselDisplay();
  1100.                 updateSlideClasses();
  1101.             }, 50);
  1102.             
  1103.             console.log('Carousel initialized successfully');
  1104.             
  1105.         } catch (error) {
  1106.             console.error('Carousel initialization failed:', error);
  1107.             // エラー時も表示を戻す
  1108.             \$('.mycarousel-wrapper').css('visibility', 'visible');
  1109.         }
  1110.     }
  1111.     let resizeTimer;
  1112.     \$(window).on('resize', function() {
  1113.         clearTimeout(resizeTimer);
  1114.         resizeTimer = setTimeout(async () => {
  1115.             // centerPaddingを動的に更新
  1116.             updateCenterPadding();
  1117.             
  1118.             // デバイス切り替わり時は再初期化
  1119.             const newImages = getCurrentImages();
  1120.             const imagesSwitched = !currentImages.length || 
  1121.                 newImages.length !== currentImages.length ||
  1122.                 newImages[0] !== currentImages[0];
  1123.             
  1124.             if (imagesSwitched) {
  1125.                 currentImages = newImages;
  1126.                 await preloadImages();
  1127.             }
  1128.             
  1129.             optimizeCarouselDisplay();
  1130.             updateSlideClasses();
  1131.         }, 200);
  1132.     });
  1133.     
  1134.     \$(document).ready(function() {
  1135.         currentImages = getCurrentImages();
  1136.         initialize();
  1137.     });
  1138.     
  1139.     \$(window).on('load', function() {
  1140.         if (!isInitialized) {
  1141.             initialize();
  1142.         }
  1143.     });
  1144. });
  1145. </script>
  1146. {% endblock %}""index.twig""/home/iseyabread/www/iseya/app/template/default/index.twig");
  1147.     }
  1148. }