CSS线性渐变拼接,一个完整的渐变容器(div),要拆分成多个渐变容器(div),并且保持渐变效果一致

news2024/11/17 16:53:19

1 需求

一个有渐变背景的div,需要替换成多个渐变背景div拼接,渐变效果需要保持一致(不通过一个大的div渐变,其他子的div绝对定位其上并且背景透明来解决)

2 分析

主要工作:

  1. 计算完整div背景线性渐变时的渐变开始线和结束线(假设中心点为几何中心)
  2. 计算各个独立div背景线性渐变时的渐变开始线和结束线(假设中心点为几何中心)
  3. 重新计算各个子div的渐变开始线和结束线(百分比)

3 实现

3.1 水平拼接

在这里插入图片描述

解释:

  • 黑色虚线为各个子div的水平和垂直中心线
  • 红色虚线为整个div的水平和垂直中心线
  • 绿色虚线为渐变方向上的中心线,和黑色虚线的夹角为各个子div的渐变角
  • 紫色虚线为渐变方向上的中心线,和红色虚线的夹角为整个div的渐变角
  • 蓝色虚线为渐变开始线和结束线,垂直于渐变方向上的中心线
  • 蓝色圆为各个子div独立渐变时的渐变起始中心点,绿色圆为各个子div独立渐变时的渐变结束中心点
  • 紫色圆为整个div的渐变起始中心点,红色圆为整个div的渐变结束中心点
  • 蓝色紫色双圆为当前子div独立渐变时和其作为整个div整体渐变的一部分时的共同渐变起始中心点,是重合的
  • 绿色红色双圆为当前子div独立渐变时和其作为整个div整体渐变的一部分时的共同渐变结束中心点,是重合的
  • 蓝色实线段为整个渐变路径,其长度为渐变长度,也就是颜色值后面的参数0-100%
  • 绿色实线段为为了作为整体渐变一部分而需要增加的渐变路径
<template>
  <div class="container gradient"></div>
  <div class="container">
    <div
      class="container-column"
      v-for="(col, index) in itemList"
      :key="index"
      :style="{
        width: col.width + 'px',
        height: col.height + 'px',
        background: getGradient(col, index)
      }"
    ></div>
  </div>
</template>

<script setup lang="ts">
const itemList = ref([
  {
    width: 100,
    height: 400
  },
  {
    width: 200,
    height: 400
  },
  {
    width: 300,
    height: 400
  }
]);
const angle = ref(45);

const getGradient = (item, index) => {
  const beforeWidth = itemList.value.slice(0, index).reduce((a, b) => a + b.width, 0);
  const afterWidth = itemList.value.slice(index + 1).reduce((a, b) => a + b.width, 0);
  const startPosition = `calc(100% - (${beforeWidth} * sin(${angle.value}deg) / (2 * (${item.width / 2} * tan(${angle.value}deg) + ${item.height / 2}) * cos(${angle.value}deg)) + 1) * 100%)`;
  const endPosition = `calc((${afterWidth} * sin(${angle.value}deg) / (2 * (${item.width / 2} * tan(${angle.value}deg) + ${item.height / 2}) * cos(${angle.value}deg)) + 1) * 100%)`;
  const ret = `linear-gradient(${angle.value}deg,
        red ${startPosition},
        blue ${endPosition}
      )`;
  return ret;
};
</script>
<style scoped lang="scss">
.container {
  width: 600px;
  height: 400px;
  display: inline-block;

  .container-column {
    display: inline-block;
  }
}
.gradient {
  background: linear-gradient(45deg, red 0%, blue 100%);
}
</style>


效果:

在这里插入图片描述

加上边框更清晰点:

在这里插入图片描述

3.2 垂直拼接

在这里插入图片描述

