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個小節,因爲如果有兩個以上的小節,我們必須複合所有以前的小節。最後一部分是當前正在繪製的酒吧 –