1

我目前被分配了一个项目来使用 javascript 创建以下内容,您可以在此处查看最终产品:http: //i1245.photobucket.com/albums/gg583/leetpete1994/Infografic-TrafficSources_zpsf50dfa6d.png

获取提供的 PDF 并创建一种动态显示图像传达的数据的方法基本上是我的工作。数据本身将在其他地方计算,所以我所担心的是接受每个烧杯的值,并适当地填充它们。

我现在的想法:

现在我的想法是使用画布。我创建了一个烧杯类,然后将 5 个烧杯作为该类的实例。这很好用,我坐在一张画布上,在正确的位置有 5 个空烧杯。我将每个烧杯除以 100;然后我可以正确地填充每个像素所需的像素数量,无论它碰巧是什么百分比,但这就是我遇到问题的地方。每个烧杯都是不同的形状,随着每个烧杯被填满,形状会发生变化。因此,我很难真正吸取烧杯中的液体。其次,如果我确实设法正确地吸入液体,它将覆盖烧杯的细节。如果我先做液体然后烧杯,那将是相反的问题。我还尝试使用堆叠的两个画布并控制液体的不透明度,

那么,有没有更好的方法来做到这一点,或者轻松地将奇怪的形状绘制到画布上?我开始认为使用画布不是最好的方法。我知道我可以为每个不同的液位制作几张图像,但我想避免在最终产品中使用那么多图像。

4

3 回答 3

1

我相信您应该对问题使用揭示方法...

每个空烧杯的一张图像,以及每个满液体的一张图像以及烧杯的详细信息。

然后将液体图像放置在底部并向上显示尽可能多的像素。

<div class="beaker">
    <div class="liquid"></div>
</div>

.beaker, .liquid {
    background: url('path-to-sprite-image.png') 0 100% no-repeat;
    width:130px;
}
.beaker {
    height:280px;
    position:relative;
}
.liquid {
    background-position: right 100%;
    bottom:0;
    left:0;
    position:absolute;
}

http://jsfiddle.net/27E5q/的简单演示

于 2013-10-05T21:56:24.880 回答
1

这是一种使用 Canvas 获得所需效果的方法:

  • 用透明的烧杯绘制图像
  • 从下往上逐渐绘制原图
  • 从而用流体填充透明烧杯。

在此处输入图像描述

在此处输入图像描述

你可以比我花更多的时间让烧杯变得透明;)

当然,您可以将绘图分成几列并以您需要的任何速度填充烧杯。

如果您需要不同的颜色来填充烧杯,可以使用 context.globalCompositeOperation="destination-over"。这种合成模式允许您“在”现有图形下“绘制”(新颜色只会填充现有图像上的透明像素)。

这是代码和小提琴:http: //jsfiddle.net/m1erickson/Enyjb/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    #canvas{border:1px solid red; border-radius:15px;}
    canvas{position:absolute;}
</style>

<script>
$(function(){

    window.requestAnimFrame = (function(callback) {
      return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
      function(callback) {
        window.setTimeout(callback, 1000 / 60);
      };
    })();


    // draw a background that fills the beakers with gray
    var background=document.getElementById("background");
    var bkCtx=background.getContext("2d");
    bkCtx.fillStyle="rgb(234,234,234)";
    bkCtx.fillRect(0,0,background.width,background.height);

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var y;

    var img1=new Image();
    img1.onload=function(){
        ctx.drawImage(img1,0,0);
        y=img1.height-50;
        img2=new Image();
        img2.onload=function(){
            animate();
        }
        img2.src="https://dl.dropboxusercontent.com/u/139992952/temp01.png";
    }
    img1.src="https://dl.dropboxusercontent.com/u/139992952/temp02.png";


    var fps = 30;
    function animate() {
        setTimeout(function() {

            if(y<100){return;}

            requestAnimFrame(animate);

            // Drawing code goes here
            y-=1;
            ctx.drawImage(img2,
                          0,y,img2.width,img2.height-y,
                          0,y,img2.width,img2.height-y)


        }, 1000 / fps);
    }


}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="background" width=1024 height=327></canvas>
    <canvas id="canvas" width=1024 height=327></canvas>
</body>
</html>
于 2013-10-06T01:27:55.333 回答
0

我不是数据可视化方面的专家,这可能有点矫枉过正 - 但是 - 您可能需要考虑使用 D3.js:

http://d3js.org/

这是一个用于绘制数据的漂亮库。超级酷,看起来超级简单。

这是一个画廊\示例页面:画廊

*不,我与 D3.js 没有任何关系(-!

祝你好运!

于 2013-10-05T21:55:45.867 回答