gpt4 book ai didi

javascript - 如何根据增加/减少值制作仪表动画

转载 作者:行者123 更新时间:2023-12-03 08:21:02 25 4
gpt4 key购买 nike

功能:

Canvas Gauge 会根据计算并显示在浏览器页面上的增加/减少值进行动画处理。因此,如果有计数器功能, Canvas 仪表应根据计数器值的递减进行动画处理。

我做了什么:

我已经创建了 2 个仪表的 Canvas 以及倒计时计数器和滚动速度的功能实现。

问题:

我已经正确创建了 2 个仪表的 Canvas 以及功能实现。然而,它们目前是两个独立的实体。 因此,我想寻求想法或帮助,我如何才能将两者集成在一起,以便 Canvas 仪表正确反射(reflect)速度或倒数计数器功能的增加/减少值?一个例子是 Attractive-jQuery-Circular-Countdown-Timer-Plugin-TimeCircles/ 中看到的动画类型。

我已经包含了代码供您细读:

var numOfSpin = 0,
distanceCovered = 0,
counter = 0,
timer = 10;

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
//CountDown Counter
var canvas2 = document.getElementById("Counter");
var ctx2 = canvas2.getContext("2d");
//dimensions
//Speedometer
var W = canvas.width;
var H = canvas.height;
//CountDown Counter
var W2 = canvas2.width;
var H2 = canvas2.height;
//Global Variables
var degrees = 0;
var new_degrees = 0;
var difference = 0;
var color = "#ffa500";
var bgcolor = "#654321";
var animation_loop, redraw_loop;

function drawGauge() {

ctx.clearRect(0, 0, W, H);
//Background 360 degree arc
//Speedometer
ctx.beginPath();
ctx.strokeStyle = bgcolor;
ctx.lineWidth = 30;
//background arc of the speedometer
ctx.arc(W / 2, H / 2, 120, 2.35, 0.8, false);
ctx.stroke();
//CountDown Counter
ctx2.clearRect(0, 0, W, H);
ctx2.beginPath();
ctx2.strokeStyle = bgcolor;
ctx2.lineWidth = 30;
//background arc of the countdown counter
ctx2.arc(W / 2, H / 2, 120, 2.35, 0.8, false);
ctx2.stroke();
//internal gauge will be a simple arc
//Angle in radians = angle in degrees * PI / 180
var radians = degrees * Math.PI / 180;
//Speedometer
ctx.beginPath();
ctx.strokeStyle = color;
ctx.lineWidth = 30;
/* arc(x, y, radius, startAngle, endAngle, anticlockwise)*/
ctx.arc(W / 2, H / 2, 120, 0 + 135 * Math.PI / 180, radians - 84 * Math.PI / 180, false);
ctx.stroke();
//CountDown Counter
ctx2.beginPath();
ctx2.strokeStyle = color;
ctx2.lineWidth = 30;
/*ctx2.arc(W2/2, H2/2, 100, 0 + 135*Math.PI/180, radians - 84*Math.PI/180, false);*/
ctx2.arc(W2 / 2, H2 / 2, 120, 0 + 135 * Math.PI / 180, radians - 84 * Math.PI / 180, false);
ctx2.stroke();
}

function animate() {
..(SHOULD I HAVE A SEPARATE FUNCTION FOR THE ANIMATION OR COULD I PLACE IT DIRECTLY UNDER FUNCTION DRAW() ? ? ? )..
}

function MainGame() {

$("#scrollerDiv").scroll(function() {
var height = $("#scrollerDiv").scrollTop();
for (var i = 0; i < 250; i++) {
if (height > i * 10) {
if (i >= 0 && i < 10) {
$("#roller").attr("src", "Image/rolling_pin/Rolling Pin Spin00" + i + ".png");
}
if (i >= 10 && i < 100) {
$("#roller").attr("src", "Image/rolling_pin/Rolling Pin Spin0" + i + ".png");
}
if (i >= 100 && i < 1000) {
$("#roller").attr("src", "Image/rolling_pin/Rolling Pin Spin" + i + ".png");
$("#scrollerDiv").scrollTop(0);
numOfSpin++;
distanceCovered += 0.59;
console.log(distanceCovered);
console.log(numOfSpin);
}
}
}
})

rollingInterval = setInterval(function() {
counter = counter + 1;
timer = timer - 1;
speed = distanceCovered / counter;
speed2dec = speed.toFixed(2);
$('#speedSpan').html(speed2dec + '<br>ms');
$('#timeSpan').html(timer + 's');

//Set Conditional Checks; user satisfy game condition, advance to next page, else navigate to the "GameOver" Page.
if (counter == 10 && speed > 20) {
console.log("Count");
clearInterval(rollingInterval);
$("#page2").hide();
$("#page3").show();
} else if (counter == 10 && speed < 20) {
clearInterval(rollingInterval);
$("#page2").hide();
$("#GameOver").show();
}
}, 1000)

}
<div id="page2" class="img-wrapper" align="center" style=" position: relative; background-image: url(Image/Page2.png); background-repeat: no-repeat; display: none; width: 100%;height: 100%;">