解释:

  • 黑色虚线为各个子div的水平和垂直中心线
  • 红色虚线为整个div的水平和垂直中心线
  • 绿色虚线为渐变方向上的中心线,和黑色虚线的夹角为各个子div的渐变角
  • 紫色虚线为渐变方向上的中心线,和红色虚线的夹角为整个div的渐变角
  • 蓝色虚线为渐变开始线和结束线,垂直于渐变方向上的中心线
  • 蓝色圆为各个子div独立渐变时的渐变起始中心点,绿色圆为各个子div独立渐变时的渐变结束中心点
  • 紫色圆为整个div的渐变起始中心点,红色圆为整个div的渐变结束中心点
  • 蓝色紫色双圆为当前子div独立渐变时和其作为整个div整体渐变的一部分时的共同渐变起始中心点,是重合的
  • 绿色红色双圆为当前子div独立渐变时和其作为整个div整体渐变的一部分时的共同渐变结束中心点,是重合的
  • 蓝色实线段为整个渐变路径,其长度为渐变长度,也就是颜色值后面的参数0-100%
  • 绿色实线段为为了作为整体渐变一部分而需要增加的渐变路径
<template>
  <div class="container gradient"></div>
  <div class="container">
    <div
      class="container-column"
      v-for="(col, index) in itemList"
      :key="index"
      :style="{
        width: col.width + 'px',
        height: col.height + 'px',
        background: getGradient(col, index)
      }"
    ></div>
  </div>
</template>

<script setup lang="ts">
const itemList = ref([
  {
    width: 400,
    height: 100
  },
  {
    width: 400,
    height: 200
  },
  {
    width: 400,
    height: 300
  },
  {
    width: 400,
    height: 300
  }
]);
const angle = ref(45);

const getGradient = (item, index) => {
  const afterHeight = itemList.value.slice(0, index).reduce((a, b) => a + b.height, 0);
  const beforeHeight = itemList.value.slice(index + 1).reduce((a, b) => a + b.height, 0);
  const startPosition = `calc(100% - (${beforeHeight} * cos(${angle.value}deg) / (2 * (${item.width / 2} * tan(${angle.value}deg) + ${item.height / 2}) * cos(${angle.value}deg)) + 1) * 100%)`;
  const endPosition = `calc((${afterHeight} * cos(${angle.value}deg) / (2 * (${item.width / 2} * tan(${angle.value}deg) + ${item.height / 2}) * cos(${angle.value}deg)) + 1) * 100%)`;
  const ret = `linear-gradient(${angle.value}deg,
        red ${startPosition},
        blue ${endPosition}
      )`;
  return ret;
};
</script>
<style scoped lang="scss">
.container {
  width: 400px;
  height: 900px;
  display: inline-block;
  & + .container {
    margin-left: 10px;
  }
  line-height: 0;
  .container-column {
    display: inline-block;
  }
}
.gradient {
  background: linear-gradient(45deg, red 0%, blue 100%);
}
</style>

</style>


效果:

在这里插入图片描述

加上边框更清晰点:

在这里插入图片描述

3.3 矩阵拼接

在这里插入图片描述

图上画线太多,下图画个稍微简明点的

在这里插入图片描述

解释:

  • 黑色虚线为各个子div的水平和垂直中心线
  • 红色虚线为整个div的水平和垂直中心线
  • 绿色虚线为渐变方向上的中心线,和黑色虚线的夹角为各个子div的渐变角
  • 紫色虚线为渐变方向上的中心线,和红色虚线的夹角为整个div的渐变角
  • 蓝色虚线为渐变开始线和结束线,垂直于渐变方向上的中心线
  • 蓝色圆为各个子div独立渐变时的渐变起始中心点,绿色圆为各个子div独立渐变时的渐变结束中心点
  • 紫色圆为整个div的渐变起始中心点,红色圆为整个div的渐变结束中心点
  • 蓝色紫色双圆为当前子div独立渐变时和其作为整个div整体渐变的一部分时的共同渐变起始中心点,是重合的
  • 绿色红色双圆为当前子div独立渐变时和其作为整个div整体渐变的一部分时的共同渐变结束中心点,是重合的
  • 蓝色实线段为整个渐变路径,其长度为渐变长度,也就是颜色值后面的参数0-100%
  • 绿色实线段为为了作为整体渐变一部分而需要增加的渐变路径
