如何用html css js 画出曲线 或者斜线;

效果图

在这里插入图片描述

解题思路

将图片全部定位至中心点,然后x轴就变动translateX ,y轴同理;

这里有两个问题

浏览器: 以左上角为原点0,0 越往下y越大
数学坐标系:以中心点为原点0,0 越往下y越小;
曲线函数:坐标确定了原点确定了,就需要对应的曲线函数来描述这条线段

我们一个个来解决

一、如何把数学坐标系运用到浏览器之中,转化y轴的上下大小反序;

translateX 变化多少就是多少,translateY 变化多少就是反向移动多少,所以重要的是这个反向我们如何来描述,其实这里也很简单,我们使用css变量,然后在变化的时候,setProperty对应的变量值,然后在css里我们做对应的描述;

<style>
 #container {
 	width: 100vw;
    height: 100vh;
    background-color: aqua;
    position: relative;
    overflow: auto;
  }
  .curveImg {
    --size: 30px;
    --dx: 1;
    --dy: 1;
    border-radius: calc(var(--size) / 2);
    width: var(--size);
    height: var(--size);
    position: absolute;
    left: 50%;
    top: 50%;
    margin-left: calc(var(--size) / 2);
    margin-top: calc(var(--size) / 2);
    object-fit: cover; /* 保持图片纵横比 */
    transition: all 0.8s ease-out ;
    transform: translate(calc(var(--dx) * 1px), calc(var(--dy) * -1px));
  }
 </style>
  <body>
    <div id="container"></div>
  </body>

此时我们已经完成了准备工作,接着完成反向排序的准备工作,dy越大则在html中排列就越小,超越原点即为负数;

二、将原点挪至中心点

原点在与你想让它在那个位置,它都可以排列到那个位置,这里我想让它在容器内渲染,所以我想设置在容器内的中心位置,那么这个中心位置,其实就是我给定的最大值与最小值和的一半就是我的中心点;
那么我只要让其对应的横坐标点,减去当前的原点,就是它当前需要移动的距离,也就是dx,y同理;

曲线函数

不管是曲线,还是抛物线,还是斜线,其实都是有一个方程式,或者叫做函数来表示;

那么如果是在数学中;
y=x; 那就表示一段45度的斜线;
y=-x ; 那就表示一段-45度的斜线;
y=sin(x); 那就表示连绵的曲线;
数学坐标系中是无限延伸的,但在我们的浏览器中,他是有一个范围呢;所以我们还需要给他一个范围

如果是在代码中,如果我们得到了曲线的表示函数,接下来就是将其用html、css、js来绘制到我们的电脑屏幕中;

我们先来写一个类来表示这个计算类
class Curve {
/**    
  * 创建一个计算类的实例    *    
  * @constructor    
  * @param {Function} curveFunc 要添加的任务实例 
  * @param {Array} xRange x取值范围
  * @param {Array} yRange y取值范围
  */ 
  constructor(curveFunc, xRange, yRange) {
    this.xRange = xRange
    this.yRange = yRange
    this.curveFunc = curveFunc
  }
  /**
   * 计算曲线函数
   * @param {Number} x x值
   * @returns {Number} y y值
  */
  getY(x) {
    let y = this.curveFunc(x)
    if (y < this.yRange[0]) {
      y = this.yRange[0]
    }
    if (y > this.yRange[1]) {
      y = this.yRange[1]
    }
    return y
  }
}

上面我们已经创建好一个计算类、具体释义有jsdoc注释;

那么我们如何来表示曲线或者直线呢

const line = new Curve(x=>x,[-1,1],[-1,1])
const wave = new Curve(
  x => Math.sin(x),
  [-1 * Math.PI, 3 * Math.PI],
  [-1, 1]
)

这样就表示出来了;
曲线:y = wave.getY(x);
直线:y = line.getY(x);
那么关于坐标关系我们已经用代码描述出来绘制就是最简单的事了;

  <div id="container"></div>

假设我们现在有这么一个div;
然后我们先在div里创建一些图片(当然这里也可以换成你喜欢的样式);

const box = document.querySelector("#container")
const initImg = className => {
  const frag = document.createDocumentFragment()
  for (let i = 0; i < 100; i++) {
    const img = document.createElement("img")
    img.classList.add(className)
    img.src = "./test.jpg" // 设置图片路径
    frag.appendChild(img)
  }
  box.appendChild(frag)
}
initImg("curveImg")