<div id='content'></div>
<canvas id="canvas" width="300" height="300">
</canvas>
<canvas id="Counter" width="300" height="300">
</canvas>
<p id="speedSpan">0.00
<br>ms</p>
<p id="timeSpan">10 s</p>

<img id="roller" style="position: relative; top:1100px; width: 100%" src="Image/rolling_pin/Rolling Pin Spin000.png" />
<img id="scroll" style="position:absolute; top: 1250px; left: 380px; overflow-y: auto;" src="Image/Scroll.png">

<div id="scrollerDiv">
<p id="invisibleElement"></p>
</div>
</div>

最佳答案

我花了几个小时来尝试一下。为了简单起见,我将其实现为 js 构造函数 Gauge() 而不是 jQuery 插件。

function Gauge(canvasId, options) {
this.settings = {
val: 0,
color: '#FFF',
bgcolor: '#040',
lineWidth: 10,
needleSpan: 5,
legend: '',
font: 'Arial',
fontSize: '12px',
transitionDuration: '0.7s'
}
$.extend(this.settings, options);
var $canvas = $('#' + canvasId);
this.ctx = $canvas[0].getContext('2d');
this.W = $canvas.width();
this.H = $canvas.height();
var offset = $canvas.offset();
var n = this.settings.needleSpan * Math.PI/180; //needle arc in radians
var textOffset = parseInt(this.settings.fontSize) / 3;

//Background 360 degree arc
this.ctx.beginPath();
this.ctx.strokeStyle = this.settings.bgcolor;
this.ctx.lineWidth = this.settings.lineWidth;
//background circle
/* arc(x, y, radius, startAngle, endAngle, anticlockwise)*/
this.ctx.arc(this.W/2, this.H/2, (this.W - this.settings.lineWidth)/2, 0, 2*Math.PI, false);
this.ctx.stroke();

this.ctx.font = this.settings.fontSize + ' ' + this.settings.font;
this.ctx.textAlign = 'center';
this.ctx.fillText(this.settings.legend, this.W/2, this.H/2 + textOffset);

// overlaid canvas for the gauge setting
this.overlay = $("<canvas/>").attr({
'width': this.W,
'height': this.H
}).css({
'position': 'absolute',
'left': offset.left,
'top': offset.top,
'borderRadius': this.W/2 + 'px',
'transition-duration': this.settings.transitionDuration
}).insertAfter($canvas);
this.ctx2 = this.overlay[0].getContext('2d'); // gauge's setting arc
this.ctx2.beginPath();
this.ctx2.strokeStyle = this.settings.color;
this.ctx2.lineWidth = this.settings.lineWidth;
/* arc(x, y, radius, startAngle, endAngle, anticlockwise)*/
this.ctx2.arc(this.W/2, this.H/2, (this.W - this.settings.lineWidth)/2, -Math.PI/2-n/2, -Math.PI/2+n/2, false);
this.ctx2.stroke();

this.set(this.settings.val);
}

Gauge.prototype.set = function (val) { // val is an angle in degrees
this.val = val;
this.overlay.css({
'transform': 'rotate(' + val + 'deg)'
});
};
Gauge.prototype.get = function () {
return this.val;
};

$(function() {
var gauge1 = new Gauge('gauge1', {
val: 270,
color: "#009090",
bgcolor: "#00F5F0",
needleSpan: 10,
lineWidth: 10,
legend: 'Gauge 1',
font: 'Arial',
fontSize: '15px'
});
var gauge2 = new Gauge('gauge2', {
val: 90,
color: "#FFA500",
bgcolor: "#654321",
needleSpan: 10,
lineWidth: 10,
legend: 'Gauge 2',
font: 'Arial',
fontSize: '11px'
});
$("#val1").val(gauge1.get()).on('change', function() {
gauge1.set($(this).val());
});
$("#val2").val(gauge2.get()).on('change', function() {
gauge2.set($(this).val());
});
});

默认设置在对象 this.settings 中定义。通过传递与 this.settings 具有相同属性的 options 对象,可以覆盖任何设置。

jsFiddle

包含 input 元素是为了演示可以通过编程方式设置仪表(以度为单位)。它们不是由 Gauge() 构造函数放置到位。

在 Opera 33.0、Chrome 46.0、IE 11 中测试

<小时/>

注意:就目前情况而言,Gauge() 非常原始。改进可能包括:

  • 背景表盘上的刻度线/图例
  • 零和最大限制(即不使用完整的 360 度)
  • 按实际值设置,而不是度数
  • 圆内/外当前值的文本表示
  • 更多样式选项

在开始之前,我会寻找一个 jQuery 插件。各种功能强大的仪表和刻度盘已经存在。

关于javascript - 如何根据增加/减少值制作仪表动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33748452/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com