<template>
  <div class="container gradient"></div>
  <div class="container">
    <div class="container-row" v-for="(row, rowIndex) in itemList" :key="rowIndex">
      <div
        class="container-column"
        v-for="(col, colIndex) in row"
        :key="colIndex"
        :style="{
          width: col.width + 'px',
          height: col.height + 'px',
          background: getGradient(col, colIndex, rowIndex)
        }"
      ></div>
    </div>
  </div>
</template>

<script setup lang="ts">
const itemList = ref([
  [
    {
      width: 100,
      height: 100
    },
    {
      width: 300,
      height: 100
    }
  ],
  [
    {
      width: 200,
      height: 200
    },
    {
      width: 100,
      height: 200
    },
    {
      width: 100,
      height: 200
    }
  ],
  [
    {
      width: 100,
      height: 300
    },
    {
      width: 100,
      height: 300
    },
    {
      width: 100,
      height: 300
    },
    {
      width: 100,
      height: 300
    }
  ],
  [
    {
      width: 400,
      height: 300
    }
  ]
]);
const angle = ref(45);

const getGradient = (item, colIndex, rowIndex) => {
  const afterHeight = itemList.value.slice(0, rowIndex).reduce((a, b) => a + b[0].height, 0);
  const beforeHeight = itemList.value.slice(rowIndex + 1).reduce((a, b) => a + b[0].height, 0);
  const beforeWidth = itemList.value[rowIndex].slice(0, colIndex).reduce((a, b) => a + b.width, 0);
  const afterWidth = itemList.value[rowIndex].slice(colIndex + 1).reduce((a, b) => a + b.width, 0);
  const startPosition = `calc(100% - ((${beforeHeight} * cos(${angle.value}deg) + ${beforeWidth} * sin(${angle.value}deg))/ (2 * (${item.width / 2} * tan(${angle.value}deg) + ${item.height / 2}) * cos(${angle.value}deg)) + 1) * 100%)`;
  const endPosition = `calc(((${afterHeight} * cos(${angle.value}deg) + ${afterWidth} * sin(${angle.value}deg)) / (2 * (${item.width / 2} * tan(${angle.value}deg) + ${item.height / 2}) * cos(${angle.value}deg)) + 1) * 100%)`;
  const ret = `linear-gradient(${angle.value}deg,
        red ${startPosition},
        blue ${endPosition}
      )`;
  return ret;
};
</script>
<style scoped lang="scss">
.container {
  width: 400px;
  height: 900px;
  display: inline-block;
  & + .container {
    margin-left: 10px;
  }
  .container-row {
    line-height: 0;
    .container-column {
      display: inline-block;
    }
  }
}
.gradient {
  background: linear-gradient(45deg, red 0%, blue 100%);
}
</style>


效果:

在这里插入图片描述

加上边框更清晰点:

在这里插入图片描述

4 最后

还可以有更复杂的情况:

  • 矩阵中的跨行跨列,大家可自行探索(其实投篮的办法是可以把跨行跨列的单元再进行拆分,使得所有单元都不出现跨行跨列,那么上面第三种矩阵拼接就可以使用了)
  • 多个颜色(中间的颜色需要根据当前百分比位置和增加的距离得到最终的百分比位置)
  • 非线性渐变的情况(感觉稍微有点复杂)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2088868.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

福建聚鼎:装饰画店铺怎么做盈利快

在艺术的殿堂里&#xff0c;装饰画店铺是一扇通往美与创意的门。要想让这扇门快速盈利&#xff0c;我们需要从多个维度出发&#xff0c;打造一个独特且吸引人的艺术空间。 我们要注重产品的独特性。每一幅装饰画都应该是独一无二的艺术品&#xff0c;它们不仅仅是墙面的装饰&am…

