Skip to content

Commit

Permalink
Delete ratio attribute in Carousel.
Browse files Browse the repository at this point in the history
修得我想吊。
  • Loading branch information
M1hono committed Sep 16, 2024
1 parent ea6a0e6 commit 4b50558
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 112 deletions.
81 changes: 41 additions & 40 deletions .vitepress/plugins/carousels.ts
Original file line number Diff line number Diff line change
@@ -1,58 +1,59 @@
import { tab, MarkdownItTabOptions } from "@mdit/plugin-tab";
import { logger } from '../config/sidebarControl';
import { logger } from "../config/sidebarControl";
import type { PluginSimple } from "markdown-it";

// 深拷贝函数
function deepCloneEnv(env) {
return JSON.parse(JSON.stringify(env));
}

export const carousels: PluginSimple = (md) => {
md.use(tab, {
name: "carousels",
tabsOpenRenderer(info, tokens, index, opt, env) {
const content = JSON.parse(JSON.stringify(env))
const IContent = content.content
let token: string = ""
let config: string = ""
if (IContent && typeof IContent === "string") {
const matches = IContent.match(/carousels#\{[^\}]*\}/g)
if (matches) {
matches.forEach(match => {
token += match.replace("carousels#", "")
})
}
}
// logger(JSON.stringify(tokens[index]), "jsonCheck.json")
try {
const configObj = JSON.parse(token)

if (configObj.arrows) {
if (typeof configObj.arrows === "boolean") {
config += ` :show-arrows="${configObj.arrows}"`
} else if (configObj.arrows === "hover") {
config += ` :show-arrows="hover"`
// 每次使用时深拷贝 env,确保配置不被共享
const localEnv = deepCloneEnv(env);
const IContent = localEnv.content;
let config = "";

// 重新解析 meta 字段中的配置,确保每次渲染时配置独立
const token = tokens[index];
if (token && token.meta && typeof token.meta.id === 'string') {
try {
const configObj = JSON.parse(token.meta.id);
if (configObj.arrows !== undefined) {
config += ` :show-arrows="${configObj.arrows}"`;
}
}

if (configObj.undelimiters && configObj.undelimiters === true) config += ` :hide-delimiters="true"`

if (configObj.cycle && configObj.cycle === true) {
config += ` :cycle="true"`

if (configObj.interval && typeof configObj.interval === "number") {
config += ` :interval="${configObj.interval}"`
if (configObj.cycle !== undefined) {
config += ` :cycle="${configObj.cycle}"`;
}
if (configObj.interval !== undefined) {
config += ` :interval="${configObj.interval}"`;
}
if (configObj.undelimiters !== undefined) {
config += ` :hide-delimiters="${configObj.undelimiters}"`;
}
config += ` :continuous="true"`;
} catch (error) {
console.error("Error parsing carousel config from meta:", error);
}

if (configObj.ratio && typeof configObj.ratio === "number") config += `aspectRatio="${configObj.ratio}" `
} catch (error) { }
return `<MdCarousel${config} >`;
}

// 确保每次返回独立配置的组件实例
return `<MdCarousel
v-model="currentIndex"${config}
@update:model-value="handleSlideChange"
@before-change="onBeforeChange"
>`;
},
tabsCloseRenderer() {
return `</MdCarousel>`;
},
tabOpenRenderer(data) {

return `\n<v-carousel-item cover src="${data.title}">\n`;
tabOpenRenderer() {
return `\n<v-carousel-item>\n`;
},
tabCloseRenderer() {
return `</v-carousel-item>`;
return `</v-carousel-item>\n`;
},
})
});
};
136 changes: 84 additions & 52 deletions .vitepress/theme/components/carousels.vue
Original file line number Diff line number Diff line change
@@ -1,97 +1,129 @@
<template>
<div class="carousel">
<v-responsive :aspect-ratio="aspectRatio" ref="responsiveContainer">
<!-- 动态的 v-responsive 宽高比 -->
<v-carousel
:height="carouselHeight"
:show-arrows="showArrows"
:cycle="cycle"
:interval="interval"
:hide-delimiters="hideDelimiters"
>
<slot></slot>
</v-carousel>
</v-responsive>
<div class="carousel" ref="carouselContainer">
<v-carousel
v-if="isReady"
:height="carouselHeight"
:show-arrows="showArrows"
:cycle="cycle"
:interval="interval"
:hide-delimiters="hideDelimiters"
>
<slot></slot>
</v-carousel>
</div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue'
import { ref, onMounted, onUnmounted, nextTick, watch } from "vue";
const props = defineProps({
aspectRatio: {
type: Number,
default: 16 / 9, // 默认宽高比
},
showArrows: {
type: [Boolean, String],
default: true, // 控制箭头的显示,默认为 true,可以传入 'hover' 显示
default: true,
},
cycle: {
type: Boolean,
default: false, // 是否启用自动轮播
default: false,
},
interval: {
type: Number,
default: 6000, // 自动轮播的间隔
default: 6000,
},
hideDelimiters: {
type: Boolean,
default: false, // 是否隐藏指示点
default: false,
},
})
});
const carouselHeight = ref(0)
const responsiveContainer = ref(null)
const carouselContainer = ref(null);
const carouselHeight = ref("auto");
const isReady = ref(false);
const updateCarouselHeight = () => {
if (responsiveContainer.value) {
const containerElement = responsiveContainer.value.$el;
carouselHeight.value = containerElement.offsetWidth / props.aspectRatio;
if (carouselContainer.value) {
const items =
carouselContainer.value.querySelectorAll(".v-carousel__item");
let maxHeight = 0;
items.forEach((item) => {
item.style.display = "block";
const itemHeight = item.scrollHeight;
item.style.display = "";
if (itemHeight > maxHeight) maxHeight = itemHeight;
});
carouselHeight.value = maxHeight > 0 ? `${maxHeight}px` : "auto";
isReady.value = true;
}
}
};
const debouncedUpdateHeight = debounce(updateCarouselHeight, 100);
let resizeObserver = null;
if (typeof ResizeObserver !== 'undefined') {
resizeObserver = new ResizeObserver(() => {
updateCarouselHeight()
});
if (typeof ResizeObserver !== "undefined") {
resizeObserver = new ResizeObserver(debouncedUpdateHeight);
}
onMounted(() => {
nextTick(() => {
updateCarouselHeight()
if (responsiveContainer.value && resizeObserver) {
resizeObserver.observe(responsiveContainer.value.$el)
if (carouselContainer.value && resizeObserver) {
resizeObserver.observe(carouselContainer.value);
}
})
})
window.addEventListener("resize", debouncedUpdateHeight);
updateCarouselHeight();
});
});
onUnmounted(() => {
if (responsiveContainer.value && resizeObserver) {
resizeObserver.unobserve(responsiveContainer.value.$el)
if (carouselContainer.value && resizeObserver) {
resizeObserver.unobserve(carouselContainer.value);
}
if (resizeObserver) {
resizeObserver.disconnect()
resizeObserver.disconnect();
}
})
</script>
window.removeEventListener("resize", debouncedUpdateHeight);
});
watch(
() => props,
() => {
nextTick(updateCarouselHeight());
},
{ deep: true, immediate: true }
);
<style>
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
</script>

