如何用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>相关文章:
如何用html css js 画出曲线 或者斜线;
效果图 解题思路 将图片全部定位至中心点,然后x轴就变动translateX ,y轴同理; 这里有两个问题 浏览器: 以左上角为原点0,0 越往下y越大 数学坐标系:以中心点为原点0,0 越往下y越小࿱…...
【错误记录】Uncaught TypeError: m.nodeName.toLowerCase is not a function
描述:在控制台输出上述错误~ 原因:在页面中,使用jQuery 开发时,命名不能和jQuery一起方法属性冲突,比如这里的nodeName,这里换一个不冲突的名字,就解决问题了。...
王颖奇:ONES.ai 上线,以及我的一些思考
ONES.ai 正式上线!为你解锁更智能、更高效的新一代研发管理体验 我们上线了 ONES.ai,当然我们用了公开的 LLM(AI),目前我们最方便使用的就是公开的 LLM,其实是不是 公开的 LLM 也不重要,在未来可预见的时间内ÿ…...
将AI技术与VR元宇宙相结合的整体解决方案
当前人工智能与VR虚拟现实两大热门技术的融合,正引领着人类走向更智能、更数字化、更便捷、更快速的时代。将这两者结合,AI智能检索应用到VR教学中,将为教育带来前所未有的好处。 个性化教学体验 通过AI智能检索,VR教学可以针对每…...
IPKISS Tutorials 3------绘制矩形版图
IPKISS Tutorials 3------绘制矩形版图 方法1------使用Rectangle函数模块导入与放置层设定创建PCell可视化版图这里给大家介绍一下如何在 IPKISS 绘制一个矩形结构的版图。 方法1------使用Rectangle函数 import si_fab.all as pdk import ipkiss3.all as i3class Box(i3.PC…...
为什么需要用高压放大器
高压放大器是一种重要的电子设备,它的主要功能是将高电压信号放大到所需的输出水平。在各种不同的应用中,为什么我们需要使用高压放大器呢?本文将详细探讨以下几个方面的原因。 高压放大器在科学研究中起着关键的作用。在物理学、化学、生物学…...
前端uniapp生成海报绘制canvas画布并且保存到相册【实战/带源码/最新】
目录 插件市场效果如下图注意使用my-share.vue插件文件如下图片hch-posterutilsindex.js draw-demo.vuehch-poster.vue 最后 插件市场 插件市场 效果如下图 注意 主要:使用my-share.vue和绘制canvas的hch-poster.vue这两个使用 使用my-share.vue <template&…...
【算法专题】双指针
双指针 双指针1. 移动零2. 复写零3. 快乐数4. 盛水最多的容器5. 有效三角形的个数6. 和为s的两个数字7. 三数之和8. 四数之和 双指针 常见的双指针有两种形式,⼀种是对撞指针,⼀种是左右指针。 对撞指针:⼀般用于顺序结构中,也称…...
redis运维(七)基础通用命令
一 基础通用命令 备注: 与具体数据类型无关Tab键 自动补全补充: redis 命令是不区分大小写 通用不到 10 个提升逼格的 redis 命令 后续: slowlog、rename-command、monitor、set ① help command 需求: 显示有关redis命令的…...
搜索引擎ElasticSearch分布式搜索和分析引擎学习,SpringBoot整合ES个人心得
ElasticSearch Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。Elas…...
云原生微服务架构图
云原生微服务架构的具体架构图会根据应用程序的需求、规模和业务场景而有所不同。以下是一个通用的云原生微服务架构图,具体每层的组件可能有所不同: 用户界面层: Web应用或移动应用: 提供用户访问和交互的前端应用。API Gateway&…...
泊车功能专题介绍 ———— AVP系统技术要求之人机交互云平台
文章目录 人机交互车端人机交互车外人机交互灯光交互声音交互 车内人机交互信号装置标示的交互声音交互 场景左右转弯经过让行提示泊入泊出 激活及退出条件激活条件退出条件 场端人机交互V2X交互故障车提醒路口盲区预警弱势交通参与者提醒 场端设施的预警车辆入场车辆故障 APP人…...
精密云工程:智能激活业务速率 ——华为云11.11联合大促倒计时 仅剩3日
现新客3.96元起,下单有机会抽HUAWEI P60 Art,福利仅限双十一,机会唾手可得,立即行动! 双十一购物节来临倒计时,华为云备上多款增值产品,以最优品质迸发冬日技术热浪,满足行业技术应用…...
SpringBoot整合EasyExcel
目录 一、EasyExcel介绍 1、简介 2、常用注解 二、SpringBoot整合EasyExcel 1、基本环境 (1)引入依赖 (2)创建实体类 2、EasyExcel内容读取 (1)创建监听器 (2)测试 3、EasyExcel内容校验 (1)场景描述 (2)EasyExcel监听器 (3)测试 4、EasyExcel内容批量插…...
详解JS遍历数组的十八种方法
for循环 let arr[1,2,3] for(let i0;i<arr.length;i){console.log(arr[i]) }for循环可以遍历数组,它一共有三个参数,第一个参数可以当成数组索引值,想要遍历时候可以设置初始值为0,然后以数组长度为判断依据,如果不…...
Python程序设计基础2
第1关:HUT开学了: # 请在此添加代码 Name = input() # 输入学生的姓名 ########## Begin ########## print("|++++++++++++++++++++++|") print("| |") print("| Welcome to HUT |") print("| …...
域名服务器有哪些类型
域名服务器有哪些类型 随着现在网络的不断发展,越来越多的企业开始使用网络建站,以此来进行营销和推广,而网站在建设过程中需要使用域名和空间,那么域名服务器是什么?下面由给大家说一下。 主域名服务器 负责维护一…...
5.什么是Spring的依赖注入(DI)?IOC和DI的区别是什么
很多人把IOC和DI说成一个东西,笼统来说的话是没有问题的,但是本质上还是有所区别的,希望大家能够严谨一点, IOC和DI是从不同的角度描述的同一件事,IOC是从容器的角度描述,而DI是从应用程序的角度来描述,也…...
Python开源自动化工具Playwright安装及介绍
一个非常强大的自动化项目叫 playwright-python 它支持主流的浏览器,包含:Chrome、Firefox、Safari、Microsoft Edge 等,同时支持以无头模式、有头模式运行,并提供了同步、异步的 API,可以结合 Pytest 测试框架 使用&…...
Nginx生产环境安装配置
不建议使用nginx-1.18.0.tar.gz,因为扫出很多漏洞 上传nginx-1.24.0.tar.gz [rootzonghe01 data]# ll -rw-r--r-- 1 root root 1112471 Oct 26 15:57 nginx-1.24.0.tar.gz [rootzonghe01 data]# pwd /data解押 [rootzonghe01 data]# tar -zxvf nginx-1.24.0.tar…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]
报错信息:libc.so.6: cannot open shared object file: No such file or directory: #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...
Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解
文章目录 一、开启慢查询日志,定位耗时SQL1.1 查看慢查询日志是否开启1.2 临时开启慢查询日志1.3 永久开启慢查询日志1.4 分析慢查询日志 二、使用EXPLAIN分析SQL执行计划2.1 EXPLAIN的基本使用2.2 EXPLAIN分析案例2.3 根据EXPLAIN结果优化SQL 三、使用SHOW PROFILE…...
WebRTC调研
WebRTC是什么,为什么,如何使用 WebRTC有什么优势 WebRTC Architecture Amazon KVS WebRTC 其它厂商WebRTC 海康门禁WebRTC 海康门禁其他界面整理 威视通WebRTC 局域网 Google浏览器 Microsoft Edge 公网 RTSP RTMP NVR ONVIF SIP SRT WebRTC协…...
python基础语法Ⅰ
python基础语法Ⅰ 常量和表达式变量是什么变量的语法1.定义变量使用变量 变量的类型1.整数2.浮点数(小数)3.字符串4.布尔5.其他 动态类型特征注释注释是什么注释的语法1.行注释2.文档字符串 注释的规范 常量和表达式 我们可以把python当作一个计算器,来进行一些算术…...