接下来就是渲染

const layout = (curve, doms, width, height) => {
  const [minX, maxX] = curve.xRange
  const [minY, maxY] = curve.yRange
  // 步长 
  const xStep = (maxX - minX) / (doms.length - 1)
  // 与实际坐标轴的比例
  const xScale = width / (maxX - minX)
  const yScale = height / (maxY - minY)
  const cx = (maxX + minX) / 2
  const cy = (maxY + minY) / 2
  for (let i = 0; i < doms.length; i++) {
    const dom = doms[i]
    const x = minX + i * xStep
    const y = curve.getY(x)
    const dx = (x - cx) * xScale
    const dy = (y - cy) * yScale
    dom.style.setProperty("--dx", dx)
    dom.style.setProperty("--dy", dy)
  }
}

接下来只要我们执行layout函数,那么图片就会进行对应的渲染;

上全部代码

<!DOCTYPE html>
<html lang="en">
 <head>
   <meta charset="UTF-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <title>Document</title>
   <style>
     #container {
       width: 100vw;
       height: 100vh;
       background-color: aqua;
       position: relative;
       overflow: auto;
     }
     .curveImg {
       --size: 30px;
       --dx: 1;
       --dy: 1;
       border-radius: calc(var(--size) / 2);
       width: var(--size);
       height: var(--size);
       position: absolute;
       left: 50%;
       top: 50%;
       margin-left: calc(var(--size) / 2);
       margin-top: calc(var(--size) / 2);
       object-fit: cover; /* 保持图片纵横比 */
       transition: all 0.8s ease-out ;
       transform: translate(calc(var(--dx) * 1px), calc(var(--dy) * -1px));
     }
    
   </style>
 </head>
 <body>
   <div>
     <button onclick="renderLine()">直线</button>
     <button onclick="renderWave()">曲线</button>
     <button onclick="renderLineX()">x线</button>
     <button onclick="renderWaveX()">交叉曲线线</button>
   </div>
   <div id="container"></div>
   <script>
     class Curve {
       /**
        * 创建一个计算类的实例    *
        * @constructor
        * @param {Function} curveFunc 要添加的任务实例
        * @param {Array} xRange x取值范围
        * @param {Array} yRange y取值范围
        */
       constructor(curveFunc, xRange, yRange) {
         this.xRange = xRange
         this.yRange = yRange
         this.curveFunc = curveFunc
       }
       /**
        * 计算曲线函数
        * @param {Number} x x值
        * @returns {Number} y y值
        */
       getY(x) {
         let y = this.curveFunc(x)
         if (y < this.yRange[0]) {
           y = this.yRange[0]
         }
         if (y > this.yRange[1]) {
           y = this.yRange[1]
         }
         return y
       }
     }

     const layout = (curve, doms, width, height) => {

       const [minX, maxX] = curve.xRange
       const [minY, maxY] = curve.yRange
       const xStep = (maxX - minX) / (doms.length - 1)
       const xScale = width / (maxX - minX)
       const yScale = height / (maxY - minY)
       const cx = (maxX + minX) / 2
       const cy = (maxY + minY) / 2
       for (let i = 0; i < doms.length; i++) {
         const dom = doms[i]
         const x = minX + i * xStep
         const y = curve.getY(x)
         const dx = (x - cx) * xScale
         const dy = (y - cy) * yScale
         dom.style.setProperty("--dx", dx)
         dom.style.setProperty("--dy", dy)
       }
     }
     const box = document.querySelector("#container")
     const initImg = className => {
       const frag = document.createDocumentFragment()
       for (let i = 0; i < 100; i++) {
         const img = document.createElement("img")
         img.classList.add(className)
         img.src = "./test.jpg" // 设置图片路径
         frag.appendChild(img)
       }
       box.appendChild(frag)
     }
     initImg("curveImg")
     const images = document.querySelectorAll(".curveImg")
     const wave = new Curve(
       x => Math.sin(x),
       [-1 * Math.PI, 3 * Math.PI],
       [-1, 1]
     )
     const wave2 = new Curve(
       x => Math.sin(x),
       [0 * Math.PI, 4 * Math.PI],
       [-1, 1]
     )
     const line = new Curve(x => x, [-1, 1], [-1, 1])
     const line2 = new Curve(x => -x, [-1, 1], [-1, 1])
     const middleIndex = Math.floor(images.length / 2)
     const dom1 = Array.from(images).slice(0,middleIndex);
     const dom2 = Array.from(images).slice(middleIndex);
     function renderLine() {
       layout(line, images, box.clientWidth - 200, box.clientHeight - 200)
     }
     function renderWave() {
       layout(wave, images, box.clientWidth - 200, box.clientHeight - 200)
     }
     function renderLineX() {
       layout(line, dom1, box.clientWidth - 200, box.clientHeight - 200)
       layout(line2, dom2, box.clientWidth - 200, box.clientHeight - 200)
     }
     function renderWaveX() {
       layout(wave, dom1, box.clientWidth - 200, box.clientHeight - 200)
       layout(wave2, dom2, box.clientWidth - 200, box.clientHeight - 200)
     }
     document.addEventListener("DOMContentLoaded", () => {
       renderLine()
     })
   </script>
 </body>
