1
我正在尝试动画水平条形图绘制。它会慢慢画出来,一旦画完第二张。就像chart.js一样。它不一定要那么先进。我只是想学习画布绘画+动画。我正在使用ctx.fillRect
,我不确定这是否可以动画。画布上的动画矩形
更新:在我的第二个片段我已经加入周围fillRect超时。它激活了酒吧,但现在position.Y似乎并没有在适当的时间更新。酒吧被绘制在彼此的顶部。
/**
* Javascript Carousel
* Author: Yasin Yaqoobi
* Project Goal: Build a really simple slider using javascript timer and css transition.
* Date: 07/09/16
**/
var Charts = (function(){
var ctx;
var canvas;
var legendsHeight = 50;
var yLabelsWidth = 100;
var scaleRatio;
function init(canvas, chart){
\t setupCanvas(canvas);
\t setScaleRatio(chart);
\t if (chart.type.localeCompare('HorizontalBar') != -1){
\t \t drawHorizontalChart(chart);
\t }
}
function drawHorizontalChart(chart){
\t var canvasHeight = $(canvas).outerHeight();
\t var canvaswidth = $(canvas).outerWidth();
\t var marginRatio = (canvasHeight - 2 * legendsHeight)/chart.data.labels.length * 0.2;
\t var barHeight = ((canvasHeight - 2 * legendsHeight)/chart.data.labels.length) - marginRatio;
\t \t
\t ctx.beginPath();
\t ctx.moveTo(yLabelsWidth, legendsHeight); // (30, 15)
\t ctx.lineTo(yLabelsWidth, canvasHeight - legendsHeight); // (30,385)
\t ctx.lineTo(canvaswidth, canvasHeight - legendsHeight); // (1000,385)
\t ctx.stroke();
\t ctx.font = "16px serif";
\t ctx.fillText(chart.data.datasets[0].label, (canvaswidth - yLabelsWidth)/2, legendsHeight/2);
\t var position = {x:yLabelsWidth,y:legendsHeight};
\t for (var i = chart.data.labels.length-1; i >= 0; i--){
\t \t ctx.fillStyle = chart.data.datasets[0].backgroundColor[i];
\t \t ctx.fillRect(position.x,position.y, scaleRatio * chart.data.datasets[0].data[i], barHeight);
\t \t position.y += marginRatio + barHeight;
\t \t console.log('this is i ' + i);
\t }
}
function setScaleRatio(chart){
\t scaleRatio = chart.data.datasets[0].data.reduce(function(prev,curr){
\t \t if (prev > curr){
\t \t \t return prev;
\t \t }
\t \t return curr;
\t });
\t scaleRatio = $(canvas).outerWidth()/(scaleRatio + 10);
}
function setupCanvas(canv){
\t canvas = canv;
\t if (canvas.getContext){
\t \t ctx = canvas.getContext('2d');
\t }
\t console.log(ctx);
}
var publicApi = {
\t init: init
};
return publicApi;
})();
$(document).ready(function(){
\t var canvas = document.getElementById("myChart");
\t Charts.init(canvas, {
\t \t type: 'HorizontalBar',
\t \t data: {
\t \t \t labels: ['USA', 'Russia', 'China'],
\t \t \t datasets: [
\t \t \t \t {
\t \t \t \t \t label: 'Progress Chart',
\t \t \t \t \t backgroundColor: [
\t \t \t \t \t \t 'rgba(255, 99, 132, 0.2)',
\t \t 'rgba(54, 162, 235, 0.2)',
\t \t 'rgba(255, 206, 86, 0.2)'
\t ],
\t borderColor: [
\t \t 'rgba(255,99,132,1)',
\t \t 'rgba(54, 162, 235, 1)',
\t \t 'rgba(255, 206, 86, 1)'
\t ],
\t borderWidth: 1,
\t data: [60, 30, 80]
\t }
\t \t \t ]
\t \t }
\t });
});
.container{
\t width: 1200px;
\t box-shadow: 5px 5px 35px 0px rgba(0,0,0,0.4);
\t -webkit-box-shadow: 5px 5px 35px 0px rgba(0,0,0,0.4);
\t -moz-box-shadow: 5px 5px 35px 0px rgba(0,0,0,0.4);
\t overflow: hidden;
\t margin: 0 auto;
\t padding: 5%;
}
canvas{
\t margin: 0 auto;
\t display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
\t <h1 class="page-title underline-text">Charts</h1>
\t \t <div class="charts-area">
\t \t <h3>Progress Chart</h3>
\t \t <canvas id="myChart" width="1000" height="400"></canvas>
\t </div>
<script src="jquery-3.1.0.js"></script>
<script src="npo.js"></script>
<script src="index.js"></script>
</body>
/**
* Javascript Carousel
* Author: Yasin Yaqoobi
* Project Goal: Build a really simple slider using javascript timer and css transition.
* Date: 07/09/16
**/
var Charts = (function(){
var ctx;
var canvas;
var legendsHeight = 50;
var yLabelsWidth = 100;
var scaleRatio;
function init(canvas, chart){
\t setupCanvas(canvas);
\t setScaleRatio(chart);
\t if (chart.type.localeCompare('HorizontalBar') != -1){
\t \t drawHorizontalChart(chart);
\t }
}
function drawHorizontalChart(chart){
\t var canvasHeight = $(canvas).outerHeight();
\t var canvaswidth = $(canvas).outerWidth();
\t var marginRatio = (canvasHeight - 2 * legendsHeight)/chart.data.labels.length * 0.2;
\t var barHeight = ((canvasHeight - 2 * legendsHeight)/chart.data.labels.length) - marginRatio;
\t \t
\t ctx.beginPath();
\t ctx.moveTo(yLabelsWidth, legendsHeight); // (30, 15)
\t ctx.lineTo(yLabelsWidth, canvasHeight - legendsHeight); // (30,385)
\t ctx.lineTo(canvaswidth, canvasHeight - legendsHeight); // (1000,385)
\t ctx.stroke();
\t ctx.font = "16px serif";
\t ctx.fillText(chart.data.datasets[0].label, (canvaswidth - yLabelsWidth)/2, legendsHeight/2);
\t var position = {x:yLabelsWidth,y:legendsHeight};
\t for (var i = chart.data.labels.length-1; i >= 0; i--){
\t \t ctx.fillStyle = chart.data.datasets[0].backgroundColor[i];
\t \t for (var n = 20; n < scaleRatio * chart.data.datasets[0].data[i]; n+=1){
\t \t (function (ratio){
\t \t \t setTimeout(function(){
\t \t \t \t console.log(ratio);
\t \t \t \t ctx.fillRect(position.x,position.y, ratio, barHeight);
\t \t \t }, 1000);
\t \t })(n);
\t }
\t \t position.y += marginRatio + barHeight;
\t \t console.log('this is positionY ' + position.y);
\t }
}
function setScaleRatio(chart){
\t scaleRatio = chart.data.datasets[0].data.reduce(function(prev,curr){
\t \t if (prev > curr){
\t \t \t return prev;
\t \t }
\t \t return curr;
\t });
\t scaleRatio = $(canvas).outerWidth()/(scaleRatio + 10);
}
function setupCanvas(canv){
\t canvas = canv;
\t if (canvas.getContext){
\t \t ctx = canvas.getContext('2d');
\t }
\t console.log(ctx);
}
var publicApi = {
\t init: init
};
return publicApi;
})();
$(document).ready(function(){
\t var canvas = document.getElementById("myChart");
\t Charts.init(canvas, {
\t \t type: 'HorizontalBar',
\t \t data: {
\t \t \t labels: ['USA', 'Russia', 'China'],
\t \t \t datasets: [
\t \t \t \t {
\t \t \t \t \t label: 'Progress Chart',
\t \t \t \t \t backgroundColor: [
\t \t \t \t \t \t 'rgba(255, 99, 132, 0.2)',
\t \t 'rgba(54, 162, 235, 0.2)',
\t \t 'rgba(255, 206, 86, 0.2)'
\t ],
\t borderColor: [
\t \t 'rgba(255,99,132,1)',
\t \t 'rgba(54, 162, 235, 1)',
\t \t 'rgba(255, 206, 86, 1)'
\t ],
\t borderWidth: 1,
\t data: [60, 30, 80]
\t }
\t \t \t ]
\t \t }
\t });
});
.container{
\t width: 1200px;
\t box-shadow: 5px 5px 35px 0px rgba(0,0,0,0.4);
\t -webkit-box-shadow: 5px 5px 35px 0px rgba(0,0,0,0.4);
\t -moz-box-shadow: 5px 5px 35px 0px rgba(0,0,0,0.4);
\t overflow: hidden;
\t margin: 0 auto;
\t padding: 5%;
}
canvas{
\t margin: 0 auto;
\t display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
\t <h1 class="page-title underline-text">Charts</h1>
\t \t <div class="charts-area">
\t \t <h3>Progress Chart</h3>
\t \t <canvas id="myChart" width="1000" height="400"></canvas>
\t </div>
<script src="jquery-3.1.0.js"></script>
<script src="npo.js"></script>
<script src="index.js"></script>
</body>
这个不错谢谢。你能简化setTimeout吗?我很难理解它。还有一个原因是你绑定了ctx而不是直接使用ctx?不知道在超时设置后,会发生什么?(i> 0?delay +(bars [i-1] .value * speed):0)+ delay + l * speed);' –
我正在使用bind, 'for'循环中'i'和'l'的值被保留;如果你不这样做,他们会在调用函数的时候假定当前的'i'和'l'的值。它与'var'的范围有关(通过'let'语句固定在ES6中,我相信)。 在超时的第二个参数是“时机”本身 - 我将解释在下面评论更好(跑出来的字符) –
定时的工作原理如下:'I> 0'是一个三元声明问我们”?在第二,第三,第四...栏(基本上,如果我们不在第一栏上)。如果我们不在第一个栏上,我们会根据我们的时间延迟+ bars [i-1] .value * speed',这意味着我们在延迟之后绘制上一个栏的总长度TIMES绘制的速度“ - >这有效地将前一个小节添加为下一个小节的总延迟,但这只适用于2个小节,因为如果有两个以上的小节,我们必须复合所有以前的小节。最后一部分是当前正在绘制的酒吧 –