Можно ли элементу в canvas добавить transition во время анимации?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Speedometer</title>
<link rel="stylesheet" href="../css/common.css">
<style>
*{
background: #fff;
font-family: 'SF Pro Display',sans-serif!important;
margin: 0;
padding: 0;
}
.container{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
position: relative;
}
.data_about_load{
position: relative;
top: -60px;
opacity: 0;
}
.data_about_load:before{
content: "";
display: inline-block;
width: 20px;
height: 20px;
background: url(../img/svg/add/check_green.svg) center no-repeat;
background-size: contain;
position: relative;
top: 4px;
margin-right: 12px;
}
#canvas{
opacity: 0;
}
.data{
font-size: 16px;
font-weight: 600;
color: #0a0a0a;
}
.bold_time{
font-weight: 700;
}
/*animations*/
.fade-in-left {
animation: fade-in-left 0.6s cubic-bezier(0.390, 0.575, 0.565, 1.000) both;
}
.slide-in-fwd-center {
animation: slide-in-fwd-center 0.6s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
}
@keyframes fade-in-left {
0% {
transform: translateX(-50px);
opacity: 0;
}
100% {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slide-in-fwd-center {
0% {
transform: translateZ(-1400px);
opacity: 0;
}
100% {
transform: translateZ(0);
opacity: 1;
}
}
</style>
</head>
<body>
<div class="container">
<canvas id="canvas" width="500" height="500"></canvas>
<div class="data_about_load"><span class="data">Время загрузки <span class="bold_time">0.1 сек</span></span></div>
</div>
<script>
const canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
counterClockwise = false,
proportions={
general: {
// general settings
middleX : canvas.width / 2,
middleY : canvas.height / 2,
radius : 240,
},
ticks: {
//ticks settings
tickOffsetFromArc : canvas.width / 40,
},
digits: {
digitsOffsetFromArc : canvas.width / 15,
},
indicator: {
quarterY: (canvas.height / 2)/1.7
}
},
colorPalette= {
// ticks palette
ticks: {
red: {
redTickColor: "#FF0000"
},
yellow: {
darkYellowTickColor: "#F9AF00"
},
green: {
greenTickColor: "#13B74B",
whiteFillColor: "#FFF",
greenShadowColor: "#a8bbaa"
}
},
//arrow color
arrow: {
bgBlue: "#3970eb",
shadowColor: "rgba(66,115,247,0.5)"
},
//text color
text: "#0a0a0a",
diagram:{
bg :{
gradient:[
"#e0f6e8",
"#deede4"
],
lines: "#ecedec"
}
}
},
fonts={
digitsFont: "bold 20px SF Pro Display",
indicator: "600 80px SF Pro Display",
diagramFont: "bold 10px SF Pro Display"
},
// numbers setting
digits = [0, 20, 40, 50, 60, 70, 80, 90, 100],
//zones
zonesCount = digits.length - 1;
// Arrow settings
let arrowValueIndex = -2.45,
// beginning and ending of our arc. Sets by radius*pi
startAngleIndex = .75,
endAngleIndex = 2.25,
step = (endAngleIndex - startAngleIndex) / zonesCount,
allDataDiagram=[],
forVisibleElem=true;
/*draw zones*/
let DrawZones = function () {
const greyZonesCount = zonesCount / 1.6;
greenZonesCount = zonesCount - greyZonesCount,
startAngle = (startAngleIndex - 0.02) * Math.PI,
endGreyAngle = (startAngleIndex + greyZonesCount * step) * Math.PI,
endGreenAngle = (endAngleIndex + 0.02) * Math.PI,
//zones' options
sectionOptions = [
{
startAngle: startAngle,
endAngle: endGreyAngle,
color: "#e7e7e7",
zoneLineWidth: 2
},
{
startAngle: endGreyAngle,
endAngle: endGreenAngle,
color: "#13b74b",
zoneLineWidth: 5
},
];
//draw zones
this.DrawZone = function (options) {
ctx.beginPath();
ctx.arc(proportions.general.middleX, proportions.general.middleY, proportions.general.radius, options.startAngle, options.endAngle, counterClockwise);
ctx.lineWidth = options.zoneLineWidth;
ctx.strokeStyle = options.color;
ctx.lineCap = "round";
ctx.stroke();
};
sectionOptions.forEach(options => this.DrawZone(options));
};
/*draw dots*/
let DrawTicks = function () {
startAngleIndex = .73,
endAngleIndex = 2.27,
step = (endAngleIndex - startAngleIndex) / zonesCount;
this.DrawTick = function (angle,count) {
let fromX = proportions.general.middleX + (proportions.general.radius - proportions.ticks.tickOffsetFromArc) * Math.cos(angle),
fromY = proportions.general.middleY + (proportions.general.radius - proportions.ticks.tickOffsetFromArc) * Math.sin(angle),
toX = proportions.general.middleX + (proportions.general.radius + proportions.ticks.tickOffsetFromArc) * Math.cos(angle),
toY = proportions.general.middleY + (proportions.general.radius + proportions.ticks.tickOffsetFromArc) * Math.sin(angle),
centerOfDotX=(fromX+toX)/2,
centerOfDotY=(fromY+toY)/2;
ctx.beginPath();
ctx.arc(centerOfDotX,centerOfDotY,6,0,Math.PI*2,true);
if (count<6){
switch (count) {
case 1:
case 2:
case 3:
ctx.fillStyle=colorPalette.ticks.red.redTickColor;
break;
default:
ctx.fillStyle=colorPalette.ticks.yellow.darkYellowTickColor;
break;
}
}else{
ctx.fillStyle=colorPalette.ticks.green.whiteFillColor;
ctx.strokeStyle=colorPalette.ticks.green.greenTickColor;
ctx.shadowColor = colorPalette.ticks.green.greenShadowColor;
ctx.shadowBlur = 15;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.stroke();
}
ctx.fill();
ctx.closePath();
ctx.shadowBlur =0;
};
let count=0;
for (let i = startAngleIndex; i <= endAngleIndex; i += step) {
let angle = i * Math.PI;
count++;
this.DrawTick(angle,count);
}
};
//draw numbers
let DrawDigits = function () {
let angleIndex = startAngleIndex;
digits.forEach(function (digit) {
let angle = angleIndex * Math.PI,
x = proportions.general.middleX + (proportions.general.radius - proportions.digits.digitsOffsetFromArc) * Math.cos(angle),
y = proportions.general.middleY + (proportions.general.radius - proportions.digits.digitsOffsetFromArc) * Math.sin(angle);
angleIndex += step;
ctx.font = fonts.digitsFont;
ctx.fillStyle = colorPalette.text;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(digit, x, y);
});
};
/*draw arrow*/
let DrawArrow = function () {
ctx.beginPath();
ctx.lineCap = "round";
ctx.moveTo(proportions.general.middleX-15, proportions.general.middleY);
ctx.lineTo(proportions.general.middleX, proportions.general.middleY-150);
ctx.lineTo(proportions.general.middleX+15, proportions.general.middleY);
ctx.closePath();
ctx.strokeStyle = colorPalette.arrow.bgBlue;
ctx.fillStyle=colorPalette.arrow.bgBlue;
ctx.shadowColor=colorPalette.arrow.shadowColor;
ctx.shadowBlur = 15;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.stroke();
ctx.fill();
ctx.shadowBlur =0;
};
let oldText=0;
/*draw indicator's number*/
let DrawIndicator=function (val) {
ctx.font = fonts.indicator;
ctx.fillStyle = colorPalette.ticks.green.whiteFillColor; // or whatever color the background is.
ctx.fillText(oldText, proportions.general.middleX, proportions.indicator.quarterY);
ctx.fillStyle = colorPalette.text;
ctx.fillText(`${val}`, proportions.general.middleX, proportions.indicator.quarterY);
ctx.font = fonts.digitsFont;
ctx.fillText('points',proportions.general.middleX,proportions.indicator.quarterY+proportions.general.middleY/5);
oldText=val;
};
let indicatorNum=0;
/*renderer*/
function renderer() {
ctx.clearRect(0,0,canvas.width,canvas.height);
DrawZones();
DrawTicks();
DrawDigits();
Diagram();
DrawIndicator(indicatorNum);
ctx.translate(proportions.general.middleX,proportions.general.middleY);
ctx.rotate(arrowValueIndex);
ctx.translate(-proportions.general.middleX,-proportions.general.middleY);
DrawArrow();
ctx.translate(proportions.general.middleX,proportions.general.middleY);
ctx.rotate(-arrowValueIndex);
ctx.translate(-proportions.general.middleX,-proportions.general.middleY);
}
function val(value) {
let sector = Math.PI*0.385;
if (value < 40)
arrowValueIndex = value/40*sector - sector*2;
else
arrowValueIndex = (value-40)/60*sector*3 - sector;
let add=(val)=>{
indicatorNum=val;
allDataDiagram.unshift(val);
allDataDiagram=allDataDiagram.slice(0,186);
};
add(value);
// document.querySelector('span').textContent = value;
renderer();
}
//кроссбраузерный requestAnimationFrame
let requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback){
window.setTimeout(callback, 1000 / 60);
};
})();
let mainNum=0;
let max=0.5, min=-0.6;
let Engine=()=>{
if (forVisibleElem) canvas.classList.add('slide-in-fwd-center');
if (mainNum<70) mainNum+=.5;
if (mainNum>=70 && mainNum<97)mainNum+=.4;
if (mainNum>=97){
if(forVisibleElem) mainNum+=.3;
else mainNum+=.03;
}
if (mainNum>=100){
mainNum=98.7;
if (forVisibleElem) {
document.querySelector(".data_about_load").classList.add("fade-in-left");
forVisibleElem=false;
}
}
val(Math.floor(mainNum));
requestAnimFrame(Engine);
};
let Diagram=()=>{
this.drawLines=(x,y,width,height)=>{
ctx.lineWidth=1.5;
ctx.strokeStyle=colorPalette.diagram.bg.lines;
ctx.moveTo(x,y);
ctx.lineTo(width,height);
ctx.stroke();
};
this.drawCircles = (x,y,r)=>{
ctx.beginPath();
ctx.arc(x,y,r,2*Math.PI,false);
ctx.fillStyle=colorPalette.ticks.green.greenTickColor;
ctx.fill();
ctx.closePath();
};
this.writeNums = (value,x,y)=>{
ctx.font = fonts.diagramFont;
ctx.fillStyle = colorPalette.text;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(value, x, y);
};
this.drawD=()=>{
// console.log(allDataDiagram);
for (var i=0; i<=widthD; i++){
//draw bg gradient
ctx.fillRect(proportions.general.middleX/1.6+i, proportions.general.middleY*1.53+heightD, 1, -(allDataDiagram[i]*0.25-2));
ctx.fillStyle=colorPalette.ticks.green.whiteFillColor;
ctx.fillRect(proportions.general.middleX/1.6+i,proportions.general.middleY*1.53,1,4+28-allDataDiagram[i]*0.25);
ctx.fillStyle=colorPalette.ticks.green.greenTickColor;
ctx.fillRect(proportions.general.middleX/1.6+i,proportions.general.middleY*1.53+4+28-allDataDiagram[i]*0.25,1,2);
ctx.fillStyle=gradientD;
}
};
const widthD=186,
heightD=32,
gradientD=ctx.createLinearGradient(0,0,widthD/2,0);
gradientD.addColorStop(0,colorPalette.diagram.bg.gradient[0]);
gradientD.addColorStop(1,colorPalette.diagram.bg.gradient[0]);
//draw grey lines
this.drawLines(proportions.general.middleX/1.6,proportions.general.middleY*1.53,proportions.general.middleX/1.6,proportions.general.middleY*1.53+heightD);
this.drawLines(proportions.general.middleX/1.6+widthD,proportions.general.middleY*1.53,proportions.general.middleX/1.6+widthD,proportions.general.middleY*1.53+heightD);
//write numbers
this.writeNums(94,proportions.general.middleX/1.6, proportions.general.middleY*1.48);
this.writeNums(97,proportions.general.middleX/1.6+widthD, proportions.general.middleY*1.48);
//draw diagram
this.drawD();
//draw circles
this.drawCircles(proportions.general.middleX/1.6,(proportions.general.middleY*1.53)+(32-94*0.25),3);
this.drawCircles(proportions.general.middleX/1.6+widthD,(proportions.general.middleY*1.53)+(32-97*0.25),3);
};
window.onload=Engine;
</script>
</body>
</html>
CSS transition
никак не применить к элементам на канве.
Для получения плавной анимации в общем случае необходимо получать значения в зависимости от времени а не прибавлять каждый кадр фиксированные значения:
Я изменил в Вашем примере одну функцию:
let delay = 2; // задержка перед анимацией
let duration = 3; // кол во секунд анимации роста значения
let time = new Date().getTime(); // Время начала анимации
let Engine = () => {
// кол-во секунд с начала анимации
let t = (new Date().getTime() - time) / 1000;
val(+getValueFromTime(t).toFixed(1));
requestAnimFrame(Engine);
};
// получить значение спидометра в зависимости от текущего времени
function getValueFromTime(t) {
if (t < delay) // если еще не прошло время задержки
return 0 // вернем 0
t -= delay; // иначе вычитаем время задержки
if (t < 0.95*duration) { // если прошло меньше 95 % времени анимации
// переводим значение времени в значение при помощи функции сглаживания
// EasingFunctions.easeOutCubic (значение на входе должно быть от 0 до 1)
return 98 * EasingFunctions.easeOutCubic(t/duration);
}
// иначе это функция от синуса от этого значения
return 98 + Math.sin(t * 55);
}
Функции сглаживания взяты отсюда, больше функций сглаживания тут
<div class="container">
<canvas id="canvas" width="500" height="500"></canvas>
<div class="data_about_load"><span class="data">Время загрузки <span class="bold_time">0.1 сек</span></span></div>
</div>
<script>
let EasingFunctions = {
// no easing, no acceleration
linear: function (t) { return t },
// accelerating from zero velocity
easeInQuad: function (t) { return t*t },
// decelerating to zero velocity
easeOutQuad: function (t) { return t*(2-t) },
// acceleration until halfway, then deceleration
easeInOutQuad: function (t) { return t<.5 ? 2*t*t : -1+(4-2*t)*t },
// accelerating from zero velocity
easeInCubic: function (t) { return t*t*t },
// decelerating to zero velocity
easeOutCubic: function (t) { return (--t)*t*t+1 },
// acceleration until halfway, then deceleration
easeInOutCubic: function (t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1 },
// accelerating from zero velocity
easeInQuart: function (t) { return t*t*t*t },
// decelerating to zero velocity
easeOutQuart: function (t) { return 1-(--t)*t*t*t },
// acceleration until halfway, then deceleration
easeInOutQuart: function (t) { return t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t },
// accelerating from zero velocity
easeInQuint: function (t) { return t*t*t*t*t },
// decelerating to zero velocity
easeOutQuint: function (t) { return 1+(--t)*t*t*t*t },
// acceleration until halfway, then deceleration
easeInOutQuint: function (t) { return t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t }
};
</script>
<script>
const canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
counterClockwise = false,
proportions={
general: {
// general settings
middleX : canvas.width / 2,
middleY : canvas.height / 2,
radius : 240,
},
ticks: {
//ticks settings
tickOffsetFromArc : canvas.width / 40,
},
digits: {
digitsOffsetFromArc : canvas.width / 15,
},
indicator: {
quarterY: (canvas.height / 2)/1.7
}
},
colorPalette= {
// ticks palette
ticks: {
red: {
redTickColor: "#FF0000"
},
yellow: {
darkYellowTickColor: "#F9AF00"
},
green: {
greenTickColor: "#13B74B",
whiteFillColor: "#FFF",
greenShadowColor: "#a8bbaa"
}
},
//arrow color
arrow: {
bgBlue: "#3970eb",
shadowColor: "rgba(66,115,247,0.5)"
},
//text color
text: "#0a0a0a",
diagram:{
bg :{
gradient:[
"#e0f6e8",
"#deede4"
],
lines: "#ecedec"
}
}
},
fonts={
digitsFont: "bold 20px SF Pro Display",
indicator: "600 80px SF Pro Display",
diagramFont: "bold 10px SF Pro Display"
},
// numbers setting
digits = [0, 20, 40, 50, 60, 70, 80, 90, 100],
//zones
zonesCount = digits.length - 1;
// Arrow settings
let arrowValueIndex = -2.45,
// beginning and ending of our arc. Sets by radius*pi
startAngleIndex = .75,
endAngleIndex = 2.25,
step = (endAngleIndex - startAngleIndex) / zonesCount,
allDataDiagram=[],
forVisibleElem=true;
/*draw zones*/
let DrawZones = function () {
const greyZonesCount = zonesCount / 1.6;
greenZonesCount = zonesCount - greyZonesCount,
startAngle = (startAngleIndex - 0.02) * Math.PI,
endGreyAngle = (startAngleIndex + greyZonesCount * step) * Math.PI,
endGreenAngle = (endAngleIndex + 0.02) * Math.PI,
//zones' options
sectionOptions = [
{
startAngle: startAngle,
endAngle: endGreyAngle,
color: "#e7e7e7",
zoneLineWidth: 2
},
{
startAngle: endGreyAngle,
endAngle: endGreenAngle,
color: "#13b74b",
zoneLineWidth: 5
},
];
//draw zones
this.DrawZone = function (options) {
ctx.beginPath();
ctx.arc(proportions.general.middleX, proportions.general.middleY, proportions.general.radius, options.startAngle, options.endAngle, counterClockwise);
ctx.lineWidth = options.zoneLineWidth;
ctx.strokeStyle = options.color;
ctx.lineCap = "round";
ctx.stroke();
};
sectionOptions.forEach(options => this.DrawZone(options));
};
/*draw dots*/
let DrawTicks = function () {
startAngleIndex = .73,
endAngleIndex = 2.27,
step = (endAngleIndex - startAngleIndex) / zonesCount;
this.DrawTick = function (angle,count) {
let fromX = proportions.general.middleX + (proportions.general.radius - proportions.ticks.tickOffsetFromArc) * Math.cos(angle),
fromY = proportions.general.middleY + (proportions.general.radius - proportions.ticks.tickOffsetFromArc) * Math.sin(angle),
toX = proportions.general.middleX + (proportions.general.radius + proportions.ticks.tickOffsetFromArc) * Math.cos(angle),
toY = proportions.general.middleY + (proportions.general.radius + proportions.ticks.tickOffsetFromArc) * Math.sin(angle),
centerOfDotX=(fromX+toX)/2,
centerOfDotY=(fromY+toY)/2;
ctx.beginPath();
ctx.arc(centerOfDotX,centerOfDotY,6,0,Math.PI*2,true);
if (count<6){
switch (count) {
case 1:
case 2:
case 3:
ctx.fillStyle=colorPalette.ticks.red.redTickColor;
break;
default:
ctx.fillStyle=colorPalette.ticks.yellow.darkYellowTickColor;
break;
}
}else{
ctx.fillStyle=colorPalette.ticks.green.whiteFillColor;
ctx.strokeStyle=colorPalette.ticks.green.greenTickColor;
ctx.shadowColor = colorPalette.ticks.green.greenShadowColor;
ctx.shadowBlur = 15;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.stroke();
}
ctx.fill();
ctx.closePath();
ctx.shadowBlur =0;
};
let count=0;
for (let i = startAngleIndex; i <= endAngleIndex; i += step) {
let angle = i * Math.PI;
count++;
this.DrawTick(angle,count);
}
};
//draw numbers
let DrawDigits = function () {
let angleIndex = startAngleIndex;
digits.forEach(function (digit) {
let angle = angleIndex * Math.PI,
x = proportions.general.middleX + (proportions.general.radius - proportions.digits.digitsOffsetFromArc) * Math.cos(angle),
y = proportions.general.middleY + (proportions.general.radius - proportions.digits.digitsOffsetFromArc) * Math.sin(angle);
angleIndex += step;
ctx.font = fonts.digitsFont;
ctx.fillStyle = colorPalette.text;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(digit, x, y);
});
};
/*draw arrow*/
let DrawArrow = function () {
ctx.beginPath();
ctx.lineCap = "round";
ctx.moveTo(proportions.general.middleX-15, proportions.general.middleY);
ctx.lineTo(proportions.general.middleX, proportions.general.middleY-150);
ctx.lineTo(proportions.general.middleX+15, proportions.general.middleY);
ctx.closePath();
ctx.strokeStyle = colorPalette.arrow.bgBlue;
ctx.fillStyle=colorPalette.arrow.bgBlue;
ctx.shadowColor=colorPalette.arrow.shadowColor;
ctx.shadowBlur = 15;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.stroke();
ctx.fill();
ctx.shadowBlur =0;
};
let oldText=0;
/*draw indicator's number*/
let DrawIndicator=function (val) {
ctx.font = fonts.indicator;
ctx.fillStyle = colorPalette.ticks.green.whiteFillColor; // or whatever color the background is.
ctx.fillText(oldText, proportions.general.middleX, proportions.indicator.quarterY);
ctx.fillStyle = colorPalette.text;
ctx.fillText(`${val}`, proportions.general.middleX, proportions.indicator.quarterY);
ctx.font = fonts.digitsFont;
ctx.fillText('points',proportions.general.middleX,proportions.indicator.quarterY+proportions.general.middleY/5);
oldText=val;
};
let indicatorNum=0;
/*renderer*/
function renderer() {
ctx.clearRect(0,0,canvas.width,canvas.height);
DrawZones();
DrawTicks();
DrawDigits();
Diagram();
DrawIndicator(indicatorNum);
ctx.translate(proportions.general.middleX,proportions.general.middleY);
ctx.rotate(arrowValueIndex);
ctx.translate(-proportions.general.middleX,-proportions.general.middleY);
DrawArrow();
ctx.translate(proportions.general.middleX,proportions.general.middleY);
ctx.rotate(-arrowValueIndex);
ctx.translate(-proportions.general.middleX,-proportions.general.middleY);
}
function val(value) {
let sector = Math.PI*0.385;
if (value < 40)
arrowValueIndex = value/40*sector - sector*2;
else
arrowValueIndex = (value-40)/60*sector*3 - sector;
let add=(val)=>{
indicatorNum=val;
allDataDiagram.unshift(val);
allDataDiagram=allDataDiagram.slice(0,186);
};
add(value);
// document.querySelector('span').textContent = value;
renderer();
}
//кроссбраузерный requestAnimationFrame
let requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback){
window.setTimeout(callback, 1000 / 60);
};
})();
if (forVisibleElem)
canvas.classList.add('slide-in-fwd-center');
let delay = 2; // задержка перед анимацией
let duration = 3; // кол во секунд анимации роста значения
let time = new Date().getTime(); // Время начала анимации
let Engine = () => {
// кол-во секунд с начала анимации
let t = (new Date().getTime() - time) / 1000;
val(+getValueFromTime(t).toFixed(1));
requestAnimFrame(Engine);
};
// получить значение спидометра в зависимости от текущего времени
function getValueFromTime(t) {
if (t < delay) // если еще не прошло время задержки
return 0 // вернем 0
t -= delay; // иначе вычитаем время задержки
if (t < 0.95*duration) { // если прошло меньше 95 % времени анимации
// переводим значение времени в значение при помощи функции сглаживания
// EasingFunctions.easeOutCubic (значение на входе должно быть от 0 до 1)
return 98 * EasingFunctions.easeOutCubic(t/duration);
}
// иначе это функция от синуса от этого значения
return 98 + EasingFunctions.easeInOutQuint(1-(1+Math.sin(t*22))/2);
}
let Diagram=()=>{
this.drawLines=(x,y,width,height)=>{
ctx.lineWidth=1.5;
ctx.strokeStyle=colorPalette.diagram.bg.lines;
ctx.moveTo(x,y);
ctx.lineTo(width,height);
ctx.stroke();
};
this.drawCircles = (x,y,r)=>{
ctx.beginPath();
ctx.arc(x,y,r,2*Math.PI,false);
ctx.fillStyle=colorPalette.ticks.green.greenTickColor;
ctx.fill();
ctx.closePath();
};
this.writeNums = (value,x,y)=>{
ctx.font = fonts.diagramFont;
ctx.fillStyle = colorPalette.text;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(value, x, y);
};
this.drawD=()=>{
// console.log(allDataDiagram);
for (var i=0; i<=widthD; i++){
//draw bg gradient
ctx.fillRect(proportions.general.middleX/1.6+i, proportions.general.middleY*1.53+heightD, 1, -(allDataDiagram[i]*0.25-2));
ctx.fillStyle=colorPalette.ticks.green.whiteFillColor;
ctx.fillRect(proportions.general.middleX/1.6+i,proportions.general.middleY*1.53,1,4+28-allDataDiagram[i]*0.25);
ctx.fillStyle=colorPalette.ticks.green.greenTickColor;
ctx.fillRect(proportions.general.middleX/1.6+i,proportions.general.middleY*1.53+4+28-allDataDiagram[i]*0.25,1,2);
ctx.fillStyle=gradientD;
}
};
const widthD=186,
heightD=32,
gradientD=ctx.createLinearGradient(0,0,widthD/2,0);
gradientD.addColorStop(0,colorPalette.diagram.bg.gradient[0]);
gradientD.addColorStop(1,colorPalette.diagram.bg.gradient[0]);
//draw grey lines
this.drawLines(proportions.general.middleX/1.6,proportions.general.middleY*1.53,proportions.general.middleX/1.6,proportions.general.middleY*1.53+heightD);
this.drawLines(proportions.general.middleX/1.6+widthD,proportions.general.middleY*1.53,proportions.general.middleX/1.6+widthD,proportions.general.middleY*1.53+heightD);
//write numbers
this.writeNums(94,proportions.general.middleX/1.6, proportions.general.middleY*1.48);
this.writeNums(97,proportions.general.middleX/1.6+widthD, proportions.general.middleY*1.48);
//draw diagram
this.drawD();
//draw circles
this.drawCircles(proportions.general.middleX/1.6,(proportions.general.middleY*1.53)+(32-94*0.25),3);
this.drawCircles(proportions.general.middleX/1.6+widthD,(proportions.general.middleY*1.53)+(32-97*0.25),3);
};
window.onload=Engine;
</script>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Подскажите пожалуйста есть ли какая-нибудь HTML/JS библиотека-слайдер для файлов в форматеpdf с кнопками переключения next/prev? В идеале хотелось...
Есть репозиторий (не мой) https://githubcom/dwcares/realchess В котором написан скрипт онлайн шахмат
Есть необходимость при изменении значения переменной, менять текст в заголовке
Подскажите пожалуйста, есть такой код который обновляет div с id="com_project"