Linux——IO模型_多路转接(epoll)

目录 0.往期文章 1.epoll的三个接口 1.epoll_create 2.epoll_ctl 结构体 epoll_event 3.epoll_wait 2. epoll的工作原理&#xff0c;和接口对应 1.理解数据到达主机 2.epoll的工作原理 3.基于epoll的TCP服务器&#xff08;代码) 辅助库 基于TCP的Socket封装 服务器代…

集运系统如何多维度展现企业业务情况?

在集运行业&#xff0c;数据是企业决策的重要依据。为了在竞争中保持优势&#xff0c;企业需要一套高效、灵活且可靠的管理工具来应对市场的快速变化。易境通集运系统以其全面而精细的统计报表功能&#xff0c;成为企业决策优化和业务增长的重要助手。 易境通集运系统https://…

OpenLayers3, 箭头线绘制实现

文章目录 一、前言二、代码实现三、总结 一、前言 本文基于OpenLayers3&#xff0c;实现绘制箭头线的功能。 二、代码实现 <!DOCTYPE html> <html> <head><title>绘制箭头线</title><link href"../../libs/ol3/ol.css" rel"…

山东省大数据职称考试(2)

注意&#xff1a;数据本身不具备价值。 线性表的顺序存储结构是指用一段地址连续的存储单元依次存储线性表的数据元素。 面向对象程序设计的特点包括&#xff1a;抽象、封装、继承、多态123。其中&#xff0c;抽象用于描述问题的高度概括、分类和抽象&#xff0c;封装实现了数据…

物料信息库管理杂谈

在国内某大型电子设备厂调研时&#xff0c;听到研发人员说&#xff0c;采购部门总是不能及时地采购所需要物料&#xff0c;导致进度延迟&#xff1b;而采购人员常常抱怨说&#xff0c;研发人员选用的物料很难采购&#xff1b;同时&#xff0c;生产人员也认为生产排期很难进行&a…

FGF23:家族靶向治疗先行者

成纤维细胞生长因子23&#xff08;FGF23&#xff09;属于FGF19亚家族成员&#xff0c;由成骨细胞、骨细胞和骨髓合成&#xff0c;是磷酸盐和钙稳态的重要调节剂&#xff0c;同时与铁稳态、炎症和红细胞生成也有关。 &#xff08;数据来源AlphaFold&#xff09; FGF23由251个氨…

内联函数与动态内存分配

内联函数 • 调用普通函数的问题&#xff1a; 每个普通函数调用语句都需要发生跳转操作&#xff0c;这种跳转操作会带来时间开销。 • 内 联就是用 函数已被编译好的二进制代码 &#xff0c; 替换 对该函数的调用指令 • 内 联在保证函数特性的同时&#xff0c;避免了函数 调用…

什么是Java以及Java的发展历程

Java是什么 搜索百度百科词条 Java是一门面向对象的编程语言&#xff0c;不仅吸收了C语言的各种优点&#xff0c;还摒弃了C里难以理解的多继承、指针等概念&#xff0c;因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表&#xff0c;极好地…

瞩“M”蓉城,驾趣“耍起” 全新BMW M5策马领衔,宝马集团13款新车闪耀成都车展

宝马秉持长期主义&#xff0c;以强大产品和创新体验&#xff0c;满足中国客户需求2024是BMW M大年&#xff0c;车型数量将扩至23款&#xff0c;几乎覆盖BMW所有细分市场全新BMW M5中国首秀&#xff0c;即将于今年年底上市 以“精简有道”融合性能美学与空气动力学&#xff0c;设…

实用好软-----电脑端 Kuvid工具 支持上千网站的视频下载软件

