見出し画像

【無料配布】FANZA同人商品情報ボードのコード(※)

ども、目が覚めると太ももがジンジンするので、病院でレントゲンを撮ったらアングル的な関係で、タマタマっぽいのも映っていて「看護師さんにも見られたのかな?」と思ったデコポンです。

と、いうわけで以下↓商材を購入した方向けの専用コードを無料で配布します。


コードの基本スペック

FANZA同人記事を生成した際に以下の項目がボード内に記述されます。

  • 商品タイトル

  • サークル名

  • 品番

  • ページ数

  • シリーズ

  • ジャンル

振り分け機能

シリーズがないVer.

「シリーズ」に関しては「存在する・しない」という条件によって「表示される、されない」といった感じで、振り分ける仕様になっています。

シリーズがあるVer.

スマホユーザーにも「こいつ動くぞ!?」と思わせるギミック

グリグリ

普通のテーブル表なんて見飽きている人も多いと思うので、ちょっと立体感を出しつつ、アクセスユーザー側に主導権を握らせるような。アクション性が最大のポイントです。

グリグリ動く

百聞は一見にしかず、の言葉通り、実際にコードを試してもらって、指先やマウスでグリグリと動かしてみてください。

スクロールに合わせてお辞儀する

通常、商品ボードが動くなんて思わないのが、当たり前です。

スルーされるのも悲しいので、画面をスクロールしたタイミングに合わせてボードがペコリと、お辞儀のような動作をする仕掛けを施しています。

▶▶▷サイト閲覧ユーザーの指や視線を確実に1秒止める。

上記見出しは、アダルトでも一般ジャンルであっても、共通して狙いたいアクションだと感じている要素の一つであり、

個人的には結構、重要なポイントではなかろうか?とも実感しています。

今回はボタンリンクではないので、CVに直結するコンテンツではありませんが、自分自身が閲覧ユーザーの際に、例えばスマホをササーっとスクロールさせてる時に

「おっ!」と思わず視線が釘付けになるタイトルや文言、もしくは指先が急ブレーキをかけるコンテンツに遭遇する時って、

言語化よりも先に感情が動いている時なのかもしれません。

使用時の注意点

適用前にバックアップを取ってください。利用はすべて自己責任でお願いします。

また、動かないというフィードバックに対して、どこまで対応できるか未知数なため、そこら辺はあまり期待しないでください。

ただ、コメント欄に報告をガンガン書き込んでもらえると、助かります。

また、1ページに複数のボードを配置した場合、2枚目はお辞儀もしないし、グリグリ動きませんので、予めご了承ください。(仕様です)

一応、Chat GPT、Gemini、ClaudeをエヴァンゲリオンのMAGIシステムのように使い、コードに重大な瑕疵はないか?整合性は取れているか?などを確認させて、なるべくエラーが出にくいよう、チューニングを重ねました。

あとがき

今回は無料配布ということで、最もオーソドックスなタイプのデザインとなっています。

好評であれば、リッチなデザイン性のボードや、ボタンリンクなどもリリースしていければなと思います。(300円~500円くらい?)

カスタムテンプレートにコピペするだけで使えるお手軽さが最大のポイントです。

<?php
// Atroposライブラリを動的に読み込み
wp_enqueue_style('atropos-css', 'https://cdn.jsdelivr.net/npm/atropos@2/atropos.min.css');
wp_enqueue_script('atropos-js', 'https://cdn.jsdelivr.net/npm/atropos@2/atropos.min.js', array(), null, true);
?>

<style>
.orbital-wrapper { 
    width: 88%; 
    max-width: 420px; 
    margin: 60px auto; 
    perspective: 2500px; 
}

.spec-final-3d {
    background: transparent !important;
    filter: drop-shadow(0 12px 25px rgba(0, 0, 0, 0.15));
    transition: filter 0.3s ease;
}

.atropos-active .spec-final-3d {
    filter: drop-shadow(0 35px 60px rgba(0, 0, 0, 0.25));
}

.spec-final-3d .atropos-inner {
    background: #ffffff !important; 
    border: 1px solid #eee !important;
    border-radius: 20px;
    overflow: hidden;
}

.atropos-shadow { 
    display: none !important; 
}

.pop-out { 
    transform: translateZ(100px) !important; 
    display: inline-block; 
}

.mxdx-header {
    background: #000000;
    padding: 24px 22px;
    text-align: center;
}

.orbital-title { 
    color: #ffffff !important; 
    font-size: 1.1rem; 
    font-weight: 900; 
}

.mxdx-content-body { 
    padding: 10px 22px 30px; 
}

