当前位置: 首页 > article >正文

JS实现SVG的TEXT标签自动换行功能

首先定义了一个RectAndText组件,这个组件实现了在矩形中显示居中的文本(矩形可以根据自己需求要或者不要)

<template>
    <rect :x="x" :y="y" :width="width" :height="height" :stroke="stroke" :stroke-width="strokeWidth"></rect>
  <g v-if="lines.length <= 1">
    <text :x="getRectangleCenter(x, y, width, height).centerX + skewX"
          :y="getRectangleCenter(x, y, width, height).centerY + skewY"
          :font-size="fontSize" :fill="fill" :font-family="fontFamily" text-anchor="middle" alignment-baseline="middle">
      {{ title }}</text>

  </g>

  <g v-if="lines.length > 1" :transform="`translate(${getRectangleCenter(x, y, width, height).centerX + skewX},${getRectangleCenter(x, y, width, height).centerY + skewY - (lines.length - 1) * fontSize / 4})`">
    <text v-for="(line, index) in lines" :key="index" :x="0" :y="index * fontSize * 1.2" :font-size="fontSize" :fill="fill" :font-family="fontFamily" text-anchor="middle" alignment-baseline="ideographic">
      {{ line }}
    </text>
  </g>
</template>

<script setup>
//自定义组件 绘制矩形的同时渲染一个居中的文本
import {onMounted, ref} from "vue";

const props = defineProps({
  fontSize: {
    type: Number,
    default: () => 40
  },
  fontFamily: {
    type: String,
    default: () => 'NSimSun'
  },
  stroke: {
    type: String,
    default: () => '#ffffff'
  },
  fill: {
    type: String,
    default: () => '#ffffff'
  },
  title: {
    type: [String, Number],
    default: () => ''
  },
  x: {
    type: Number,
    default: () => 100
  },
  y: {
    type: Number,
    default: () => 100
  },
  height: {
    type: Number,
    default: () => 100
  },
  width: {
    type: Number,
    default: () => 100
  },
  strokeWidth: {
    type: String,
    default: () => '2'
  },
  //偏移量:有时候不一定会居中显示,有可能偏移
  skewX: {
    type: Number,
    default: () => 0
  },
  skewY: {
    type: Number,
    default: () => 0
  },
});

// 使用computed属性来将title字符串分割成多行
const lines = computed(() => {
  // 检查 props.title 是否是一个字符串
  if (typeof props.title === 'string') {
    // 如果是字符串,则按换行符分割
    return props.title.split('\n');
  } else {
    // 如果不是字符串,返回一个空数组或包含默认值的数组
    return [''];
  }
});


onMounted(() => {

});

//计算文字在矩形居中的位置
function getRectangleCenter(x, y, width, height) {
  // 计算中心点的x坐标
  const centerX = x + width / 2;
  // 计算中心点的y坐标
  const centerY = y + height / 2;

  // 返回中心点坐标
  return { centerX, centerY };
}
</script>

第一个g里面实现了默认的一行居中显示文本。重点是第二个g,如果检测到了文本中存在换行符\n,则渲染第二个g,这里通过transform实现y坐标的偏移,偏移量是根据fontSize文本大小来计算的,这是为了保证在偏移时不超出矩形边框。这时你只需要传入一个包含\n的文本字符串就可以实现动态换行了。效果如下:
在这里插入图片描述
在这里插入图片描述
至于如何换行的逻辑,这里就需要自己去实现,我举个例子:
我这边有个字符串"IG,IIG,3G,4G,4DG,8DG,4G,4DG",我需要把他拆分为两行显示,我通过,分割出来的字符串确认要从哪里进行拆分,(同时拆分后要把文字大小减小,否则会超出矩形边框,这个根据自己的需求去写就行)。

/**
 * 文本换行逻辑
 * 动态的通过\n分割文本
 * 同时计算文本的大小(比如文本默认大小是40,那么分为两行就要变为30,三行变为20...)
 */
function getTextLineAndSize(text, fontSize, devicesPerLine) {
  let devices = text.split(',');
  let lines = Math.ceil(devices.length / devicesPerLine); // 计算需要的行数
  let decreaseSize = 10 * (lines - 1); // 每增加一行,字体大小减少10
  let result = { content: text, size: fontSize - decreaseSize };

  // 根据每行的设备数量添加换行符
  for (let i = devicesPerLine; i < devices.length; i += devicesPerLine) {
    devices[i] = '\n' + devices[i];
  }

  result.content = devices.join(',');
  return result;
}

最后是调用这个组件的例子,这里的变量自己传入就可以

<RectAndText :x="rectX" :y="rectY" :width="rectWidth" :height="100" :stroke="stroke" :strokeWidth="strokeWidth" :fontSize="getTextLineAndSize(devName, fontSize, 4).size" :title="getTextLineAndSize(devName, fontSize, 4).content"/>

http://www.kler.cn/a/469233.html

相关文章:

  • [CTF/网络安全] 攻防世界 view_source 解题详析
  • UE5失真材质
  • 3.6 高级树形数据结构(2-3-4树、B树、B+树、哈夫曼树等)
  • 【HF设计模式】05-单例模式
  • 深入Android架构(从线程到AIDL)_09 认识Android的主线程
  • MATLAB R2015b安装、激活记录少走弯路
  • 【Unity Shader】【图形渲染】Unity Shader操作基础5-Unity Shader调试技巧
  • 面向实习的Golang服务端技能分析
  • MATLAB语言的函数实现
  • [桌面运维]windows自动设置浅深色主题
  • 基于Springboot +Vue 实验课程预约管理系统
  • [CTF/网络安全] 攻防世界 simple_php 解题详析
  • 决策树和随机森林
  • 云手机 —— 手机矩阵的 “超级外挂
  • JAVA解析Excel复杂表头
  • HTML——66.单选框
  • Unity3D 搭建ILRuntime开发环境详解
  • security框架的安全登录
  • 【Cesium】九、Cesium点击地图获取点击位置的坐标,并在地图上添加图标
  • Chrome 查看 session 信息