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

css 实现1个像素在不同分辨率屏幕上画网格线

实现网格线绘制,要考虑画布style尺寸和画布像素大小的缩放关系

单像素绘制主要出现的问题是会模糊,从像素角度看就是出现绘制两个像素,实际就是要做偏移

核心就是:按物理像素绘制,首先要对齐物理像素,计算物理像素与css像素之间的关系,然后绘制的时候如果绘制的线宽是奇数就要考虑做偏移,不缩放的情况下是0.5个css像素,缩放就需要计算比例,核心代码如下

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta http-equiv="X-UA-Compatible" content="ie=edge" /><title>Static Template</title></head><body><canvas id="canvas"> </canvas><script>// 设置 Canvas 的物理像素缩放,确保在高分屏下清晰绘制const canvas = document.getElementById("canvas");const context = canvas.getContext("2d");const ratio = window.devicePixelRatio || 1;// 设置画布css大小const width = 300;const height = 200;// 设置 CSS 尺寸, 这里设置的css大小,在绘制的时候,会根据ratio进行缩放,必须保证比例精确,否则绘制出来的线会模糊canvas.style.width = `${width}px`;canvas.style.height = `${height}px`;// 设置高分辨率画布尺寸canvas.width = width * ratio;canvas.height = height * ratio;// 缩放上下文,保持绘图逻辑不变context.setTransform(ratio, 0, 0, ratio, 0, 0);const deviceLineWidth = 1const devicePxWidth = 1 / ratioconst gridLineWidth = 1 / ratioconst offset = 0.5 // 偏移量,用于对齐像素// 现在 context 中坐标单位是 CSS 像素// 对齐设备像素,当浏览器或系统设置非整数分辨率时,单个像素也不是整数,不能简单的取整function alignDevicePixel(px) {return Math.round(px / devicePxWidth) * devicePxWidth;}// 绘制一条真正 1px 的线(在物理像素中)function draw1pxGridLine() {context.lineWidth = deviceLineWidth / ratio;context.strokeStyle = 'black';const halfLineWidth = deviceLineWidth / 2;const _needTranslateOffset = Math.abs(Math.round(halfLineWidth) - halfLineWidth) > 1e-4; // 这里在算是奇数还是偶数const dprOffset = _needTranslateOffset ?  offset / ratio : 0// 对齐像素,+0.5 使线落在像素中心for (let x = 0; x <= width; x += 30) {context.beginPath();x = alignDevicePixel(x)x -= gridLineWidthcontext.moveTo(x + dprOffset, 0);context.lineTo(x + dprOffset, height);context.stroke();}for (let y = 0; y <= height; y += 20) {context.beginPath();y = alignDevicePixel(y)y -= gridLineWidthcontext.moveTo(0, y + dprOffset);context.lineTo(width, y + dprOffset);context.stroke();}}draw1pxGridLine();</script></body>
</html>

http://www.xdnf.cn/news/1061947.html

相关文章:

  • 如何正确处理音频数据:16位整数与32位浮点数
  • 【考研数学:高数11】一元函数积分学的应用(二)——积分等式和积分不等式
  • SSE 流与普通 HTTP 响应的区别
  • FPGA基础 -- Verilog 层次路径名
  • 物体变化下的迈克尔逊干涉:条纹密度、载波解调与双曝光去畸变
  • DAY 54 python打卡
  • 解锁数据宝藏:数据挖掘之数据预处理全解析
  • 【MySQL性能优化】DISTINCT和GROUP BY去重性能深度剖析
  • 基于存储过程的MySQL自动化DDL同步系统设计
  • 技术评测:三丰云免费服务器的真实能力边界
  • Vue 比较两个数组对象,页面展示差异数据值
  • GO 原子操作面试题及参考答案
  • 前端页面Javascript数组
  • 西门子PLC模块上的SF(系统故障)红灯故障分析
  • 前端工程结构设计指南:如何让模块解耦、易维护、可拓展
  • postgresql 函数调试
  • 接口测试需要注意的一些BUG
  • 多相机三维人脸扫描仪:超写实数字人模型制作“加速器”
  • chili3d笔记19 读取dxf
  • 阿里巴巴开源的 分布式事务解决方案Seata
  • iOS应用启动时间优化:通过多工具协作提升iOS App性能表现
  • 1532.在区间范围内统计奇数数目
  • Android 当apk是系统应用时,无法使用webView的解决方案
  • 京运通601908,一只值得长期跟踪操作的波段投资标的,两个指标即可做好
  • Cargo 与 Rust 项目
  • Spring Boot自动配置原理
  • 【智能安全帽新升级】搭载VTX316TTS语音合成芯片,让安全“听得见”!
  • 【国产AI服务器】全国产PCIE5.0交换板,替代博通89104/89144,支持海光、龙芯等平台
  • HTTP 请求方法与状态码
  • “地标界爱马仕”再拓疆域:世酒中菜联袂赤水金钗石斛定义中国GI