如何用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 = xRangethis.yRange = yRangethis.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.xRangeconst [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) / 2const cy = (maxY + minY) / 2for (let i = 0; i < doms.length; i++) {const dom = doms[i]const x = minX + i * xStepconst y = curve.getY(x)const dx = (x - cx) * xScaleconst dy = (y - cy) * yScaledom.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 = xRangethis.yRange = yRangethis.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.xRangeconst [minY, maxY] = curve.yRangeconst xStep = (maxX - minX) / (doms.length - 1)const xScale = width / (maxX - minX)const yScale = height / (maxY - minY)const cx = (maxX + minX) / 2const cy = (maxY + minY) / 2for (let i = 0; i < doms.length; i++) {const dom = doms[i]const x = minX + i * xStepconst y = curve.getY(x)const dx = (x - cx) * xScaleconst dy = (y - cy) * yScaledom.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>

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何实现一个下班倒计时程序

shigen日更文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 Hello伙伴们&#xff0c;好几天不见啦。最近也是晚上打球太累&#xff0c;加上一直在研究mybatis的多租户问题&…

深度模型压缩研究回顾

深度模型压缩研究回顾 作者&#xff1a;安静到无声 个人主页 目录 深度模型压缩研究回顾推荐专栏 在本节中&#xff0c;主要介绍了目前主流的深度神经网络压缩与加速方法&#xff0c;主要包括轻量化网络设计、参数量化、知识蒸馏、模型剪枝和硬件加速等&#xff0c;其中模型剪…

我认为除了HelloWorld之外,Python的三大数据转换实例可以作为开始学习Python的入门语言。

Python的三大数据转换实例 一、反转三位数 class Solution:def funtcion(self,number):hint(number/100)tint(number%100/10)zint(number%10)return 100*z10*th if __name____main__:solution Solution()num123new_num solution.funtcion(num)print("输入:{}".fo…

torch.stack

看网上看多没讲的不是很明白&#xff0c;我来试试空间上的理解 # 假设是时间步T1的输出 T1 torch.tensor([[1, 2, 3],[4, 5, 6],[7, 8, 9]]) # 假设是时间步T2的输出 T2 torch.tensor([[10, 20, 30],[40, 50, 60],[70, 80, 90]])输出&#xff1a; print(torch.stack((T1,T2…

Selenium——利用input标签上传文件

Selenium利用input标签上传文件 完整流程 打开文件上传页面选择要上传的文件点击上传按钮确认文件上传成功介绍怎么方便的获取对应元素的Xpath或者Css 简单介绍 在使用Selenium进行浏览器自动化测试时&#xff0c;文件上传是一个常见的需求。而 标签就是实现文件上传功能的…

【数据分享】2023年我国省市县三级的独角兽企业数量(Excel/Shp格式)

企业是经济活动的参与主体。一个城市的企业数量决定了这个城市的经济发展水平&#xff01;比如一个城市的金融企业较多&#xff0c;那这个城市的金融产业肯定比较发达&#xff1b;一个城市的制造业企业较多&#xff0c;那这个城市的制造业肯定比较发达。 之前我们给大家分享了…

LangChain 2模块化prompt template并用streamlit生成网站 实现给动物取名字

上一节实现了 LangChain 实现给动物取名字&#xff0c; 实际上每次给不同的动物取名字&#xff0c;还得修改源代码&#xff0c;这周就用模块化template来实现。 1. 添加promptTemplate from langchain.llms import OpenAI # 导入Langchain库中的OpenAI模块 from langchain.p…

IO多路转接之select和poll

目录 一. IO多路转接的概念 二. 通过select实现IO多路转接 2.1 select接口 2.2 Select服务器的实现 2.3 select实现IO多路转接的优缺点 三. 通过poll实现IO多路转接 3.1 poll接口 3.2 Poll服务器的实现 3.3 poll实现IO多路转接的优缺点 四. 总结 一. IO多路转接的概念…

制作Go程序的Docker容器

今天突然遇到需要将 Go 程序制作成 Docker 的需求&#xff0c;所以进行了一些研究。方法很简单&#xff0c;但是官方文档和教程有些需要注意的地方&#xff0c;所以写本文进行记录。 源程序 首先介绍一下示例程序&#xff0c;示例程序是一个 HTTP 服务器&#xff0c;会显示si…

【Linux从入门到放弃】环境变量

&#x1f9d1;‍&#x1f4bb;作者&#xff1a; 情话0.0 &#x1f4dd;专栏&#xff1a;《Linux从入门到放弃》 &#x1f466;个人简介&#xff1a;一名双非编程菜鸟&#xff0c;在这里分享自己的编程学习笔记&#xff0c;欢迎大家的指正与点赞&#xff0c;谢谢&#xff01; 文…

ESP32网络开发实例-非接触式水位监测

非接触式水位监测 文章目录 非接触式水位监测1、HC-SR04介绍2、软件准备3、硬件准备4、代码实现在本文中,我们将使用 HC-SR04 超声波传感器和 ESP32 创建一个水位监测网络服务器。 这将是一个非接触式水位测量系统。 首先,我们将介绍HC-SR04 与 ESP32 连接。 使用ESP32对超声…

PaddlePaddle:开源深度学习平台

深度学习作为人工智能领域的重要分支&#xff0c;正在全球范围内得到广泛应用。而在构建和训练深度学习模型时&#xff0c;选择一个高效、易用且功能强大的开源平台是至关重要的。PaddlePaddle&#xff08;即飞桨&#xff09;作为国内领先的深度学习平台&#xff0c;一直以来都…