You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在p5.js中为map函数生成的各支出区块分配不同透明色?

问题:为美国政府支出区块分配不同透明色并按比例显示的p5.js问题

我想用map函数生成代表美国政府各支出类别的矩形区块,要求每个区块宽度对应支出占总支出的比例,且每个区块用不同的透明颜色。但尝试用setAlpha()时得到的是渐变效果而非整体透明;调整循环中i值单独修改区块时,出现了颜色拆分的矩形。以下是我的p5.js代码:

function setup() {
  createCanvas(800, 400);
  dollar=loadImage('https://media.istockphoto.com/id/1198332549/vector/american-usd-dollar-bill-outline-isolated-on-white-background.jpg?s=1024x1024&w=is&k=20&c=HLVlJ9Ak63IIK2ddS-I-_gr_rHKH8OEFlAGNVNMUhQw=')
  spending = [
    {name: "Social Security",
    billions: 1220},
    {name: "Health Care",
    billions: 914},
    {name: "Income Security",
    billions: 865},
    {name: "National Defense",
    billions: 767},
    {name: "Medicare",
    billions: 755},
    {name: "Education",
    billions: 677},
    {name: "Interest",
    billions: 475},
    {name: "Veteran Benefits",
    billions: 274},
    {name: "Transportation",
    billions: 132},
    {name: "Government",
    billions: 129},
    {name: "Other",
    billions: 65}
  ];
}

function draw() {
  background(255);
  image(dollar,80,-100)
  dollar.resize(600,0)
  for (let i=0;i<spending.length;i++){
    fill(255,0,0,10)
    let sectionwidth = map(spending[i].billions,0,6273,0,2470)
    rect(140,97,sectionwidth,205)
  }
}

问题分析与修正方案

原代码核心问题

  1. 所有矩形都从x=140位置开始绘制,导致区块完全重叠,多个低透明度红色叠加后呈现渐变效果
  2. 未累积起始位置,无法实现按顺序排列的区块
  3. 所有区块使用相同颜色,未满足"不同透明颜色"的需求
  4. dollar.resize()放在draw()中会重复执行,影响性能

修正后的代码

let dollar;
let spending;
let totalSpending;

function setup() {
  createCanvas(800, 400);
  // 预加载图片并调整大小
  dollar = loadImage('https://media.istockphoto.com/id/1198332549/vector/american-usd-dollar-bill-outline-isolated-on-white-background.jpg?s=1024x1024&w=is&k=20&c=HLVlJ9Ak63IIK2ddS-I-_gr_rHKH8OEFlAGNVNMUhQw=', () => {
    dollar.resize(600, 0);
  });
  
  spending = [
    {name: "社会保障", billions: 1220},
    {name: "医疗保健", billions: 914},
    {name: "收入保障", billions: 865},
    {name: "国防", billions: 767},
    {name: "医保", billions: 755},
    {name: "教育", billions: 677},
    {name: "利息", billions: 475},
    {name: "退伍军人福利", billions: 274},
    {name: "交通", billions: 132},
    {name: "政府运作", billions: 129},
    {name: "其他", billions: 65}
  ];
  
  // 计算总支出,避免重复计算
  totalSpending = spending.reduce((sum, item) => sum + item.billions, 0);
}

function draw() {
  background(255);
  // 绘制背景美元图片
  if (dollar) {
    image(dollar, 80, -100);
  }
  
  let currentX = 140; // 区块起始x坐标
  const blockHeight = 205;
  const maxDisplayWidth = 600; // 适配画布宽度,避免超出
  
  for (let i = 0; i < spending.length; i++) {
    // 按比例计算区块宽度
    const sectionWidth = map(spending[i].billions, 0, totalSpending, 0, maxDisplayWidth);
    
    // 为每个区块分配不同色相的透明色(HSL模式更易控制颜色多样性)
    const hue = map(i, 0, spending.length, 0, 360); // 色相从0到360循环
    fill(hue, 80, 60, 150); // 最后一位是透明度(0-255)
    
    // 绘制当前区块
    rect(currentX, 97, sectionWidth, blockHeight);
    
    // 更新下一个区块的起始x坐标
    currentX += sectionWidth;
  }
}

关键修改说明

  • 预计算总支出:在setup()中用reduce计算总支出,避免draw()中重复运算
  • 累积区块位置:用currentX变量记录每个区块的起始位置,绘制后累加宽度,实现区块依次排列
  • 差异化透明色:使用HSL颜色模式,按区块索引分配不同色相,同时设置统一或差异化的透明度
  • 优化图片处理:仅在图片加载完成后调整一次大小,避免draw()循环中重复执行
  • 适配画布宽度:将最大显示宽度设为画布内合理值,避免区块超出可视范围

内容的提问来源于stack exchange,提问作者Tarnya Marshall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 08:22:55