百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Web端重叠路径可视化

zhezhongyun 2025-01-17 14:31 38 浏览

近几年来,由于信息技术的发展,大数据成为了这个时代的代名词之一,“数据可视化”风靡一时。得益于HTML5提供的新标签“canvas”,Web端也能分“数据可视化”一杯羹。

随着越来越多的可视化方案和需求,需要解决问题也越来越多。当我们在Web端遇到重叠路径可视化渲染问题时,我们应该怎么做呢?

思路

按照数学的思路来说,对于上图所示的重叠路径渲染,我们应当计算出重叠的区域及重叠的次数,然后再分别进行渲染,就能得到上图。

但是,实践发现,在Web端这是一件极其复杂和困难的事情,我们不得不另寻他法。既然来硬的不行,就只能变通变通,另辟蹊径,做其他的尝试。

Canvas元素是一个位图,是基于像素的,在绘制图形时,当图形重叠时,其颜色通道会按照一定的规则进行叠加运算,如下图所示。

这就是我们的切入点,我们只需要根据叠加规则进行颜色再填充就能实现重叠路径的颜色区分渲染。

基于Canvas 2D

在Canvas2D 中,我们只需要设置填充颜色带透明度,绘制后获取ImageData,对ImageData进行修改,再重新渲染即可。

1.创建离屏canvas 设置透明度,进行渲染

const offscreenCanvas = new OffscreenCanvas(width, height); // 离屏canvas
const ctx = offscreenCanvas.getContext('2d');
ctx.fillStyle = 'rgba(0, 255, 0, 0.1)';
// 绘制内容

2.获取ImageData

const imageData = ctx.getImageData(0, 0, width, height); // 获取ImageData

3.通过imageData 计算遍数并改变颜色

const base = 0.1; // 上面第一步设置的填充颜色透明度
const data = imageData.data;
for(let i = 3; i < data.length; i++) {
const a = data[i];
const time = Math.log(1-a) / Math.log(1 - base); // 重叠次数
// 根据重叠次数更改颜色
}
return new ImageData(data, imageData.width, imageData.height);
// 返回imageData

4.再渲染上屏

ctx.putImageData(imageData, 0, 0); // 此处ctx为屏幕上canvas的上下文。

这样我们就可以使用Canvas2D API 在canvas 中绘制出重叠区域区分颜色的带状图。但是我们要注意一点,使用Path渲染时,一次渲染会被视为一个整体图案,透明度是不会叠加的。我们需要分批次渲染多边形,才能实现透明度叠加。

这种方法适合数据量不多且不存在高刷新的情况下,因为绘制数据、获取ImageData 及编辑ImageData需要占用很多的时间。

那还有没有更好的办法呢?Canvas2D 性能不满足的东西,就试着交给WebGL吧。

基于WebGL

WebGL是HTML5提供的基于canvas的像素栅格化的API,与canvas2D相比,它不再将绘制全交给CPU,而是由GPU进行图元绘制,在绘制性能上,有很大的提升。

原生WebGL使用相对比较复杂,在这里我们就使用Pixi.js进行搭建。

1.初始化

const app = new PIXI.Application({
width: 1920, height: 929,
antialias: true,    // default: false 反锯齿
transparent: true, // default: false 透明度
resolution: 1       // default: 1 分辨率
});
const container = new PIXI.Container();

2.设置滤镜,用于改变颜色

const fragment = `
arying vec2 vTextureCoord;
uniform sampler2D uSampler;
void main(void)
{
  vec4 currentColor = texture2D(uSampler, vTextureCoord);
  if(currentColor.a == 0.0) {
    gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
  } else {
    highp float t = 1.0 - currentColor.a;
    highp float l = log(t);
    float temp = l / log(0.99);
    float f = fract(temp);
    int colorIndex = int(temp) - 1;
    if(f >= 0.5) {
       colorIndex += 1;
    }
// 大致的遍数 colorIndex;
// getColor 为你设置颜色的方法;
    gl_FragColor = getColor(colorIndex);
  }}
`
const filter = new PIXI.Filter(null, fragment);
app.stage.filters = [filter];

3.绘制内容

const line = new PIXI.Graphics();
line.lineStyle(60, 0x00FF00, 0.1);
line.moveTo(x, y);
line.lineTo(x1, y1);
.......
line.x = 0;
line.y = 0;
container.addChild(line);

这样就可以用WebGL区分颜色绘制出重叠路径了。

但是这只是个大概值,原因是因为精度的问题,随着重叠的次数的增加,误差会越来越大。

透明度是一个0-1的值,在默认情况下,透明度叠加时,是按照 (1 - (1 - 透明度)的重叠次数次方)的规律叠加。

这个值的差异会越来越小,渲染时又会丢失部分精度,这样就影响到了我们获取正确的重叠次数。

优化计算规则

我们知道了透明度叠加的问题,那有什么更好的办法吗?

我们还是离不开颜色,除了透明度外,还有单个颜色通道的叠加。

gl.enable(gl.BLEND);
gl.blendFunc(gl.ONE, gl.ONE);