<style scoped>
.carousel {
width: 100%;
max-width: 100vw;
}
:deep(.v-carousel__item) {
position: absolute;
top: 0;
left: 0;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: auto;
max-height: 100vh;
position: relative;
}
.carousel img {
width: 100%;
height: 100%;
object-fit: cover;
:deep(.v-carousel__item img) {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,43 @@ next: false

概念参考图:

<Carousel :cycle="false">
<img src="https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/samples/1.png">
<img src="https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/samples/2.png">
<img src="https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/samples/3.png">
<img src="https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/samples/4.png">
<img src="https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/samples/5.png">
</Carousel>
::: carousels#{"arrows": true, "undelimiters": true }
@tab
![1](https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/samples/1.png)
@tab
![2](https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/samples/2.png)
@tab
![3](https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/samples/3.png)
@tab
![4](https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/samples/4.png)
@tab
![6](https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/samples/5.png)
:::

![alt text](/crychic/artdesign/avalonward/entities/mage/guide1.png)

玻璃瓶参考图:

<Carousel :cycle=" false">
<img src="https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/bottles/1.png">
<img src="https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/bottles/2.png">
<img src="https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/bottles/3.png">
<img src="https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/bottles/4.png">
<img src="https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/bottles/5.png">
<img src="https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/bottles/6.png">
</Carousel>
::: carousels#{"arrows": false,"undelimiters": false}
@tab
![1](https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/bottles/1.png)
@tab
![1](https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/bottles/2.png)
@tab
![1](https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/bottles/3.png)
@tab
![1](https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/bottles/4.png)
@tab
![1](https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/bottles/5.png)
@tab
![1](https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/bottles/6.png)
:::

卢恩文字参考图

<Carousel :cycle="false">
<img src="https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/lunes/1.png">
<img src="https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/lunes/2.png">
</Carousel>
::: carousels#{"undelimiters": false}
@tab
![1](https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/lunes/1.png)
@tab
![1](https://docs.mihono.cn/crychic/artdesign/avalonward/entities/mage/lunes/2.png)
:::
3 changes: 2 additions & 1 deletion docs/zh/doc/styleList.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,13 +216,14 @@ VuePress Theme Hope ++十分++ 强大。
:::
::::

> 尝试塞入一个 codeblock 试试?
### 配置语法 {#carousels-grammer}

`carousels`容器的配置项由跟随在容器声明后的`json`提供,使用`#`以连接配置与容器声明。

| 配置字段 | 用途 | 类型 | 省缺值 |
|----------------|----------------------------------------|---------|---------|
| `ratio` | 设置横幅的比例,默认为16:9。 | `number` | `16/9` |
| `cycle` | 设置横幅是否自动循环,默认为关闭。 | `boolean` | `false` |
| `interval` | 设置横幅循环时停留的时间,默认为6秒。 | `number` | `6000` |
| `arrows` | 设置横幅导航控制按钮是否显示,hover为<br/>鼠标悬停在横幅上时显示,默认显示。 | `boolean` \| "`hover`" | `true` |
Expand Down

0 comments on commit 4b50558

Please sign in to comment.