</html>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

pyinstaller 打包pyqt6等ui文件为exe可执行程序的方法

刚开始使用auto-py-to-exe打包pyqt6的程序&#xff0c;折腾好半天都会出错&#xff0c;关键打包出来的exe单文件有快100兆了&#xff0c;真大啊&#xff01; auto-py-to-exe有图形界面&#xff0c;看起来比较直观。 还有中文语言&#xff0c;对使用者比较友善&#xff0c;可以…

【技术追踪】SAM(Segment Anything Model)代码解析与结构绘制之Mask Decoder

论文&#xff1a;Segment Anything   代码&#xff1a;https://github.com/facebookresearch/segment-anything 系列篇&#xff1a;   &#xff08;1&#xff09;【技术追踪】SAM&#xff08;Segment Anything Model&#xff09;代码解析与结构绘制之Image Encoder   &am…

LaTeX 数学公式常见问题及解决方案

本文汇总了博主在使用 LaTeX 写文档过程中遇到的所有数学公式常见问题及对应的 LaTeX 解决方案 持续更新... 目录 1. 连等式2. 公式重新开始编号2.1 图片/表格重新编号 1. 连等式 在数学公式推导过程中常常会遇到如 Figure 1 所示的连等式&#xff0c;一般需要保证等号或者不等…

消息积压了如何处理?

欢迎大家到我的博客阅读这篇文章。消息积压了如何处理&#xff1f; - 胤凯 (oyto.github.io)在系统中使用消息队列的时候&#xff0c;消息积压这个问题也经常遇到&#xff0c;并且这个问题还不太好解决。 消息积压的直接原因通常是&#xff0c;系统中的某个部分出现了性能问题…

经典ctf ping题目详解 青少年CTF-WEB-PingMe02

题目环境&#xff1a; 根据题目名称可知 这是一道CTF-WEB方向常考的知识点&#xff1a;ping地址 随便ping一个地址查看接受的数据包?ip0.0.0.0 有回显数据&#xff0c;尝试列出目录文件 堆叠命令使用’;作为命令之间的连接符&#xff0c;当上一个命令完成后&#xff0c;继续执…

Flink1.17 DataStream API

目录 一.执行环境&#xff08;Execution Environment&#xff09; 1.1 创建执行环境 1.2 执行模式 1.3 触发程序执行 二.源算子&#xff08;Source&#xff09; 2.1 从集合中读取数据 2.2 从文件读取数据 2.3 从 RabbitMQ 中读取数据 2.4 从数据生成器读取数据 2.5 …

【产品应用】一体化伺服电机在系留无人机中的应用

一体化伺服电机是一种将电机、驱动器、编码器结合在一起的伺服系统&#xff0c;具有高精度控制、快速响应和高效运行等优点。系留无人机则是一种通过绳索或链条与地面设施连接的无人机&#xff0c;能够实现长时间的稳定悬停和空中作业。 01.设备简介 电源线牵引装置&#xff1…

MATLAB Simulink和S7-1200PLC MOBUSTCP通信

MATLAB Simulink和SMART PLC OPC通信详细配置请查看下面文章链接: MATLAB和西门子SMART PLC OPC通信-CSDN博客文章浏览阅读749次,点赞26次,收藏2次。西门子S7-200SMART PLC OPC软件的下载和使用,请查看下面文章Smart 200PLC PC Access SMART OPC通信_基于pc access smart的…

人工智能-循环神经网络通过时间反向传播