当我们将WebGL混合像素算法的源混合因子和源目标合因子都指定为gl.ONE,单个颜色通道的颜色就会进行相加。我们指定颜色为 vec4(0.0, 1.0 / 255, 0, 1), 那么我们在着色器中可以这样写。

highp vec4 currentColor = texture2D(u_sampler, v_texCoord);
if(currentColor.g == 0.0) {
  gl_FragColor = u_backGround;
} else {
  // 颜色叠加 很准 最大限制255
  int colorIndex = int(currentColor.g * 255.0);
  gl_FragColor = getColor(colorIndex - 1);
}

这样绿色颜色通道就会随着叠加次数由0~1, 通过运算就能得到0~255次重叠下渲染的精确,至于更多次数,那就得另寻他法了。

相关推荐

JavaScript中常用数据类型,你知道几个?

本文首发自「慕课网」,想了解更多IT干货内容,程序员圈内热闻,欢迎关注!作者|慕课网精英讲师Lison这篇文章我们了解一下JavaScript中现有的八个数据类型,当然这并不是JavaScr...

踩坑:前端的z-index 之bug一二(zh1es前端)

IE6下浮动元素bug给IE6下的一个div设置元素样式,无论z-index设置多高都不起作用。这种情况发生的条件有三个:1.父标签position属性为relative;2.问题标签无posi...

两栏布局、左边定宽200px、右边自适应如何实现?

一、两栏布局(左定宽,右自动)1.float+margin即固定宽度元素设置float属性为left,自适应元素设置margin属性,margin-left应>=定宽元素宽度。举例:HTM...

前端代码需要这样优化才是一个标准的网站

  网站由前端和后端组成,前端呈现给用户。本文将告诉您前端页面代码的优化,当然仍然是基于seo优化的。  就前端而言,如果做伪静态处理,基本上是普通的html代码,正常情况下,这些页面内容是通过页面模...

网页设计如何自学(初学网页设计)

1在Dreamweaver中搭建不同的页面,需要掌握HTML的语句了,通过调整各项数值就可以制作出排版漂亮的页面,跟着就可以学习一些可视化设计软件。下面介绍网页设计如何自学,希望可以帮助到各位。Dre...

1、数值类型(数值类型有)

1.1数据类型概览MySQL的数据类型可划分为三大类别:数值类型:旨在存储数字(涵盖整型、浮点型、DECIMAL等)。字符串类型:主要用于存储文本(诸如CHAR、VARCHAR之类)。日期/...

网页设计的布局属性(网页设计的布局属性是什么)

布局属性是网站设计中必不可少的一个重要的环节,主要用来设置网页的元素的布局,主要有以下属性。1、float:该属性设置元素的浮动方式,可以取none,left和right等3个值,分别表示不浮动,浮在...

Grid网格布局一种更灵活、更强大的二维布局模型!

当涉及到网页布局时,display:flex;和display:grid;是两个常用的CSS属性,它们都允许创建不同类型的布局,但有着不同的用法和适用场景。使用flex布局的痛点当我们使...

React 项目实践——创建一个聊天机器人

作者:FredrikStrandOseberg转发链接:https://www.freecodecamp.org/news/how-to-build-a-chatbot-with-react/前言...

有趣的 CSS 数学函数(css公式)

前言之前一直在玩three.js,接触了很多数学函数,用它们创造过很多特效。于是我思考:能否在CSS中也用上这些数学函数,但发现CSS目前还没有,据说以后的新规范会纳入,估计也要等很久。然...

web开发之-前端css(5)(css前端设计)

显示控制一个元素的显示方式,我们可以使用display:block;display:inline-block;display:none;其中布局相关的还有两个很重要的属性:display:flex;和...

2024最新升级–前端内功修炼 5大主流布局系统进阶(分享)

获课:keyouit.xyz/14642/1.前端布局的重要性及发展历程前端布局是网页设计和开发的核心技能之一,它决定了页面元素如何组织和呈现。从早期的静态布局到现代的响应式布局,前端布局技术经历了...

教你轻松制作自动换行的CSS布局,轻松应对不同设备!

在网页设计中,自动换行的CSS布局是非常常见的需求,特别是在响应式设计中。它可以让网页内容自动适应不同屏幕尺寸,保证用户在不同设备上都能够获得良好的浏览体验。本文将介绍几种制作自动换行的CSS布局的方...

晨光微语!一道 CSS 面试题,伴你静享知识治愈时光

当第一缕阳光温柔地爬上窗台,窗外的鸟鸣声清脆悦耳,空气中弥漫着清新的气息。在这宁静美好的清晨与上午时光,泡一杯热气腾腾的咖啡,找一个舒适的角落坐下。前端的小伙伴们,先把工作的疲惫和面试的焦虑放在一边,...

2023 年的响应式设计指南(什么是响应式设计优缺点)

大家好,我是Echa。如今,当大家考虑构建流畅的布局时,没有再写固定宽度和高度数值了。相反,小编今天构建的布局需要适用于几乎任何尺寸的设备。是不是不可思议,小编仍然看到网站遵循自适应设计模式,其中它有...