{"id":2618,"date":"2026-03-03T23:08:42","date_gmt":"2026-03-03T15:08:42","guid":{"rendered":"https:\/\/purestudio.com.tw\/official\/?p=2618"},"modified":"2026-04-09T14:11:33","modified_gmt":"2026-04-09T06:11:33","slug":"jianpu-master-introduce","status":"publish","type":"post","link":"https:\/\/purestudio.com.tw\/official\/jianpu-master-introduce\/","title":{"rendered":"\u2726 \u7c21\u8b5c\u5320"},"content":{"rendered":"\n<div class=\"wp-block-group is-content-justification-center is-nowrap is-layout-flex wp-container-core-group-is-layout-ac719c21 wp-block-group-is-layout-flex\" style=\"margin-top:0;margin-bottom:0;padding-top:0px;padding-bottom:30px\">\n<h2 class=\"wp-block-heading has-x-large-font-size\">2026 \u7c21\u8b5c\u7de8\u8f2f\u5f15\u64ce<\/h2>\n<\/div>\n\n\n\n<div class=\"wp-block-group has-global-padding is-layout-constrained wp-block-group-is-layout-constrained\">\n<div id=\"jm-engine-wrapper\">\n    <style>\n        \/* 1. \u57fa\u790e\u5bb9\u5668 - \u7dad\u6301\u5e95\u8272 #e2e2e2 *\/\n        #jm-engine-wrapper {\n            font-family: \"Inter\", \"PingFang TC\", \"Microsoft JhengHei\", sans-serif;\n            color: #2c2c2c;\n            line-height: 1.7;\n            max-width: 1000px;\n            margin: 0 auto;\n            padding: 20px;\n            background-color: #e2e2e2; \n            box-sizing: border-box;\n            position: relative;\n        }\n\n        #jm-engine-wrapper * { box-sizing: border-box; }\n\n        \/* \u9802\u90e8\u7cfb\u7d71\u72c0\u614b *\/\n        .jm-system-status {\n            display: flex;\n            align-items: center;\n            gap: 10px;\n            margin-bottom: 15px;\n            font-size: 0.85rem;\n            font-weight: 600;\n            color: #666;\n        }\n\n        .jm-status-dot {\n            width: 8px; height: 8px;\n            background-color: #ffcc00;\n            border-radius: 50%;\n            box-shadow: 0 0 8px #ffcc00;\n            animation: jm-pulse 2s infinite;\n        }\n\n        @keyframes jm-pulse {\n            0% { opacity: 1; }\n            50% { opacity: 0.4; }\n            100% { opacity: 1; }\n        }\n\n        \/* 2. \u6838\u5fc3\u770b\u677f - \u6f38\u5c64\u6d41\u52d5 + \u591c\u5e97\u7bc0\u62cd *\/\n        .jm-hero-canvas {\n            position: relative;\n            width: 100%;\n            min-height: 450px;\n            border-radius: 20px;\n            margin-bottom: 25px;\n            background: linear-gradient(135deg, #1a1a1a 0%, #333333 30%, #2c3e50 60%, #000000 100%);\n            background-size: 400% 400%;\n            animation: jm-gradient-flow 15s ease infinite;\n            overflow: hidden;\n            display: flex;\n            flex-direction: column;\n            justify-content: center;\n            padding: 40px;\n            box-shadow: 0 10px 30px rgba(0,0,0,0.2);\n            transition: transform 0.1s cubic-bezier(0.17, 0.67, 0.83, 0.67), filter 0.1s ease;\n        }\n\n        @keyframes jm-gradient-flow {\n            0% { background-position: 0% 50%; }\n            50% { background-position: 100% 50%; }\n            100% { background-position: 0% 50%; }\n        }\n\n        .jm-canvas-overlay {\n            position: absolute;\n            top: 0; left: 0; right: 0; bottom: 0;\n            opacity: 0;\n            mix-blend-mode: screen;\n            pointer-events: none;\n            transition: opacity 0.1s ease;\n            z-index: 1;\n        }\n\n        .jm-hero-canvas.is-beating {\n            transform: scale(1.01);\n            filter: brightness(1.2);\n        }\n\n        .jm-main-title {\n            font-size: clamp(2rem, 5vw, 3.5rem);\n            font-weight: 900;\n            color: #ffffff;\n            z-index: 2;\n            text-shadow: 0 2px 10px rgba(0,0,0,0.5);\n            margin: 0 0 15px 0;\n            letter-spacing: 2px;\n        }\n\n        .jm-tagline {\n            font-size: 1rem;\n            max-width: 650px;\n            color: rgba(255, 255, 255, 0.9);\n            background: rgba(255, 255, 255, 0.1);\n            padding: 20px;\n            border-radius: 12px;\n            backdrop-filter: blur(12px);\n            border: 1px solid rgba(255,255,255,0.15);\n            z-index: 2;\n        }\n\n        \/* \u5f71\u7247\u5c55\u793a\u6309\u9215 *\/\n        .jm-demo-toggle-btn {\n            position: absolute;\n            bottom: 30px;\n            left: 30px;\n            background: rgba(255, 255, 255, 0.1);\n            border: 1px solid rgba(255, 255, 255, 0.2);\n            color: #fff;\n            padding: 10px 20px;\n            border-radius: 30px;\n            cursor: pointer;\n            font-size: 16px;\n            font-weight: 800;\n            letter-spacing: 1px;\n            backdrop-filter: blur(10px);\n            z-index: 1001;\n            transition: 0.3s;\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n        .jm-demo-toggle-btn:hover {\n            background: #ffcc00;\n            color: #000;\n            border-color: #ffcc00;\n        }\n\n        \/* \u7368\u7acb\u5f71\u7247\u5c55\u793a\u5340\u584a *\/\n        #jm-video-section {\n            display: none; \/* \u9810\u8a2d\u96b1\u85cf *\/\n            width: 100%;\n            background: #000;\n            border-radius: 20px;\n            margin-bottom: 25px;\n            overflow: hidden;\n            box-shadow: 0 15px 35px rgba(0,0,0,0.3);\n            animation: jm-fade-in 0.5s ease;\n        }\n        @keyframes jm-fade-in {\n            from { opacity: 0; transform: translateY(10px); }\n            to { opacity: 1; transform: translateY(0); }\n        }\n\n        .jm-video-container {\n            position: relative;\n            padding-bottom: 56.25%; \/* 16:9 *\/\n            height: 0;\n        }\n        .jm-video-container iframe {\n            position: absolute;\n            top: 0; left: 0; width: 100%; height: 100%;\n            border: none;\n        }\n\n        \/* 3. BPM \u63a7\u5236\u5668\u9762\u677f *\/\n        .jm-bpm-controller {\n            position: absolute;\n            bottom: 30px;\n            right: 30px;\n            display: flex;\n            flex-direction: column;\n            gap: 12px;\n            background: rgba(0, 0, 0, 0.3);\n            backdrop-filter: blur(20px);\n            padding: 15px;\n            border-radius: 20px;\n            border: 1px solid rgba(255,255,255,0.1);\n            z-index: 1000;\n            min-width: 240px;\n        }\n\n        .jm-bpm-info-row {\n            display: flex;\n            align-items: center;\n            justify-content: space-between;\n            padding-bottom: 8px;\n            border-bottom: 1px solid rgba(255,255,255,0.1);\n        }\n\n        .jm-bpm-display {\n            color: #ffcc00;\n            font-family: monospace;\n            font-weight: 900;\n            font-size: 1.2rem;\n        }\n\n        .jm-bpm-control-row {\n            display: flex;\n            gap: 6px;\n        }\n\n        .jm-bpm-btn {\n            height: 36px;\n            flex: 1;\n            border-radius: 8px;\n            border: none;\n            background: rgba(255, 255, 255, 0.15);\n            color: white;\n            cursor: pointer;\n            font-size: 12px;\n            font-weight: 800;\n            transition: 0.2s;\n        }\n        .jm-bpm-btn:active { background: #ffcc00; color: #000; }\n\n        .jm-audio-toggle {\n            background: rgba(255, 255, 255, 0.1);\n            border: none;\n            width: 36px;\n            height: 36px;\n            border-radius: 50%;\n            cursor: pointer;\n            font-size: 16px;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            padding: 0;\n            line-height: 1;\n        }\n        .jm-audio-toggle.is-active { background: #ffcc00; }\n\n        \/* 4. \u529f\u80fd\u7db2\u683c *\/\n        .jm-feature-grid {\n            display: grid;\n            grid-template-columns: repeat(2, 1fr);\n            gap: 20px;\n        }\n\n        .jm-card {\n            background: #ffffff;\n            border: 1px solid #e0e0e0;\n            border-radius: 14px;\n            padding: 25px;\n            transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);\n            box-shadow: 0 2px 5px rgba(0,0,0,0.02);\n            position: relative;\n        }\n\n        .jm-card:hover {\n            border-color: #ffcc00;\n            transform: translateY(-8px);\n            box-shadow: 0 15px 35px rgba(0,0,0,0.12);\n            z-index: 10;\n        }\n\n        .jm-card-header { display: flex; align-items: center; margin-bottom: 15px; }\n\n        .jm-index-num {\n            background: #ffcc00; color: #000;\n            width: 26px; height: 26px;\n            display: flex; align-items: center; justify-content: center;\n            font-size: 0.8rem; font-weight: 900; border-radius: 6px; margin-right: 12px;\n        }\n\n        .jm-card-title { font-size: 1.15rem; font-weight: 800; color: #1a1a1a; }\n        .jm-item-title {\n            font-weight: 700; display: block; color: #444; font-size: 0.95rem;\n            margin-top: 15px; border-left: 3px solid #ffcc00; padding-left: 8px;\n        }\n        .jm-item-desc { font-size: 0.85rem; color: #666; display: block; margin-top: 5px; line-height: 1.6; }\n\n        \/* 5. \u5e95\u90e8\u53d6\u5f97\u6309\u9215\u5340 *\/\n        .jm-export-box {\n            margin-top: 35px;\n            background: #1a1a1a;\n            color: #fff;\n            padding: 30px;\n            border-radius: 16px;\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            gap: 20px;\n        }\n\n        .jm-btn {\n            background: #ffcc00; color: #000;\n            padding: 14px 32px; border-radius: 10px;\n            text-decoration: none; font-weight: 800; transition: 0.3s;\n            white-space: nowrap;\n        }\n        .jm-btn:hover { background: #fff; transform: scale(1.05); }\n\n        \/* 6. \u624b\u6a5f\u7248\u512a\u5316 *\/\n        @media (max-width: 768px) {\n            #jm-engine-wrapper { padding: 0; }\n            .jm-hero-canvas { \n                padding: 30px 20px; \n                min-height: 520px; \/* \u589e\u52a0\u9ad8\u5ea6\u78ba\u4fdd\u6309\u9215\u5782\u76f4\u6392\u5217\u4e0d\u91cd\u758a *\/\n                justify-content: flex-start;\n            }\n            .jm-tagline { margin-top: 10px; padding: 15px; }\n            \n            \/* \u624b\u6a5f\u7248\u6309\u9215\u5782\u76f4\u5206\u4f48 *\/\n            .jm-demo-toggle-btn { \n                bottom: 170px; \/* \u5411\u4e0a\u79fb\u52d5\u907f\u958bBPM\u9762\u677f *\/\n                left: 20px; \n                right: 20px;\n                justify-content: center;\n            }\n            .jm-bpm-controller { \n                bottom: 20px; \n                right: 20px; \n                left: 20px; \n                min-width: unset; \n            }\n            \n            .jm-feature-grid { grid-template-columns: 1fr; gap: 15px; }\n            .jm-export-box { flex-direction: column; text-align: center; padding: 20px; }\n        }\n    <\/style>\n\n    <!-- \u7cfb\u7d71\u72c0\u614b -->\n    <div class=\"jm-system-status\">\n        <div class=\"jm-status-dot\"><\/div>\n        <span>SYSTEM READY: \u7c21\u8b5c\u5320 ENGINE v2.0<\/span>\n    <\/div>\n\n    <!-- \u85dd\u8853\u7246\u5340\u584a -->\n    <header class=\"jm-hero-canvas\" id=\"jm-wall\">\n        <div class=\"jm-canvas-overlay\" id=\"jm-overlay\"><\/div>\n        \n        <h1 class=\"jm-main-title\">\u7c21\u8b5c\u5320<span style=\"font-size:1.3rem; letter-spacing: -0.05px;\"> JianPu Master<\/span><br>\u6578\u4f4d\u88fd\u8b5c\u5c08\u5bb6<\/h1>\n        <div class=\"jm-tagline\">\n            \u5c08\u70ba\u97f3\u6a02\u4eba\u8a2d\u8a08\u7684\u5c08\u696d\u7c21\u8b5c\u88fd\u8b5c\u5de5\u5177\u3002Mac\u3001iPad\u3001iPhone \u5168\u5e73\u53f0\u652f\u63f4\uff0c\u8b93\u76f4\u89ba\u8207\u7f8e\u611f\u5728\u97f3\u7b26\u9593\u6d41\u52d5\uff0c\u7a81\u7834\u50b3\u7d71\u88fd\u8b5c\u7684\u7e41\u7463\u675f\u7e1b\u3002\n        <\/div>\n\n        <!-- \u5f71\u7247\u958b\u95dc\u6309\u9215 (\u4f4d\u65bc\u85dd\u8853\u7246\u5167) -->\n        <button class=\"jm-demo-toggle-btn\" id=\"demo-toggle\">\n                <svg width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M8 5v14l11-7z\"\/><\/svg>\n\u5f71\u7247\u5c55\u793a<\/button>\n\n        <!-- BPM \u63a7\u5236\u5668 (\u4f4d\u65bc\u85dd\u8853\u7246\u5167) -->\n        <div class=\"jm-bpm-controller\">\n            <div class=\"jm-bpm-info-row\">\n                <button class=\"jm-audio-toggle\" id=\"audio-toggle\">\ud83d\udd08<\/button>\n                <div class=\"jm-bpm-display\" id=\"bpm-val-display\">120 BPM<\/div>\n            <\/div>\n            <div class=\"jm-bpm-control-row\">\n                <button class=\"jm-bpm-btn\" id=\"bpm-minus-20\">-20<\/button>\n                <button class=\"jm-bpm-btn\" id=\"bpm-minus-5\">-5<\/button>\n                <button class=\"jm-bpm-btn\" id=\"bpm-plus-5\">+5<\/button>\n                <button class=\"jm-bpm-btn\" id=\"bpm-plus-20\">+20<\/button>\n            <\/div>\n        <\/div>\n    <\/header>\n\n    <!-- \u7368\u7acb\u5f71\u7247\u5340\u584a (\u4f4d\u65bc\u85dd\u8853\u7246\u4e0b\u65b9) -->\n    <div id=\"jm-video-section\">\n        <div class=\"jm-video-container\">\n            <iframe id=\"jm-iframe\" src=\"\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n        <\/div>\n    <\/div>\n\n    <!-- \u529f\u80fd\u7db2\u683c -->\n    <div class=\"jm-feature-grid\">\n        <article class=\"jm-card\">\n            <div class=\"jm-card-header\">\n                <span class=\"jm-index-num\">A<\/span>\n                <div class=\"jm-card-title\">\u76f4\u89ba\u5f0f\u7de8\u8f2f\u6838\u5fc3<\/div>\n            <\/div>\n            <span class=\"jm-item-title\">\u8de8\u88dd\u7f6e\u901a\u7528\u9ad4\u9a57<\/span>\n            <span class=\"jm-item-desc\">\u5b8c\u7f8e\u9069\u914d Apple \u751f\u614b\u7cfb\uff0c\u7121\u8ad6\u5728 Mac \u8655\u7406\u5927\u8b5c\u7a3f\u6216\u5728 iPad \u96a8\u624b\u8a18\u8b5c\u90fd\u6d41\u66a2\u81ea\u5982\u3002<\/span>\n            <span class=\"jm-item-title\">\u8f15\u91cf\u6975\u901f\u5f15\u64ce<\/span>\n            <span class=\"jm-item-desc\">\u6beb\u79d2\u7d1a\u6e32\u67d3\u6280\u8853\uff0c\u652f\u63f4\u5feb\u901f\u8f38\u5165\u97f3\u7b26\u3001\u6b4c\u8a5e\u8207\u6b4c\u540d\uff0c\u5fb9\u5e95\u544a\u5225\u50b3\u7d71\u8edf\u9ad4\u7684\u5361\u9813\u3002<\/span>\n        <\/article>\n\n        <article class=\"jm-card\">\n            <div class=\"jm-card-header\">\n                <span class=\"jm-index-num\">B<\/span>\n                <div class=\"jm-card-title\">\u5c08\u696d\u5074\u9078\u5de5\u5177\u5217<\/div>\n            <\/div>\n            <span class=\"jm-item-title\">\u9ad8\u6548\u5feb\u6377\u63a7\u5236<\/span>\n            <span class=\"jm-item-desc\">\u6574\u5408\u300c\u5feb\u6377\u5217\u8868\u300d\u8207\u300c\u5168\u5c40\u63a7\u5236\u300d\uff0c\u4e00\u9375\u8abf\u6574\u5168\u8b5c\u4f48\u5c40\uff0c\u6548\u7387\u63d0\u5347 200%\u3002<\/span>\n            <span class=\"jm-item-title\">\u8cc7\u6599\u5b89\u5168\u7ba1\u7406<\/span>\n            <span class=\"jm-item-desc\">\u5177\u5099\u300c\u7de8\u8f2f\u6a94\u5b58\u5132\u300d\u8207\u300c\u4e00\u9375\u6e05\u9664\u300d\u529f\u80fd\uff0c\u8b93\u5275\u4f5c\u904e\u7a0b\u65e2\u5f48\u6027\u53c8\u56b4\u8b39\u3002<\/span>\n        <\/article>\n\n        <article class=\"jm-card\">\n            <div class=\"jm-card-header\">\n                <span class=\"jm-index-num\">C<\/span>\n                <div class=\"jm-card-title\">\u591a\u7dad\u5ea6\u756b\u5e03\u67b6\u69cb<\/div>\n            <\/div>\n            <span class=\"jm-item-title\">\u7cbe\u6e96\u5206\u5c64\u7de8\u8f2f<\/span>\n            <span class=\"jm-item-desc\">\u8a2d\u8a08\u6709\u97f3\u7b26\u5c64\u3001\u6b4c\u8a5e\u5c64\u3001\u548c\u5f26\u5c64\u8207\u5c0f\u7bc0\u7dda\u8a2d\u7f6e\uff0c\u5c64\u6b21\u5206\u660e\uff0c\u4fee\u6539\u4e0d\u6df7\u4e82\u3002<\/span>\n            <span class=\"jm-item-title\">\u591a\u90e8\u65cb\u5f8b\u652f\u63f4<\/span>\n            <span class=\"jm-item-desc\">\u7368\u7279\u7684\u591a\u90e8\u65cb\u5f8b\u8207\u6b4c\u8a5e\u540c\u6b65\u529f\u80fd\uff0c\u662f\u97f3\u6a02\u6559\u5b78\u8207\u8077\u696d\u7de8\u66f2\u7684\u5f97\u529b\u52a9\u624b\u3002<\/span>\n        <\/article>\n\n        <article class=\"jm-card\">\n            <div class=\"jm-card-header\">\n                <span class=\"jm-index-num\">D<\/span>\n                <div class=\"jm-card-title\">\u8077\u4eba\u7d1a\u7d93\u9a57\u958b\u767c<\/div>\n            <\/div>\n            <span class=\"jm-item-title\">\u97f3\u6a02\u80cc\u666f\u6df1\u8015<\/span>\n            <span class=\"jm-item-desc\">\u7531\u5c08\u696d\u97f3\u6a02\u5718\u968a\u958b\u767c\uff0c\u7cbe\u78ba\u6355\u6349\u88fd\u8b5c\u75db\u9ede\uff0c\u63d0\u4f9b\u6700\u7b26\u5408\u5c08\u696d\u9700\u6c42\u7684\u7de8\u8f2f\u5de5\u5177\u3002<\/span>\n            <span class=\"jm-item-title\">\u7f8e\u5b78\u4ecb\u9762\u8a2d\u8a08<\/span>\n            <span class=\"jm-item-desc\">\u4ecb\u9762\u5340\u5206\u70ba\u7c21\u6f54\u7684\u5de6\u5074\u5c0e\u89bd\u8207\u4e3b\u7de8\u8f2f\u5340\uff0c\u8b93\u60a8\u5c08\u6ce8\u65bc\u97f3\u6a02\u5275\u4f5c\u672c\u8eab\u3002<\/span>\n        <\/article>\n    <\/div>\n\n    <!-- \u5e95\u90e8\u5c0e\u822a -->\n    <section class=\"jm-export-box\">\n        <div style=\"flex: 1;\">\n            <h3 style=\"margin:0; font-size:1.2rem; color:#ffcc00;\">\u7acb\u5373\u555f\u52d5\u60a8\u7684\u88fd\u8b5c\u9748\u611f<\/h3>\n            <p style=\"margin:5px 0 0 0; font-size:0.9rem; color:#bbb;\">\u9ad4\u9a57\u5730\u8868\u6700\u5feb\u3001\u6700\u76f4\u89ba\u7684\u7c21\u8b5c\u8edf\u9ad4\uff0c\u73fe\u5728\u5c31\u5f9e App Store \u4e0b\u8f09\u3002<\/p>\n        <\/div>\n        <a href=\"https:\/\/apps.apple.com\/tw\/app\/%E7%B0%A1%E8%AD%9C%E5%8C%A0\/id6758430506\" class=\"jm-btn\" target=\"_blank\">\u53d6\u5f97\u7c21\u8b5c\u5320 \u2192<\/a>\n    <\/section>\n\n    <footer style=\"margin-top:40px; text-align:center; font-size:0.75rem; color:#888; letter-spacing: 1px;\">\n        \u00a9 JIANPU MASTER | PROFESSIONAL MUSIC NOTATION SOLUTIONS\n    <\/footer>\n\n    <script>\n        (function() {\n            const wall = document.getElementById('jm-wall');\n            const overlay = document.getElementById('jm-overlay');\n            const bpmDisplay = document.getElementById('bpm-val-display');\n            const audioBtn = document.getElementById('audio-toggle');\n            const demoBtn = document.getElementById('demo-toggle');\n            const videoSection = document.getElementById('jm-video-section');\n            const jmIframe = document.getElementById('jm-iframe');\n            \n            let currentBPM = 120;\n            let beatTimer = null;\n            let isMuted = true;\n            const colors = ['#ff0055', '#00fbff', '#7000ff', '#ffcc00', '#00ff41'];\n\n            \/\/ \u5f71\u7247\u5c55\u793a\u908f\u8f2f\uff1a\u5c55\u958b\/\u6536\u5408\u7368\u7acb\u5340\u584a\uff0c\u4e0d\u5f71\u97ff\u85dd\u8853\u7246\n            demoBtn.onclick = (e) => {\n                e.stopPropagation();\n                if (videoSection.style.display === 'none' || videoSection.style.display === '') {\n                    videoSection.style.display = 'block';\n                    jmIframe.src = \"https:\/\/www.youtube.com\/embed\/huo3PiyyH6k?autoplay=1\";\n                    \/\/ \u5e73\u6ed1\u6efe\u52d5\u5230\u5f71\u7247\u5340\n                    setTimeout(() => {\n                        videoSection.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n                    }, 100);\n                    demoBtn.innerText = \"\u2715 \u95dc\u9589\u5f71\u7247\";\n                } else {\n                    videoSection.style.display = 'none';\n                    jmIframe.src = \"\";\n                    demoBtn.innerText = \"\u25b6 \u5f71\u7247\u5c55\u793a\";\n                }\n            };\n\n            \/\/ \u97f3\u6548\u8207\u7bc0\u62cd\u908f\u8f2f\n            const audioCtx = new (window.AudioContext || window.webkitAudioContext)();\n            function playClickSound() {\n                if (isMuted) return;\n                const osc = audioCtx.createOscillator();\n                const envelope = audioCtx.createGain();\n                osc.type = 'sine';\n                osc.frequency.setValueAtTime(1000, audioCtx.currentTime); \n                envelope.gain.setValueAtTime(0.15, audioCtx.currentTime);\n                envelope.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.04);\n                osc.connect(envelope); envelope.connect(audioCtx.destination);\n                osc.start(); osc.stop(audioCtx.currentTime + 0.05);\n            }\n\n            function startMetronome() {\n                if (beatTimer) clearInterval(beatTimer);\n                const msPerBeat = 60000 \/ currentBPM;\n                beatTimer = setInterval(() => {\n                    wall.classList.add('is-beating');\n                    overlay.style.opacity = \"0.6\";\n                    const randomColor = colors[Math.floor(Math.random() * colors.length)];\n                    overlay.style.background = `radial-gradient(circle, ${randomColor} 0%, transparent 70%)`;\n                    playClickSound();\n                    setTimeout(() => {\n                        wall.classList.remove('is-beating');\n                        overlay.style.opacity = \"0\";\n                    }, 80);\n                }, msPerBeat);\n            }\n\n            function updateBPM(delta) {\n                currentBPM = Math.max(40, Math.min(240, currentBPM + delta));\n                bpmDisplay.innerText = currentBPM + \" BPM\";\n                startMetronome();\n            }\n\n            document.getElementById('bpm-plus-20').onclick = (e) => { e.stopPropagation(); updateBPM(20); };\n            document.getElementById('bpm-plus-5').onclick = (e) => { e.stopPropagation(); updateBPM(5); };\n            document.getElementById('bpm-minus-5').onclick = (e) => { e.stopPropagation(); updateBPM(-5); };\n            document.getElementById('bpm-minus-20').onclick = (e) => { e.stopPropagation(); updateBPM(-20); };\n\n            audioBtn.onclick = (e) => {\n                e.stopPropagation();\n                if (audioCtx.state === 'suspended') audioCtx.resume();\n                isMuted = !isMuted;\n                audioBtn.innerText = isMuted ? '\ud83d\udd08' : '\ud83d\udd0a';\n                audioBtn.classList.toggle('is-active', !isMuted);\n            };\n\n            startMetronome();\n        })();\n    <\/script>\n<\/div>\n\n\n\n<div class=\"tp-global-container\" style=\"width: 100%; user-select: none; -webkit-user-select: none; display: flex; flex-direction: column; align-items: center; padding: 0;\">\n    <style>\n        \/* =============================================\n           1. \u8a2d\u5099\u5207\u63db\uff1a\u9ad8\u4eae\u6253\u78e8\u73bb\u7483\n           ============================================= *\/\n        .tp-device-switcher-wrap {\n            margin-top: 55px; margin-bottom: 0px; display: flex; justify-content: center;\n            z-index: 30; position: relative;\n        }\n        .tp-device-switcher {\n            background: rgba(255, 255, 255, 0.45); backdrop-filter: blur(20px) saturate(180%);\n            -webkit-backdrop-filter: blur(20px) saturate(180%);\n            padding: 6px; border-radius: 14px; display: flex; gap: 6px;\n            border: 1px solid rgba(255, 255, 255, 0.8);\n            box-shadow: 0 10px 25px rgba(0, 0, 0, 0.08), inset 0 0 0 1px rgba(255, 255, 255, 0.3);\n        }\n        .tp-nav-tab {\n            position: relative; color: rgba(60, 60, 60, 0.6); font-family: \"SF Pro Text\", sans-serif;\n            font-size: 11px; letter-spacing: 2.5px; text-transform: uppercase; font-weight: 600;\n            cursor: pointer; padding: 10px 24px; border-radius: 10px; transition: 0.4s;\n        }\n        .tp-nav-tab.active { color: #000; background: rgba(255, 255, 255, 0.7); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); }\n        .tp-nav-tab.active::after {\n            content: ''; position: absolute; bottom: 5px; left: 50%; transform: translateX(-50%);\n            width: 14px; height: 2px; background: rgba(0, 0, 0, 0.4); border-radius: 4px;\n        }\n\n        \/* =============================================\n           2. \u8a2d\u5099\u5bb9\u5668\n           ============================================= *\/\n        .tp-device-wrapper { \n            position: relative; display: none; width: 100%; max-width: 1000px; \n            line-height: 0; touch-action: none;\n            transition: margin-bottom 0.5s cubic-bezier(0.16, 1, 0.3, 1), margin-top 0.5s cubic-bezier(0.16, 1, 0.3, 1);\n        }\n        \n        .tp-device-wrapper img {\n            transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);\n            transform-origin: center center;\n        }\n\n        .tp-base-frame { width: 100%; height: auto; display: block; pointer-events: none; }\n        .tp-flow-layer { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 2; pointer-events: none; }\n        \n        .tp-screen-handler { \n            position: absolute; z-index: 10; cursor: pointer; -webkit-tap-highlight-color: transparent;\n            transform-origin: center top; \n            transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1), border-color 0.4s, box-shadow 0.4s;\n        }\n\n        @keyframes glow-main {\n            0%, 100% { border-color: rgba(255, 255, 255, 0.3); box-shadow: 0 0 45px rgba(255, 255, 255, 0.1); }\n            50% { border-color: rgba(255, 255, 255, 1); box-shadow: 0 0 260px rgba(255, 255, 255, 0.7); }\n        }\n\n        \/* \u767c\u5149\u6846\u7dda\u7cbe\u78ba\u5b9a\u4f4d *\/\n        #mac-screen-handler { top: 19.0%; left: 10.95%; width: 77.8%; height: 66.5%; border: 0.3px solid rgba(255, 255, 255, 0.3); border-radius: 11px; animation: glow-main 3.8s infinite; }\n        #ipad-screen-handler { top: 11.0%; left: 28.9%; width: 42.0%; height: 80.0%; border: 0.4px solid rgba(255, 255, 255, 0.3); border-radius: 10px; animation: glow-main 3.5s infinite; }\n        #iphone-screen-handler { top: 41.7%; left: 41.1%; width: 17.65%; height: 51.5%; border: 0.4px solid rgba(255, 255, 255, 0.3); border-radius: 27px; animation: glow-main 2.3s infinite; }\n\n        \/* =============================================\n           3. \u72c0\u614b\u8cc7\u8a0a\u8207\u653e\u5927\u6309\u9215\n           ============================================= *\/\n        .tp-status-text-wrap { \n            margin-top: 20px; padding: 8px 22px; \n            background: linear-gradient(145deg, #333 0%, #111 100%);\n            border-radius: 4px; display: flex; align-items: center;\n            position: relative; z-index: 25;\n        }\n        .tp-status-text { color: #E2E2E2; font-family: \"SF Pro Text\", sans-serif; font-size: 10px; letter-spacing: 2.5px; text-transform: uppercase; font-weight: 600; }\n\n        .tp-zoom-controls { display: none; gap: 8px; margin-top: 20px; z-index: 25; position: relative; }\n        .tp-zoom-btn {\n            background: rgba(255, 255, 255, 0.5); border: 1px solid rgba(0,0,0,0.05);\n            padding: 5px 12px; border-radius: 6px; font-size: 10px; font-weight: 700;\n            color: #555; cursor: pointer; transition: 0.3s;\n        }\n        .tp-zoom-btn.active { background: #000; color: #fff; border-color: #000; }\n\n        @media (max-width: 1024px) {\n            .tp-zoom-controls { display: flex; }\n            #ipad-screen-handler { border-radius: 9px; }\n            #iphone-screen-handler { border-radius: 27px; }\n        }\n\n        @media (max-width: 767px) {\n            .tp-nav-tab { padding: 8px 18px; font-size: 10px; letter-spacing: 1.5px; }\n            #mac-screen-handler { width: 77.55%; height: 66.1%; border-radius: 2.6px; }\n            #ipad-screen-handler { width: 41.75%; height: 79.5%; border-radius: 3.5px; }\n            #iphone-screen-handler { top: 41.7%; width: 17.5%; height: 51.2%; border-radius: 9.3px; }\n        }\n    <\/style>\n\n    <div class=\"tp-device-switcher-wrap\">\n        <div class=\"tp-device-switcher\">\n            <div id=\"tab-mac\" class=\"tp-nav-tab active\" onclick=\"switchDevice('mac')\">Mac<\/div>\n            <div id=\"tab-ipad\" class=\"tp-nav-tab\" onclick=\"switchDevice('ipad')\">iPad<\/div>\n            <div id=\"tab-iphone\" class=\"tp-nav-tab\" onclick=\"switchDevice('iphone')\">iPhone<\/div>\n        <\/div>\n    <\/div>\n\n    <!-- Mac Wrapper -->\n    <div id=\"mac-wrapper\" class=\"tp-device-wrapper\" style=\"display: inline-block;\">\n        <img decoding=\"async\" src=\"https:\/\/purestudio.com.tw\/official\/wp-content\/uploads\/2026\/03\/mac-mockup-frame.webp\" class=\"tp-base-frame\">\n        <img decoding=\"async\" id=\"mac-screen\" src=\"https:\/\/purestudio.com.tw\/official\/wp-content\/uploads\/2026\/04\/jianpu-master-01-sheet-music-preview.webp\" class=\"tp-flow-layer\">\n        <div id=\"mac-screen-handler\" class=\"tp-screen-handler\"><\/div>\n    <\/div>\n\n    <!-- iPad Wrapper -->\n    <div id=\"ipad-wrapper\" class=\"tp-device-wrapper\">\n        <img decoding=\"async\" src=\"https:\/\/purestudio.com.tw\/official\/wp-content\/uploads\/2026\/03\/ipad-mockup-frame.webp\" class=\"tp-base-frame\">\n        <img decoding=\"async\" id=\"ipad-screen\" src=\"https:\/\/purestudio.com.tw\/official\/wp-content\/uploads\/2026\/04\/ipad-flow-01-launch-splash-screen.webp\" class=\"tp-flow-layer\">\n        <div id=\"ipad-screen-handler\" class=\"tp-screen-handler\"><\/div>\n    <\/div>\n\n    <!-- iPhone Wrapper -->\n    <div id=\"iphone-wrapper\" class=\"tp-device-wrapper\">\n        <img decoding=\"async\" src=\"https:\/\/purestudio.com.tw\/official\/wp-content\/uploads\/2026\/03\/iphone-mockup-frame.webp\" class=\"tp-base-frame\">\n        <img decoding=\"async\" id=\"iphone-screen\" src=\"https:\/\/purestudio.com.tw\/official\/wp-content\/uploads\/2026\/04\/iphone-flow-01-welcome-splash.webp\" class=\"tp-flow-layer\">\n        <div id=\"iphone-screen-handler\" class=\"tp-screen-handler\"><\/div>\n    <\/div>\n\n    <div class=\"tp-status-text-wrap\">\n        <span id=\"tp-counter\" class=\"tp-status-text\">Step 1 \/ 2<\/span>\n    <\/div>\n\n    <div class=\"tp-zoom-controls\">\n        <div class=\"tp-zoom-btn active\" onclick=\"setZoom(1, this)\">1.0x<\/div>\n        <div class=\"tp-zoom-btn\" onclick=\"setZoom(1.5, this)\">1.5x<\/div>\n        <div class=\"tp-zoom-btn\" onclick=\"setZoom(1.8, this)\">1.8x<\/div>\n        <div class=\"tp-zoom-btn\" onclick=\"setZoom(2, this)\">2.0x<\/div>\n    <\/div>\n<\/div>\n\n<script>\n(function() {\n    const data = {\n        mac: [\n            \"https:\/\/purestudio.com.tw\/official\/wp-content\/uploads\/2026\/04\/jianpu-master-01-sheet-music-preview.webp\",\n            \"https:\/\/purestudio.com.tw\/official\/wp-content\/uploads\/2026\/04\/jianpu-master-02-editor-ui-shortcuts.webp\"\n        ],\n        ipad: [\n            \"https:\/\/purestudio.com.tw\/official\/wp-content\/uploads\/2026\/04\/ipad-flow-01-launch-splash-screen.webp\",\n            \"https:\/\/purestudio.com.tw\/official\/wp-content\/uploads\/2026\/04\/ipad-flow-03-sheet-music-editor-preview.webp\",\n            \"https:\/\/purestudio.com.tw\/official\/wp-content\/uploads\/2026\/04\/ipad-flow-04-global-settings-keyboard-input.webp\"\n        ],\n        iphone: [\n            \"https:\/\/purestudio.com.tw\/official\/wp-content\/uploads\/2026\/04\/iphone-flow-01-welcome-splash.webp\",\n            \"https:\/\/purestudio.com.tw\/official\/wp-content\/uploads\/2026\/04\/iphone-flow-02-sheet-music-editor.webp\",\n            \"https:\/\/purestudio.com.tw\/official\/wp-content\/uploads\/2026\/04\/iphone-flow-03-chord-lyrics-sync.webp\",\n            \"https:\/\/purestudio.com.tw\/official\/wp-content\/uploads\/2026\/04\/iphone-flow-04-numeric-keyboard-input.webp\",\n            \"https:\/\/purestudio.com.tw\/official\/wp-content\/uploads\/2026\/04\/iphone-flow-05-global-style-settings.webp\",\n            \"https:\/\/purestudio.com.tw\/official\/wp-content\/uploads\/2026\/04\/iphone-flow-06-slur-line-adjustment.webp\"\n        ]\n    };\n    let curD = 'mac', idxs = { mac: 0, ipad: 0, iphone: 0 };\n    const counter = document.getElementById('tp-counter');\n\n    \/\/ \u6cbf\u7528\u53c3\u8003\u78bc\u7684\u5fae\u8abf\u504f\u79fb\u91cf\n    const mobileOffsets = {\n        mac:    { \"1.0\": 0, \"1.5\": -25, \"1.8\": -34,   \"2.0\": -38 },\n        ipad:   { \"1.0\": 0, \"1.5\": -32, \"1.8\": -42.9, \"2.0\": -48 },\n        iphone: { \"1.0\": 0, \"1.5\": -7,   \"1.8\": -9,    \"2.0\": -10 }\n    };\n    const tabletOffsets = {\n        mac:    { \"1.0\": 0, \"1.5\": -67, \"1.8\": -88.4,   \"2.0\": -100 },\n        ipad:   { \"1.0\": 0, \"1.5\": -84.1, \"1.8\": -112.2, \"2.0\": -125.5 },\n        iphone: { \"1.0\": 0, \"1.5\": -18.4,   \"1.8\": -24.1,    \"2.0\": -27.1 }\n    };\n\n    function update() {\n        document.getElementById(`${curD}-screen`).src = data[curD][idxs[curD]];\n        counter.innerText = `Step ${idxs[curD] + 1} \/ ${data[curD].length}`;\n    }\n\n    window.setZoom = function(level, btn) {\n        document.querySelectorAll('.tp-zoom-btn').forEach(b => b.classList.remove('active'));\n        btn.classList.add('active');\n        \n        const wrap = document.getElementById(`${curD}-wrapper`);\n        const handler = document.getElementById(`${curD}-screen-handler`);\n        const baseHeight = wrap.offsetHeight;\n        const verticalPush = level > 1 ? (baseHeight * (level - 1) \/ 2) : 0;\n\n        document.querySelectorAll('.tp-device-wrapper').forEach(w => {\n            w.querySelectorAll('img').forEach(img => img.style.transform = `scale(${level})`);\n            if (w.style.display !== 'none') {\n                w.style.marginTop = `${verticalPush}px`;\n                w.style.marginBottom = `${verticalPush}px`;\n            } else {\n                w.style.marginTop = '0px';\n                w.style.marginBottom = '0px';\n            }\n        });\n\n        const isMobile = window.innerWidth <= 767;\n        const config = isMobile ? mobileOffsets : tabletOffsets;\n        const manualTopOffset = config[curD][level.toFixed(1)] || 0;\n        handler.style.transform = `scale(${level}) translateY(${manualTopOffset}px)`;\n    };\n\n    window.switchDevice = function(d) {\n        curD = d;\n        ['mac', 'ipad', 'iphone'].forEach(v => {\n            const wrap = document.getElementById(`${v}-wrapper`);\n            wrap.style.display = (v === d) ? 'inline-block' : 'none';\n            document.getElementById(`tab-${v}`).classList.toggle('active', v === d);\n            wrap.style.marginTop = '0px';\n            wrap.style.marginBottom = '0px';\n        });\n        const zoomBtns = document.querySelectorAll('.tp-zoom-btn');\n        if (zoomBtns.length > 0) setZoom(1, zoomBtns[0]);\n        update();\n    };\n\n    function flow(dir) {\n        const len = data[curD].length;\n        idxs[curD] = (dir === 'next') ? (idxs[curD] + 1) % len : (idxs[curD] - 1 + len) % len;\n        update();\n    }\n\n    ['mac', 'ipad', 'iphone'].forEach(d => {\n        const h = document.getElementById(`${d}-screen-handler`);\n        h.addEventListener('click', (e) => { if (e.pointerType !== 'touch') flow('next'); });\n        h.addEventListener('contextmenu', (e) => { e.preventDefault(); flow('prev'); });\n        h.addEventListener('touchstart', (e) => {\n            e.preventDefault();\n            if (e.touches.length === 2) flow('prev');\n            else if (e.touches.length === 1) flow('next');\n        }, { passive: false });\n    });\n    \n    update();\n})();\n<\/script>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>2026 \u7c21\u8b5c\u7de8\u8f2f\u5f15\u64ce<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2618","post","type-post","status-publish","format-standard","hentry","category-recentposts"],"_links":{"self":[{"href":"https:\/\/purestudio.com.tw\/official\/wp-json\/wp\/v2\/posts\/2618","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/purestudio.com.tw\/official\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/purestudio.com.tw\/official\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/purestudio.com.tw\/official\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/purestudio.com.tw\/official\/wp-json\/wp\/v2\/comments?post=2618"}],"version-history":[{"count":66,"href":"https:\/\/purestudio.com.tw\/official\/wp-json\/wp\/v2\/posts\/2618\/revisions"}],"predecessor-version":[{"id":3342,"href":"https:\/\/purestudio.com.tw\/official\/wp-json\/wp\/v2\/posts\/2618\/revisions\/3342"}],"wp:attachment":[{"href":"https:\/\/purestudio.com.tw\/official\/wp-json\/wp\/v2\/media?parent=2618"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/purestudio.com.tw\/official\/wp-json\/wp\/v2\/categories?post=2618"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/purestudio.com.tw\/official\/wp-json\/wp\/v2\/tags?post=2618"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}