Skip to content

Commit

Permalink
✨ feat: floating card
Browse files Browse the repository at this point in the history
  • Loading branch information
aaron-yang-biz committed Jul 5, 2024
1 parent 7a2a378 commit ba78e0d
Show file tree
Hide file tree
Showing 11 changed files with 453 additions and 41 deletions.
26 changes: 26 additions & 0 deletions README-cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,26 @@ Card变体的另一个例子。背景和正文被S型曲线分开。
</Scard>
```

### Floating Card

![](https://images.jieyu.ai/images/2024/07/float3dcard.png)

由一个序号、标题和描述文字组成。适合用于展示一个列表。

#### 用法示例

```
<FloatingCard :at=[0,1,2,3]
class="abs w-300px h-500px top-200px left-100px">
```yaml
color: "#F5C345"
capping: header
seq: "01"
title: LOREM IPSUM
desc: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
```



Expand Down Expand Up @@ -490,6 +509,13 @@ Admonition 是另一种卡片,但它是由 markdown-it 插件而不是组件

## History

### 0.3
- Released at July 5, 2024
- Features:
- Floating Card
- Fixed:
- markmap doesn't work when theme is installed from npmjs

### 0.2
- Release at July 4, 2024
- Features:
Expand Down
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ A Slidev theme that offers rich UI components and stunning visual effects. The f
* [Profile Card](#profile)
* [S-curve split Card](#scard)
* [Markdown admonition card](#admonition)
* [Floating Card]()
* [Markmap](#markmap)
* [Emoji](#markdown-icon)
* [Audio](#audio) with volume control, fadein and out
* [Video](#video)
* [Animation](#animated-css)


![](https://images.jieyu.ai/images/2024/07/cover.gif)
![](https://images.jieyu.ai/images/2024/07/mockup-device.gif)
![](https://images.jieyu.ai/images/2024/07/markmap.gif)
Expand Down Expand Up @@ -192,6 +194,8 @@ use generic unocss directive to control the position and size of the video.

Animate.css offers dozens of simple yet commonly used animations. However, direct usage can be inconvenient, requiring additional CSS file imports, lengthy and unwieldy style declarations, and, for exit effects, the animation reverses to its original state after the exit action completes, among other issues.

![](https://images.jieyu.ai/images/2024/07/anime.gif)

We provide the Anime component to facilitate easier utilization of Animate.css.

#### props
Expand Down Expand Up @@ -432,6 +436,29 @@ Except listed in props, the other part can be specified by generic unocss direct
</Scard>
```

### Floating Card

![](https://images.jieyu.ai/images/2024/07/float3dcard.png)

It consists of a seq number, a title and a description.

#### Example Usage

```
<FloatingCard :at=[0,1,2,3]
class="abs w-300px h-500px top-200px left-100px">
```yaml
color: "#F5C345"
capping: header
seq: "01"
title: LOREM IPSUM
desc: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
```

</FloatingCard>
```
### Markmap
Expand Down Expand Up @@ -531,6 +558,12 @@ The element will automatically bounce the element when the page is loaded.

## History

### 0.3
- Released at July 5, 2024
- Features:
- Floating Card
- Fixed:
- markmap doesn't work when theme is installed from npmjs
### 0.2
- Release at July 4, 2024
- Features:
Expand Down
2 changes: 1 addition & 1 deletion components/SoarText.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const animes = reactive([])
let rendered = {}
const container = ref(null)
const backgrounds = {}
const view = ref([])
const view = ref({})
let observer
const props = defineProps({
Expand Down
20 changes: 20 additions & 0 deletions components/Timeline.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
<!--
A vertical timeline.

https://images.jieyu.ai/images/2024/07/timeline.gif

Usage:

<div class="abs left-50px top-400px">

```yaml

- event: 1606年
img: https://*.jpg w=150 roundCorner="50%"
title: 第一张股票
text: 1606年,荷兰东印度公司发行了人类第一张股票
```
</div>


-->
<script setup>

import { ref, onMounted, reactive, watchEffect, nextTick } from 'vue';
Expand Down
File renamed without changes.
166 changes: 166 additions & 0 deletions components/card/FloatingCard.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<!--

check the prototype here

https://www.freepik.com/premium-vector/5-data-infographics-tab-paper-index-template-vector-illustration-abstract-background_18061427.htm?epik=dj0yJnU9MS1WaDZwTURzelVlN250TmJKdlJTZ3ZTMHNoak5rZXkmcD0wJm49QkpkR2tHdFVYaEtqTzh2c2VOV25aUSZ0PUFBQUFBR2FHMjRj#page=2&query=infographics%20infographic%20elements&position=24&from_view=search

-->

<script setup>
import YAML from 'yaml';
import { ref, onMounted, nextTick, onUnmounted, computed } from 'vue';
import { isShow, calcAngle } from '../../utils'
const raw = ref(null)
const data = ref({})
const container = ref(null)
const view = ref({})
let observer

const props = defineProps({
color: {
type: String,
default: "#F5C345"
},
at: {
type: [Number, Array],
default: -1
}
})

onMounted(async () => {
if (raw.value === null || $renderContext.value !== 'slide') {
return
}

data.value = YAML.parse(raw.value.textContent)

await nextTick();

observer = new ResizeObserver(entries => {
for (let entry of entries) {
const { width, height, top, left } = entry.contentRect;
if (width === 0 || height === 0) {
continue
}

let cx = width * 0.15
let cy = height * 0.1
view.value = {
x: cx,
y: cy,
blur: cx * 0.5,
rotateZ: calcAngle(cx, height)
}
}
})

if (container.value) {
observer.observe(container.value);
}
})

onUnmounted(() => {
if (observer && container.value) {
observer.unobserve(container.value);
}
});

const shadowX = computed(() => {
return view.value.x + "px"
})

const headerY = computed(() => {
return view.value.y * -1 + "px"
})

const footerY = computed(() => {
return view.value.y + "px"
})

const blur = computed(() => {
return view.value.blur + "px"
})

const footerZ = computed(() => {
return view.value.rotateZ * -1 + "deg"
})

const headerZ = computed(() => {
return view.value.rotateZ + "deg"
})


</script>
<style scoped>
.container-header,
.container-footer {
border-radius: 0.5em;
background-color: #fdfdfd;
padding: 1em;
}

.container-footer {
border-bottom: 2.5em solid var(--color);
}

.container-header {
border-top: 2.5em solid var(--color);
}

.container-header:after {
content: "";
position: absolute;
z-index: -1;
height: 90%;
width: 80%;
bottom: 5%;
box-shadow: var(--shadow-x) var(--header-y) var(--blur) rgba(0, 0, 0, 0.3);
transform: rotateZ(var(--header-z));
}

.container-footer:after {
content: "";
position: absolute;
z-index: -1;
height: 90%;
width: 80%;
bottom: 5%;
box-shadow: var(--shadow-x) var(--footer-y) var(--blur) rgba(0, 0, 0, 0.3);
transform: rotateZ(var(--footer-z));
}

.seq {
font-size: 1.5em;
font-weight: bold;
text-shadow: 1px 2px 2px rgba(0, 0, 0, 0.5);
}

.card-title {
color: var(--color);
}

.divider {
border-bottom: 2px solid grey;
}

.desc {
color: #808080;
margin-top: 2em;
}
</style>
<template>
<div style="display:none" ref="raw">
<slot />
</div>
<div v-if="isShow(props.at, $clicks)" v-bind="$attrs"
:style="[$attrs.style, { '--color': data.color, '--header-y': headerY, '--blur': blur, '--shadow-x': shadowX, '--footer-y': footerY, '--footer-z': footerZ, '--header-z': headerZ }]"
:class="[$attrs.class, `container-${data.capping}`]" ref="container">

<div class="seq">{{ data.seq }}</div>
<div class="card-title">{{ data.title }}</div>
<div class="divider" />
<div class="desc">{{ data.desc }}</div>
</div>


</template>
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit ba78e0d

Please sign in to comment.