forked from mengyxu/noob-components
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.3 KiB
84 lines
2.3 KiB
<template> |
|
<div class="main"> |
|
<el-button @click="generateText">Generate Lorem Ipsum</el-button> |
|
<el-input v-model="text" type="textarea"></el-input> |
|
<el-slider |
|
v-model="widthPercent" |
|
:min="0" |
|
:max="100" |
|
:step="1" |
|
:format-tooltip="(percent) => `${percent}%`" |
|
></el-slider> |
|
<div class="comparison"> |
|
<div class="bounding-box"> |
|
<div class="render css-render">{{ text }}</div> |
|
</div> |
|
<div class="bounding-box"> |
|
<div class="render pretext-render" ref="pretextRenderRef"> |
|
<div v-for="(line, idx) in pretextRenderResult.lines" :key="idx">{{ line.text }}</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</template> |
|
|
|
<script setup lang="ts"> |
|
import { layout, layoutWithLines, prepare, prepareWithSegments } from "@chenglou/pretext"; |
|
import { useElementSize } from "@vueuse/core"; |
|
import { LoremIpsum } from "lorem-ipsum"; |
|
import { computed, ref, StyleValue, toRef, useTemplateRef } from "vue"; |
|
|
|
const lorem = new LoremIpsum({ |
|
sentencesPerParagraph: { min: 10, max: 20 }, |
|
wordsPerSentence: { min: 4, max: 20 }, |
|
}); |
|
const text = ref<string>(lorem.generateParagraphs(1)); |
|
const widthPercent = ref<number>(60); |
|
const width = computed(() => `${Math.round(widthPercent.value)}%`); |
|
const generateText = () => { |
|
text.value = lorem.generateParagraphs(1); |
|
}; |
|
const pretextRenderRef = useTemplateRef("pretextRenderRef"); |
|
const { width: pretextRenderWidth } = useElementSize(pretextRenderRef); |
|
|
|
const font = ref("16px Microsoft YaHei"); |
|
const lineHeight = ref(20); |
|
|
|
const preparedText = computed(() => prepareWithSegments(text.value, font.value, { whiteSpace: "normal" })); |
|
const pretextRenderResult = toRef(() => |
|
layoutWithLines(preparedText.value, pretextRenderWidth.value ?? 0, lineHeight.value) |
|
); |
|
</script> |
|
|
|
<style scoped lang="scss"> |
|
.main { |
|
flex: 1; |
|
width: 80%; |
|
align-self: center; |
|
display: flex; |
|
flex-direction: column; |
|
} |
|
.textarea { |
|
min-height: 200px; |
|
} |
|
.comparison { |
|
flex: 1; |
|
overflow: hidden; |
|
display: flex; |
|
flex-direction: row; |
|
justify-content: space-between; |
|
gap: 10px; |
|
padding: 5px; |
|
} |
|
.bounding-box { |
|
flex: 1; |
|
} |
|
.render { |
|
font: v-bind("font"); |
|
border: solid grey 1px; |
|
width: v-bind("width"); |
|
height: fit-content; |
|
line-height: v-bind("`${lineHeight}px`"); |
|
text-align: center; |
|
} |
|
</style>
|
|
|