.orbital-info-row { 
    display: flex; 
    justify-content: space-between; 
    align-items: center;
    padding: 12px 0; 
    border-bottom: 1px solid rgba(0, 0, 0, 0.05); 
}

.label { 
    color: #888; 
    font-size: 0.75rem; 
    font-weight: bold; 
}

.value { 
    color: #222; 
    font-weight: bold; 
    text-align: right; 
}

.c-blue { color: #0070f3 !important; }
.c-purple { color: #7928ca !important; }

.genre-row { 
    padding: 12px 0; 
}

.genre-label { 
    color: #888; 
    font-size: 0.75rem; 
    font-weight: bold; 
    display: block; 
    margin-bottom: 8px; 
}

.genre-tags-container { 
    display: flex; 
    flex-wrap: wrap; 
    gap: 6px; 
}

.genre-tag { 
    background: #f0f0f0; 
    color: #555; 
    font-size: 0.65rem; 
    padding: 3px 8px; 
    border-radius: 4px; 
    white-space: nowrap; 
}
</style>

<div class="orbital-wrapper">
    <div id="mxdx-final-card" class="atropos spec-final-3d">
        <div class="atropos-scale">
            <div class="atropos-rotate">
                <div class="atropos-inner">
                    
                    <div class="mxdx-header">
                        <span class="orbital-title pop-out" data-atropos-offset="5">
                            <?php echo esc_html(get_field('title')); ?>
                        </span>
                    </div>

                    <div class="mxdx-content-body">
                        
                        <div class="orbital-info-row">
                            <span class="label">サークル</span>
                            <span class="value pop-out c-blue" data-atropos-offset="3">
                                <?php echo esc_html(get_field('maker-name')); ?>
                            </span>
                        </div>
                        
                        <div class="orbital-info-row">
                            <span class="label">品番</span>
                            <span class="value pop-out c-purple" data-atropos-offset="3">
                                <?php echo esc_html(get_field('content_id')); ?>
                            </span>
                        </div>

                        <?php if ($val = get_field('series')): ?>
                        <div class="orbital-info-row">
                            <span class="label">シリーズ</span>
                            <span class="value pop-out" data-atropos-offset="3">
                                <?php echo esc_html($val); ?>
                            </span>
                        </div>
                        <?php endif; ?>

                        <?php if ($val = get_field('volume')): ?>
                        <div class="orbital-info-row">
                            <span class="label">総ページ数</span>
                            <span class="value pop-out" data-atropos-offset="3">
                                <?php echo esc_html($val); ?>
                            </span>
                        </div>
                        <?php endif; ?>

                        <div class="genre-row">
                            <span class="genre-label">ジャンル</span>
                            <div class="genre-tags-container pop-out" data-atropos-offset="2">
                                <?php 
                                $genres = get_field('genre');
                                if ($genres) {
                                    $genre_list = preg_split('/[、,\s]+/u', $genres);
                                    foreach ($genre_list as $tag) {
                                        $tag = trim($tag);
                                        if (!empty($tag)) {
                                            echo '<span class="genre-tag">' . esc_html($tag) . '</span>';
                                        }
                                    }
                                }
                                ?>
                            </div>
                        </div>

                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<script>
(function() {
  let atroposInited = false;

  function initAtroposSafe() {
    if (atroposInited) return;
    if (typeof Atropos === 'undefined') {
      // ライブラリ未読み込み時は再試行
      setTimeout(initAtroposSafe, 200);
      return;
    }

    const card = document.querySelector('#mxdx-final-card');
    if (!card) return;

    atroposInited = true;

    Atropos({
      el: card,
      rotateXInitial: 25,
      rotateYInitial: -12,
      activeOffset: 70,
      rotateXMax: 40,
      rotateYMax: 30,
      highlight: true,
      shadow: false
    });

    const observer = new IntersectionObserver((entries, obs) => {
      entries.forEach(entry => {
        if (!entry.isIntersecting) return;

        const rotateEl = card.querySelector('.atropos-rotate');
        if (!rotateEl) return;

        setTimeout(() => {
          rotateEl.style.transition = "transform 0.7s cubic-bezier(0.23, 1, 0.32, 1)";
          rotateEl.style.transform = "rotateX(-25deg) rotateY(-10deg)";

          setTimeout(() => {
            rotateEl.style.transform = "";
          }, 700);
        }, 400);

        obs.unobserve(entry.target);
      });
    }, { threshold: 0.6 });

    observer.observe(card);
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initAtroposSafe);
  } else {
    initAtroposSafe();
  }
})();
</script>

いいなと思ったら応援しよう!