From 5224d459946e9e56568bc48839ff3c46f91b575d Mon Sep 17 00:00:00 2001 From: yulonger's MacBook Pro 14 Date: Sat, 29 Aug 2026 18:59:41 +0800 Subject: [PATCH] feat: add easy-jyy Slidev theme --- .../components/ContentScaleControls.vue | 699 ++++++++++++++++++ .../components/PresenterAccess.vue | 137 ++++ .../components/SlideScrollFallback.vue | 31 + .../components/SmartImages.vue | 32 + .../slidev-theme-easy-jyy/global-bottom.vue | 13 + .../slidev-theme-easy-jyy/layouts/center.vue | 5 + .../slidev-theme-easy-jyy/layouts/cover.vue | 5 + .../slidev-theme-easy-jyy/layouts/default.vue | 5 + .../layouts/image-auto.vue | 74 ++ .../layouts/image-full.vue | 21 + .../layouts/image-left.vue | 23 + .../layouts/image-right.vue | 23 + .../slidev-theme-easy-jyy/layouts/quote.vue | 5 + .../slidev-theme-easy-jyy/layouts/section.vue | 5 + .../layouts/two-cols.vue | 9 + packages/slidev-theme-easy-jyy/package.json | 33 + .../slidev-theme-easy-jyy/setup/markdown.ts | 8 + .../slidev-theme-easy-jyy/styles/base.css | 233 ++++++ .../slidev-theme-easy-jyy/styles/content.css | 69 ++ .../slidev-theme-easy-jyy/styles/index.ts | 4 + .../slidev-theme-easy-jyy/styles/layouts.css | 283 +++++++ .../styles/presenter.css | 143 ++++ .../utils/resolve-image.ts | 15 + 23 files changed, 1875 insertions(+) create mode 100644 packages/slidev-theme-easy-jyy/components/ContentScaleControls.vue create mode 100644 packages/slidev-theme-easy-jyy/components/PresenterAccess.vue create mode 100644 packages/slidev-theme-easy-jyy/components/SlideScrollFallback.vue create mode 100644 packages/slidev-theme-easy-jyy/components/SmartImages.vue create mode 100644 packages/slidev-theme-easy-jyy/global-bottom.vue create mode 100644 packages/slidev-theme-easy-jyy/layouts/center.vue create mode 100644 packages/slidev-theme-easy-jyy/layouts/cover.vue create mode 100644 packages/slidev-theme-easy-jyy/layouts/default.vue create mode 100644 packages/slidev-theme-easy-jyy/layouts/image-auto.vue create mode 100644 packages/slidev-theme-easy-jyy/layouts/image-full.vue create mode 100644 packages/slidev-theme-easy-jyy/layouts/image-left.vue create mode 100644 packages/slidev-theme-easy-jyy/layouts/image-right.vue create mode 100644 packages/slidev-theme-easy-jyy/layouts/quote.vue create mode 100644 packages/slidev-theme-easy-jyy/layouts/section.vue create mode 100644 packages/slidev-theme-easy-jyy/layouts/two-cols.vue create mode 100644 packages/slidev-theme-easy-jyy/package.json create mode 100644 packages/slidev-theme-easy-jyy/setup/markdown.ts create mode 100644 packages/slidev-theme-easy-jyy/styles/base.css create mode 100644 packages/slidev-theme-easy-jyy/styles/content.css create mode 100644 packages/slidev-theme-easy-jyy/styles/index.ts create mode 100644 packages/slidev-theme-easy-jyy/styles/layouts.css create mode 100644 packages/slidev-theme-easy-jyy/styles/presenter.css create mode 100644 packages/slidev-theme-easy-jyy/utils/resolve-image.ts diff --git a/packages/slidev-theme-easy-jyy/components/ContentScaleControls.vue b/packages/slidev-theme-easy-jyy/components/ContentScaleControls.vue new file mode 100644 index 0000000..f2074ce --- /dev/null +++ b/packages/slidev-theme-easy-jyy/components/ContentScaleControls.vue @@ -0,0 +1,699 @@ + + + diff --git a/packages/slidev-theme-easy-jyy/components/PresenterAccess.vue b/packages/slidev-theme-easy-jyy/components/PresenterAccess.vue new file mode 100644 index 0000000..c5fc84f --- /dev/null +++ b/packages/slidev-theme-easy-jyy/components/PresenterAccess.vue @@ -0,0 +1,137 @@ + + + diff --git a/packages/slidev-theme-easy-jyy/components/SlideScrollFallback.vue b/packages/slidev-theme-easy-jyy/components/SlideScrollFallback.vue new file mode 100644 index 0000000..9ed8596 --- /dev/null +++ b/packages/slidev-theme-easy-jyy/components/SlideScrollFallback.vue @@ -0,0 +1,31 @@ + + + diff --git a/packages/slidev-theme-easy-jyy/components/SmartImages.vue b/packages/slidev-theme-easy-jyy/components/SmartImages.vue new file mode 100644 index 0000000..17222bf --- /dev/null +++ b/packages/slidev-theme-easy-jyy/components/SmartImages.vue @@ -0,0 +1,32 @@ + + + diff --git a/packages/slidev-theme-easy-jyy/global-bottom.vue b/packages/slidev-theme-easy-jyy/global-bottom.vue new file mode 100644 index 0000000..34f2681 --- /dev/null +++ b/packages/slidev-theme-easy-jyy/global-bottom.vue @@ -0,0 +1,13 @@ + + + diff --git a/packages/slidev-theme-easy-jyy/layouts/center.vue b/packages/slidev-theme-easy-jyy/layouts/center.vue new file mode 100644 index 0000000..ff4b658 --- /dev/null +++ b/packages/slidev-theme-easy-jyy/layouts/center.vue @@ -0,0 +1,5 @@ + diff --git a/packages/slidev-theme-easy-jyy/layouts/cover.vue b/packages/slidev-theme-easy-jyy/layouts/cover.vue new file mode 100644 index 0000000..f333814 --- /dev/null +++ b/packages/slidev-theme-easy-jyy/layouts/cover.vue @@ -0,0 +1,5 @@ + diff --git a/packages/slidev-theme-easy-jyy/layouts/default.vue b/packages/slidev-theme-easy-jyy/layouts/default.vue new file mode 100644 index 0000000..13c4c9a --- /dev/null +++ b/packages/slidev-theme-easy-jyy/layouts/default.vue @@ -0,0 +1,5 @@ + diff --git a/packages/slidev-theme-easy-jyy/layouts/image-auto.vue b/packages/slidev-theme-easy-jyy/layouts/image-auto.vue new file mode 100644 index 0000000..f6d3732 --- /dev/null +++ b/packages/slidev-theme-easy-jyy/layouts/image-auto.vue @@ -0,0 +1,74 @@ + + + diff --git a/packages/slidev-theme-easy-jyy/layouts/image-full.vue b/packages/slidev-theme-easy-jyy/layouts/image-full.vue new file mode 100644 index 0000000..8653b53 --- /dev/null +++ b/packages/slidev-theme-easy-jyy/layouts/image-full.vue @@ -0,0 +1,21 @@ + + + diff --git a/packages/slidev-theme-easy-jyy/layouts/image-left.vue b/packages/slidev-theme-easy-jyy/layouts/image-left.vue new file mode 100644 index 0000000..2a650b2 --- /dev/null +++ b/packages/slidev-theme-easy-jyy/layouts/image-left.vue @@ -0,0 +1,23 @@ + + + diff --git a/packages/slidev-theme-easy-jyy/layouts/image-right.vue b/packages/slidev-theme-easy-jyy/layouts/image-right.vue new file mode 100644 index 0000000..e6d880b --- /dev/null +++ b/packages/slidev-theme-easy-jyy/layouts/image-right.vue @@ -0,0 +1,23 @@ + + + diff --git a/packages/slidev-theme-easy-jyy/layouts/quote.vue b/packages/slidev-theme-easy-jyy/layouts/quote.vue new file mode 100644 index 0000000..51a5def --- /dev/null +++ b/packages/slidev-theme-easy-jyy/layouts/quote.vue @@ -0,0 +1,5 @@ + diff --git a/packages/slidev-theme-easy-jyy/layouts/section.vue b/packages/slidev-theme-easy-jyy/layouts/section.vue new file mode 100644 index 0000000..3d1f164 --- /dev/null +++ b/packages/slidev-theme-easy-jyy/layouts/section.vue @@ -0,0 +1,5 @@ + diff --git a/packages/slidev-theme-easy-jyy/layouts/two-cols.vue b/packages/slidev-theme-easy-jyy/layouts/two-cols.vue new file mode 100644 index 0000000..9b89a75 --- /dev/null +++ b/packages/slidev-theme-easy-jyy/layouts/two-cols.vue @@ -0,0 +1,9 @@ + diff --git a/packages/slidev-theme-easy-jyy/package.json b/packages/slidev-theme-easy-jyy/package.json new file mode 100644 index 0000000..c15e394 --- /dev/null +++ b/packages/slidev-theme-easy-jyy/package.json @@ -0,0 +1,33 @@ +{ + "name": "slidev-theme-easy-jyy", + "version": "0.2.0", + "description": "JYY-inspired presentation theme for easy-slides and Slidev", + "license": "MIT", + "private": false, + "type": "module", + "keywords": ["slidev-theme", "slidev"], + "publishConfig": { + "access": "public" + }, + "engines": { + "node": ">=20.12.0", + "slidev": ">=52.0.0" + }, + "slidev": { + "defaults": { + "aspectRatio": "4/3", + "canvasWidth": 1024, + "colorSchema": "light", + "fonts": { + "sans": "Lato,Noto Sans SC,PingFang SC,Microsoft YaHei,sans-serif", + "mono": "Inconsolata,JetBrains Mono,Fira Code,monospace", + "serif": "Noto Serif SC,STKaiti,KaiTi,serif" + } + } + }, + "dependencies": { + "@slidev/client": "52.19.1", + "@slidev/types": "52.19.1", + "markdown-it-attrs": "4.3.1" + } +} diff --git a/packages/slidev-theme-easy-jyy/setup/markdown.ts b/packages/slidev-theme-easy-jyy/setup/markdown.ts new file mode 100644 index 0000000..4869f80 --- /dev/null +++ b/packages/slidev-theme-easy-jyy/setup/markdown.ts @@ -0,0 +1,8 @@ +import { defineMarkdownSetup } from '@slidev/types' +import markdownItAttrs from 'markdown-it-attrs' + +export default defineMarkdownSetup(() => ({ + markdownItSetup(md) { + md.use(markdownItAttrs) + }, +})) diff --git a/packages/slidev-theme-easy-jyy/styles/base.css b/packages/slidev-theme-easy-jyy/styles/base.css new file mode 100644 index 0000000..6975ab3 --- /dev/null +++ b/packages/slidev-theme-easy-jyy/styles/base.css @@ -0,0 +1,233 @@ +:root { + --easy-accent: #1d4ed8; + --easy-accent-dark: #1e40af; + --easy-accent-soft: #eff6ff; + --easy-ink: #222; + --easy-muted: #666; + --easy-border: #ddd; + --easy-code-bg: #eee; + --easy-code-font-size: 28px; + --easy-table-font-size: 30px; + --easy-table-padding-x: 14px; + --easy-table-padding-y: 10px; + --easy-slide-padding-x: 52px; + --easy-slide-padding-y: 42px; + --easy-presenter-note-size: 20px; +} + +.easy-table-sm { + --easy-table-font-size: 24px; + --easy-table-padding-x: 10px; + --easy-table-padding-y: 7px; +} + +.easy-table-md { + --easy-table-font-size: 30px; + --easy-table-padding-x: 14px; + --easy-table-padding-y: 10px; +} + +.easy-table-lg { + --easy-table-font-size: 36px; + --easy-table-padding-x: 18px; + --easy-table-padding-y: 13px; +} + +.easy-code-sm { --easy-code-font-size: 22px; } +.easy-code-md { --easy-code-font-size: 28px; } +.easy-code-lg { --easy-code-font-size: 34px; } + +.easy-code-height-sm { --easy-code-height: 180px; } +.easy-code-height-md { --easy-code-height: 300px; } +.easy-code-height-lg { --easy-code-height: 420px; } + +.slidev-layout { + position: relative; + width: 100%; + height: 100%; + padding: var(--easy-slide-padding-y) var(--easy-slide-padding-x); + overflow: hidden; + border: 1.5px solid var(--easy-border); + border-radius: 7px; + background: #fff; + color: var(--easy-ink); + text-align: left; + font-family: Lato, "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif; + font-size: 32px; + font-weight: 300; + line-height: 1.42; +} + +.slidev-layout h1, +.slidev-layout h2, +.slidev-layout h3, +.slidev-layout h4 { + color: var(--easy-ink); + font-weight: 400; + letter-spacing: 0; + line-height: 1.15; +} + +.slidev-layout h1 { + margin: 0 0 26px; + font-size: 60px; +} + +.slidev-layout h2 { + margin: 0 0 28px; + padding-bottom: 8px; + border-bottom: 3px solid var(--easy-accent); + font-size: 48px; +} + +.slidev-layout h3 { + margin: 20px 0 14px; + font-size: 38px; +} + +.slidev-layout p, +.slidev-layout ul, +.slidev-layout ol { + margin-top: 14px; + margin-bottom: 14px; +} + +.slidev-layout ul, +.slidev-layout ol { + display: block; + padding-left: 1.2em; +} + +.slidev-layout li + li { + margin-top: 10px; +} + +.slidev-layout a { + color: var(--easy-accent); + text-decoration-thickness: 1px; + text-underline-offset: .13em; +} + +.slidev-layout strong { + font-weight: 700; +} + +.slidev-layout blockquote { + margin: 24px 0; + padding: 4px 0 4px 24px; + border-left: 5px solid var(--easy-accent); + color: #1e3a5f; + font-family: "Noto Serif SC", STKaiti, KaiTi, serif; + font-style: normal; +} + +.slidev-layout code { + font-family: Inconsolata, "JetBrains Mono", "Fira Code", monospace; +} + +.slidev-layout :not(pre) > code { + border-radius: 5px; + background: var(--easy-accent-soft); + color: var(--easy-accent-dark); + padding: .08em .28em; + font-size: .86em; +} + +.slidev-layout pre { + box-sizing: border-box; + height: var(--easy-code-height, var(--easy-code-auto-height, auto)); + max-height: var(--easy-code-height, var(--easy-code-auto-max-height, var(--easy-code-auto-height, none))); + overflow-x: hidden; + overflow-y: auto; + border-radius: 10px; + background: var(--easy-code-bg); + padding: 18px 20px; + font-size: var(--easy-code-scaled-font-size, var(--easy-code-font-size)) !important; + line-height: 1.38 !important; + white-space: pre-wrap; + overflow-wrap: anywhere; +} + +.slidev-layout pre code, +.slidev-layout pre code .line { + min-width: 0 !important; + white-space: pre-wrap !important; + overflow-wrap: anywhere; + word-break: normal; +} + +.slidev-layout table { + width: 100%; + border-collapse: collapse; + font-size: var(--easy-table-font-size); +} + +.slidev-layout th, +.slidev-layout td { + padding: var(--easy-table-padding-y) var(--easy-table-padding-x); + border-bottom: 1px solid #d5d5d5; +} + +.slidev-layout th { + background: #eee; + font-weight: 600; +} + +.slidev-layout tr:nth-child(even) { + background: #f7faff; +} + +.slidev-layout img { + display: block; + max-width: 100%; + max-height: 60vh; + margin: 16px auto; + object-fit: contain; +} + +.slidev-layout p:has(> img:only-child) { + display: grid; + place-items: center; + min-height: 46vh; + margin: 8px 0; +} + +.slidev-layout p:has(> img:only-child) > img { + width: 100%; + height: 46vh; + max-height: 60vh; + margin: 0; + object-fit: contain; +} + +.slidev-layout img[fit="cover"] { + width: 100%; + height: 100%; + object-fit: cover; +} + +.slidev-layout img[fit="fill"] { object-fit: fill; } +.slidev-layout img[fit="scale-down"] { object-fit: scale-down; } +.slidev-layout img[fit="none"] { object-fit: none; } + +.slidev-layout .katex-display, +.slidev-layout .mermaid { + max-width: 100%; + max-height: 60vh; + overflow: auto; +} + +.slidev-page-number { + border-radius: 5px; + background: rgba(0, 0, 0, .26); + padding: 3px 9px; + color: #fff; + font-size: 18px; +} + +@media (max-width: 760px) { + :root { + --easy-slide-padding-x: 34px; + --easy-slide-padding-y: 30px; + } +} diff --git a/packages/slidev-theme-easy-jyy/styles/content.css b/packages/slidev-theme-easy-jyy/styles/content.css new file mode 100644 index 0000000..0d60a59 --- /dev/null +++ b/packages/slidev-theme-easy-jyy/styles/content.css @@ -0,0 +1,69 @@ +/* Shared content utilities for course and technical decks. */ +.slidev-layout .lead { + color: var(--easy-accent); + font-size: 1.16em; + line-height: 1.35; +} + +.slidev-layout .muted { + color: var(--easy-muted); + font-size: .72em; +} + +.slidev-layout .compact, +.slidev-layout.compact { + font-size: 27px; +} + +.slidev-layout .compact li + li, +.slidev-layout.compact li + li { + margin-top: 6px; +} + +.slidev-layout .outline { + list-style: none; + margin: 22px 0 0; + padding: 0; +} + +.slidev-layout .outline > li { + margin: 12px 0; + padding-left: 22px; + border-left: 5px solid #ddd; +} + +.slidev-layout .outline .current { + border-left-color: var(--easy-accent); + color: var(--easy-accent); + font-weight: 600; +} + +.slidev-layout .source-figure { + width: 100%; + max-height: 56vh; + object-fit: contain; +} + +.slidev-layout .course-table { + font-size: 21px; + line-height: 1.2; +} + +.slidev-layout .course-table th, +.slidev-layout .course-table td { + padding: 6px 9px; +} + +.slidev-layout .v-word { + color: var(--easy-accent); + font-size: 1.22em; + font-weight: 600; +} + +.easy-layout-cover .cover-identity { + width: 68%; + height: 20vh; + margin: 22px 0 0; + object-fit: contain; + object-position: left center; +} diff --git a/packages/slidev-theme-easy-jyy/styles/index.ts b/packages/slidev-theme-easy-jyy/styles/index.ts new file mode 100644 index 0000000..e4c99bc --- /dev/null +++ b/packages/slidev-theme-easy-jyy/styles/index.ts @@ -0,0 +1,4 @@ +import './base.css' +import './content.css' +import './layouts.css' +import './presenter.css' diff --git a/packages/slidev-theme-easy-jyy/styles/layouts.css b/packages/slidev-theme-easy-jyy/styles/layouts.css new file mode 100644 index 0000000..b1ed0cb --- /dev/null +++ b/packages/slidev-theme-easy-jyy/styles/layouts.css @@ -0,0 +1,283 @@ +.easy-layout-center, +.easy-layout-section, +.easy-layout-cover { + display: flex; + flex-direction: column; + justify-content: center; +} + +.easy-layout-center { + align-items: center; + text-align: center; +} + +.easy-layout-center h1, +.easy-layout-center h2 { + text-align: center; +} + +.easy-layout-cover h1 { + margin-bottom: 28px; + font-size: 68px; +} + +.easy-layout-cover blockquote { + border: 0; + padding: 0; + color: var(--easy-accent); +} + +.easy-layout-section h1, +.easy-layout-section h2 { + max-width: 980px; +} + +.easy-layout-quote { + display: flex; + flex-direction: column; + justify-content: center; +} + +.easy-layout-quote blockquote { + border: 0; + padding: 0; + color: var(--easy-accent); + font-size: 46px; + line-height: 1.35; + text-align: center; +} + +.easy-layout-two-cols { + display: grid; + grid-template-rows: auto 1fr; +} + +.easy-layout-two-cols .easy-two-cols-grid { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); + gap: 46px; + min-height: 0; +} + +.easy-layout-image-split { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); + gap: 42px; +} + +.easy-layout-image-split.easy-image-left .easy-image-pane { order: -1; } + +.easy-layout-image-auto.easy-image-top, +.easy-layout-image-auto.easy-image-bottom { + grid-template-columns: minmax(0, 1fr); + grid-template-rows: auto minmax(0, 1fr); + gap: 22px; +} + +.easy-layout-image-auto.easy-image-top .easy-image-pane { order: -1; } + +.easy-image-pane { + min-width: 0; + min-height: 0; + display: grid; + grid-template-columns: minmax(0, 1fr); + grid-template-rows: minmax(0, 1fr); + place-items: center; + overflow: hidden; + border-radius: 8px; +} + +.easy-image-pane img { + min-width: 0; + min-height: 0; + width: 100%; + height: 100%; + max-width: 100%; + max-height: 100%; + margin: 0; +} + +.easy-content-scale-host { + position: relative; + min-width: 0; + min-height: 0; +} + +.easy-content-table-host { + width: 100%; + overflow: auto; +} + +.easy-content-code-host { + width: 100%; + margin-bottom: 0 !important; +} + +.easy-image-preview-trigger { + cursor: zoom-in; +} + +.easy-image-preview-trigger:focus-visible { + outline: 3px solid var(--easy-accent); + outline-offset: 4px; +} + +.easy-image-lightbox { + position: fixed; + inset: 0; + z-index: 2147483647; + display: grid; + grid-template-columns: minmax(0, 1fr); + grid-template-rows: minmax(0, 1fr); + place-items: center; + box-sizing: border-box; + min-width: 0; + min-height: 0; + padding: clamp(16px, 4vmin, 42px); + overflow: hidden; + overscroll-behavior: contain; + background: rgba(0, 0, 0, .92); +} + +.easy-image-lightbox-preview { + display: block; + place-self: center; + min-width: 0; + min-height: 0; + width: auto; + height: auto; + max-width: 100%; + max-height: 100%; + max-inline-size: 100%; + max-block-size: 100%; + margin: 0; + object-fit: contain; + object-position: center; +} + +.easy-image-lightbox-close { + position: absolute; + top: 18px; + right: 22px; + display: grid; + width: 46px; + height: 46px; + place-items: center; + border: 1px solid rgba(255, 255, 255, .5); + border-radius: 50%; + background: rgba(0, 0, 0, .55); + color: #fff; + padding: 0 0 4px; + font: 300 38px/1 Arial, sans-serif; + cursor: pointer; +} + +.easy-image-lightbox-close:hover, +.easy-image-lightbox-close:focus-visible { + border-color: #fff; + background: var(--easy-accent); + outline: none; +} + +.easy-content-scale-toolbar { + position: absolute; + top: 8px; + right: 8px; + z-index: 30; + display: flex; + gap: 3px; + padding: 4px; + border: 1px solid rgba(180, 180, 180, .9); + border-radius: 7px; + background: rgba(255, 255, 255, .94); + box-shadow: 0 4px 16px rgba(0, 0, 0, .12); + opacity: 0; + transition: opacity .14s ease; +} + +.easy-content-scale-host:hover > .easy-content-scale-toolbar, +.easy-content-scale-host:focus-within > .easy-content-scale-toolbar { + opacity: 1; +} + +.easy-content-scale-button { + min-width: 32px; + border: 0; + border-radius: 5px; + background: #eee; + color: #222; + padding: 6px 8px; + font: 600 14px/1 Lato, "Noto Sans SC", sans-serif; + cursor: pointer; +} + +.easy-content-scale-button:hover, +.easy-content-scale-button:focus-visible { + background: var(--easy-accent); + color: #fff; + outline: none; +} + +.easy-content-scale-reset { + min-width: 52px; +} + +.easy-content-code-host > .easy-content-scale-toolbar { + right: 48px; +} + +body.easy-slide-scroll-fallback .slidev-layout { + overflow-x: hidden; + overflow-y: auto; + overscroll-behavior-y: contain; + scrollbar-width: thin; + scrollbar-color: color-mix(in srgb, var(--easy-accent) 65%, transparent) transparent; +} + +.easy-image-content { + min-width: 0; + align-self: center; +} + +.easy-layout-image-full { + padding: 0; +} + +.easy-layout-image-full > img { + width: 100%; + height: 100%; + max-height: none; + margin: 0; +} + +.easy-layout-image-full .easy-image-overlay { + position: absolute; + inset: auto 0 0; + padding: 46px 54px; + background: linear-gradient(transparent, rgba(0, 0, 0, .78)); + color: #fff; +} + +.easy-layout-image-full .easy-image-overlay :is(h1, h2, h3, p) { + color: inherit; +} + +@media (max-aspect-ratio: 4 / 3) { + .easy-layout-two-cols .easy-two-cols-grid, + .easy-layout-image-split { + grid-template-columns: 1fr; + grid-template-rows: 1fr 1fr; + gap: 22px; + } +} + +@media (hover: none) { + .easy-content-scale-toolbar { opacity: .78; } +} + +@media print { + .easy-content-scale-toolbar, + .easy-image-lightbox { display: none !important; } + + body.easy-slide-scroll-fallback .slidev-layout { overflow: hidden !important; } +} diff --git a/packages/slidev-theme-easy-jyy/styles/presenter.css b/packages/slidev-theme-easy-jyy/styles/presenter.css new file mode 100644 index 0000000..b6d50a4 --- /dev/null +++ b/packages/slidev-theme-easy-jyy/styles/presenter.css @@ -0,0 +1,143 @@ +.easy-presenter-gate { + position: fixed; + inset: 0; + z-index: 2147483646; + display: none; + width: 100vw; + height: 100dvh; + max-width: none; + max-height: none; + margin: 0; + border: 0; + padding: 0; + place-items: center; + overflow: auto; + background: #f6f5f2; + color: #222; + font-family: Lato, "Noto Sans SC", "PingFang SC", sans-serif; +} + +.easy-presenter-gate[open] { + display: grid; +} + +.easy-presenter-gate::backdrop { + background: #f6f5f2; +} + +body.easy-presenter-locked { + overflow: hidden; +} + +.easy-presenter-dialog { + width: min(440px, calc(100vw - 40px)); + border: 1px solid #d8d4d7; + border-top: 4px solid var(--easy-accent); + border-radius: 9px; + background: #fff; + padding: 34px; + box-shadow: 0 20px 70px rgba(45, 26, 42, .14); +} + +.easy-presenter-dialog h1 { + margin: 0 0 10px; + font-size: 30px; +} + +.easy-presenter-dialog p { + color: #666; + line-height: 1.55; +} + +.easy-presenter-dialog form { + display: flex; + gap: 10px; + margin-top: 24px; +} + +.easy-presenter-dialog input { + min-width: 0; + flex: 1; + border: 1px solid #aaa; + border-radius: 6px; + padding: 11px 12px; + font: inherit; +} + +.easy-presenter-dialog button, +.easy-presenter-tools button, +.easy-presenter-launcher { + border: 0; + border-radius: 6px; + background: var(--easy-accent); + color: #fff; + padding: 10px 14px; + font: 600 14px/1.1 Lato, "Noto Sans SC", sans-serif; + cursor: pointer; +} + +.easy-presenter-error { + color: #a21d32 !important; + font-weight: 600; +} + +.easy-presenter-launcher { + position: fixed; + right: 18px; + bottom: 18px; + z-index: 60; + opacity: .22; + transition: opacity .16s ease; +} + +.easy-presenter-launcher:hover, +.easy-presenter-launcher:focus-visible { + opacity: 1; +} + +.easy-presenter-tools { + position: fixed; + top: 12px; + right: 12px; + z-index: 1000; + display: flex; + gap: 6px; + padding: 6px; + border: 1px solid #d4d0d3; + border-radius: 8px; + background: rgba(255, 255, 255, .94); + box-shadow: 0 5px 22px rgba(0, 0, 0, .12); +} + +.easy-presenter-tools button { + min-width: 34px; + background: #eee9ed; + color: #351231; + padding: 8px 10px; +} + +.easy-presenter-tools button:last-child { + background: #5d1357; + color: #fff; +} + +@media (max-width: 680px) { + .easy-presenter-tools { + right: auto; + left: 12px; + } +} + +body.easy-presenter-active :is(.presenter-notes, [class*="presenter"] [class*="notes"], [class*="presenter"] [class*="note"] p) { + font-size: var(--easy-presenter-note-size) !important; + line-height: 1.65 !important; +} + +body.easy-notes-contrast :is(.presenter-notes, [class*="presenter"] [class*="notes"], [class*="presenter"] [class*="note"]) { + background: #050505 !important; + color: #fff !important; +} + +body.easy-notes-contrast :is(.presenter-notes, [class*="presenter"] [class*="notes"], [class*="presenter"] [class*="note"]) * { + color: inherit !important; +} diff --git a/packages/slidev-theme-easy-jyy/utils/resolve-image.ts b/packages/slidev-theme-easy-jyy/utils/resolve-image.ts new file mode 100644 index 0000000..437049c --- /dev/null +++ b/packages/slidev-theme-easy-jyy/utils/resolve-image.ts @@ -0,0 +1,15 @@ +const deckBase = (import.meta as ImportMeta & { env: { BASE_URL: string } }).env.BASE_URL + +export function resolveImageSource(source: string | undefined, base = deckBase) { + if (!source || isAbsoluteSource(source)) + return source + + const normalizedBase = base.endsWith('/') ? base : `${base}/` + return `${normalizedBase}${source.replace(/^\.\//, '')}` +} + +function isAbsoluteSource(source: string) { + return source.startsWith('/') + || source.startsWith('#') + || /^[a-z][a-z\d+.-]*:/i.test(source) +}