今天分享的这款软件支持很多网站视频下载 。全中文界面。操作比较简单。初步测试了下。下载B站视频操作方便 其他视频界面个别会解析错误。 软件主界面和相关设置界面 注意&#xff1a;设置中的自定义FFMPEG通常不需要开启,需要指定的路径是ffmpeg.exe的路径,不是所下载的安装…

2024高效获客转化指南 | 「人群模型」详解

营销进入“以人为本”的时代&#xff0c;小红书以其独特的UGC社区生态&#xff0c;在营销“人影响人”的传播链路中发挥着关键作用。 本期&#xff0c;千瓜就营销传播中“人”的研究展开探讨&#xff0c;通过解析人群模型、品牌案例&#xff0c;详细解读营销策略方法及应用&…

华为USG6625F设备ipsec隧道无IKE v1版本解决办法

新华为USG6625F防火墙&#xff0c;因需要和对端中心对接ipsec后发现无IKE V1版本&#xff0c;设备默认只有IKE v2版本&#xff0c;和对端对接隧道参数不一致&#xff0c;无法成功对接&#xff0c;因此需要下载相应的IKE v1插件后加载插件来解决该问题&#xff1b; USG6625F 版本…

Python自动化测试requests库深度详解

前言 发送HTTP请求 import requests# 登录的接口地址url http://............/login# 登录的参数params {"mobile_phone": 18300000000,"pwd": 12345678}# 请求头headers {X-Lemonban-Media-Type: lemonban.v2}# 发送登录请求# 请求类型为 Content-Typ…

《机器学习》 基于GANs构建数字图像生成器 探索深度学习世界

文章目录 引言生成对抗网络的基本原理生成对抗网络的数学表达生成对抗网络的应用生成对抗网络的挑战与优化生成对抗网络的实现示例结论&#xff1a;机器学习和ai技术的出现成为了C……SD……N 热榜的爹。 使用机器学习技术对热榜文章进行分析 引言 生成对抗网络&#xff08;Ge…

Training language models to follow instructionswith human feedback

Abstract 将语言模型做得更大并不会自动提高它们遵循用户意图的能力。例如&#xff0c;大型语言模型可能会生成不真实、有毒或对用户不有帮助的输出。换句话说&#xff0c;这些模型并未与用户对齐&#xff08;aligned&#xff09;。本文展示了一种通过人类反馈来对齐语言模型与…

Kubernetes 上安装 Jenkins

安装 Helm curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash添加 Jenkins Helm 仓库 首先添加 Jenkins Helm 仓库 helm repo add jenkins https://charts.jenkins.io helm repo update安装 Jenkins 使用 Helm 安装 Jenkins 的最新版本&…

2024最新gewe开发微信机器人教程说明

简介&#xff1a;本文将指导你如何搭建一个微信机器人&#xff0c;通过接入gewe实现智能回复与聊天功能。我们将从基础设置开始&#xff0c;逐步讲解如何配置机器人&#xff0c;并通过实例展示其实际应用。 随着人工智能技术的不断发展&#xff0c;智能机器人已经成为我们日常…

RS®SMM100A 矢量信号发生器重新定义中档仪器

R&S SMM100A 矢量信号发生器 100 MHz至44 GHz 产品综述 R&SSMM100A 矢量信号发生器在 100 MHz 至 44 GHz 的频率范围内提供一流的射频特性。这款仪器覆盖现有无线标准所使用的 6 GHz 以下的频段、新定义的最高 7.125 GHz 的 5G NR FR1 和 Wi-Fi 6E 频段以及最高 44 …

C++竞赛初阶L1-14-第六单元-数组(31~33课)547: T456477 查找特定的值

题目内容 在一个序列&#xff08;下标从 0 开始&#xff09;中查找一个给定的值&#xff0c;输出第一次出现的位置。 输入格式 第一行包含一个正整数 n&#xff0c;表示序列中元素个数。1≤n≤10000。 第二行包含 n 个整数&#xff0c;依次给出序列的每个元素&#xff0c;相…