到目前为止&#xff0c;我们已经反复提到像梯度爆炸或梯度消失&#xff0c; 以及需要对循环神经网络分离梯度。 例如&#xff0c;我们在序列上调用了detach函数。 为了能够快速构建模型并了解其工作原理&#xff0c; 上面所说的这些概念都没有得到充分的解释。 本节将更深入地探…

YOLO目标检测——烟雾检测数据集下载分享【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;烟雾检测数据集可用于监控烟雾情况&#xff0c;实现火灾的早期预警。数据集说明&#xff1a;烟雾检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富&#xff0c;含烟雾1个类别标签说明&#xff1a;使用lableimg标注软件标注&am…

Ant Design for Figma设计系统组件库 支持变量 非社区版

Ant Design for Figma 是基于 Ant Design 设计系统的 Figma 组件库&#xff0c;提供丰富的 UI 组件和交互功能&#xff0c;帮助设计师快速构建高质量的 Figma 设计稿。 Ant Design for Figma 继承了 Ant Design 的设计理念和风格&#xff0c;提供丰富的 UI 组件和交互功能&…

如何在el-tree懒加载并且包含下级的情况下进行数据回显-01

在项目中做需求&#xff0c;遇到一个比较棘手的问题&#xff0c;el-tree懒加载在包含下级的时候&#xff0c;需要做回显&#xff0c;将选中的数据再次勾选上&#xff0c;在处理这个需求的时候有两点是比较困难的&#xff1a; el-tree是懒加载的&#xff0c;包含下级需要一层一…

【10套模拟】【6】

关键字&#xff1a; 有向图入度、无向图度、一次深度优先、快速排序平均性能、折半查找、判断是否是二叉排序树、链式直接入插入排序

腾讯云服务器怎么买便宜?腾讯云服务器新人专享限时特惠购买链接

腾讯云作为国内领先的云计算服务提供商之一&#xff0c;为个人用户和企业用户提供了多种优惠活动。这些活动不仅能帮助用户节省成本&#xff0c;还能提升企业的效益。本文将介绍腾讯云的多重优惠活动&#xff0c;让用户能够以更优惠的价格购买和续费云服务器。 腾讯云双十一领…

HarmonyOS真机调试报错:INSTALL_PARSE_FAILED_USESDK_ERROR处理

1、 新建应用时选择与自己真机匹配的sdk版本 查看自己设备sdk版本 创建时先择匹配版本&#xff1a; 2、 根据报错提示连接打开处理方案 3、查询真机版本对应的compileSdkVersion 和 compatibleSdkVersion 提示3.1版本之后和3.1版本之前的不同命令&#xff08;此处为3.0版…

数学建模 | 灰色预测原理及python实现

目录 一、灰色预测的原理 二、灰色预测的应用及python实现 一、灰色预测的原理 灰色预测是以灰色模型为基础&#xff0c;灰色模型GM(n,h)是微分方程模型&#xff0c;可用于描述对象做长期、连续、动态的反应。其中&#xff0c;n代表微分方程式的阶数&#xff0c;h代表微分方…

课程设计(毕业设计)—基于机器学习(CNN+opencv+python)的车牌识别—(可远程调试)计算机专业课程设计(毕业设计)

基于机器学习(CNNopencvpython)的车牌识别 下载本文机器学习(CNNopencvpython)的车牌识别系统完整的代码和参考报告链接&#xff08;或者可以联系博主koukou(壹壹23七2五六98)&#xff0c;获取源码和报告&#xff09;https://download.csdn.net/download/shooter7/88548767此处…

使用Pandas进行时间重采样,充分挖掘数据价值

大家好&#xff0c;时间序列数据蕴含着很大价值&#xff0c;通过重采样技术可以提升原始数据的表现形式。本文将介绍数据重采样方法和工具&#xff0c;提升数据可视化技巧。 在进行时间数据可视化时&#xff0c;数据重采样是至关重要且非常有用的&#xff0c;它支持控制数据的…

合伙人如何承担合伙公司债务

合伙企业有不同的组织方式&#xff0c;包括普通合伙企业、特殊的普通合伙企业、有限合伙企业这三种&#xff0c;合伙人对于合伙企业的债务承担方式有以下几种情形&#xff1a; 1.普通合伙人合伙企业债务的承担 普通合伙企业由普通合伙人组成&#xff0c;合伙人对合伙企业债务承…