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.
85 lines
2.3 KiB
85 lines
2.3 KiB
|
3 months ago
|
<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>
|