我有一个线性渐变用作百分比条,其中一个小椭圆沿着条移动以显示当前的完成百分比。完成百分比通过调用函数的AngularJS绑定进行更新。
我需要根据当前位置的渐变条颜色更改椭圆的颜色。让我们说百分比是80%,我需要将渐变的颜色设置在80%的位置。
这可能吗?
<svg height="20px" width="100%">
<defs>
<linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
<stop offset="50%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgb(79,189,0);stop-opacity:1" />
</linearGradient>
</defs>
<rect width="100%" height="3px" y="50%" fill="url(#gradient)" style="stroke-width:0" />
<rect width="30px" height="20px" x="{{calculateProfilePercentage()}}%" rx="8" ry="8" fill="rgb(249,166,31)" style="stroke-width:0" />
</svg>
答案 0 :(得分:2)
AFAIK您无法从渐变中读取值,因为渐变对象不会公开方法。
但是,您可以创建一个离屏画布,绘制渐变并从那里读取像素值。
例如,让我们创建一个GradientReader对象。这允许我们实例化它并嵌入方法等等:
function GradientReader(colorStops) {
var canvas = document.createElement('canvas'), // create canvas element
ctx = canvas.getContext('2d'), // get context
gr = ctx.createLinearGradient(0, 0, 101, 0), // create a gradient
i = 0, cs;
canvas.width = 101; // 101 pixels incl.
canvas.height = 1; // as the gradient
for(; cs = colorStops[i++];) // add color stops
gr.addColorStop(cs.stop, cs.color);
ctx.fillStyle = gr; // set as fill style
ctx.fillRect(0, 0, 101, 1); // draw a single line
// method to get color of gradient at % position [0, 100]
this.getColor = function(pst) {
return ctx.getImageData(pst|0, 0, 1, 1).data;
};
}
现在我们可以使用颜色停止来设置对象。
var gr = new GradientReader([{stop: 0.0, color: '#f00'},
{stop: 0.5, color: '#ff0'},
{stop: 1.0, color: 'rgb(79,189,0)'}]);
我们现在有一个模仿渐变的对象,现在我们需要做的就是用百分比值调用它的方法getColor()
:
var col = gr.getColor(pst);
el.style.backgroundColor = 'rgb(' + col[0] + ',' + col[1] + ',' + col[2] + ')';
<强> FIDDLE 强>
根据您的喜好/需求进行修改。
希望这有帮助!
答案 1 :(得分:0)
这是我使用Angular 8中的答案和一些ES6技术的答案。新百分比是通过可观察者获得的。
HTML文件包含一个SVG,该SVG具有链接到该类的两个属性。像这样:
<svg>
<circle [attr.stroke]='strokeColor' [attr.fill]='fillColor'>
</svg>
应用程序的打字稿文件:
import {Component, Input, OnInit} from '@angular/core';
import {Observable} from 'rxjs';
@Component({
selector: 'app-real-time-indicator',
templateUrl: './real-time-indicator.component.html',
styleUrls: ['./real-time-indicator.component.css']
})
export class RealTimeIndicatorComponent implements OnInit {
@Input() percentagePassed$: Observable<number>;
@Input() minutesRemaining$: Observable<number>;
public currentPercentage: number;
public minutesRemaining: number;
private canvas2dContext: any;
private canvas: any;
public fillColor: string;
public strokeColor: string;
constructor() {
}
ngOnInit(): void {
this.percentagePassed$.subscribe((newValue) => {
this.currentPercentage = 100 - newValue;
let [r, g, b] = this.getColor( newValue);
this.fillColor = `rgb(${r},${g},${b})`;
[r, g, b] = this.getColor( 100 - newValue);
this.strokeColor = `rgb(${r},${g},${b})`;
});
this.canvas = document.createElement('canvas'); // create canvas element
this.canvas2dContext = this.canvas.getContext('2d'); // get context
const gr = this.canvas2dContext.createLinearGradient(0, 0, 101, 0); // create a gradient
this.canvas.width = 101; // 101 pixels incl.
this.canvas.height = 1; // as the gradient
const colorStops = [
{stop: 0.0, color: 'lightgreen'},
{stop: 0.9, color: 'orange'},
{stop: 1.0, color: 'red'},
];
for (const cs of colorStops) // add color stops
{
gr.addColorStop(cs.stop, cs.color);
}
this.canvas2dContext.fillStyle = gr; // set as fill style
this.canvas2dContext.fillRect(0, 0, 101, 1); // draw a single line
}
// method to get color of gradient at % position [0, 100]
getColor(percentage: number) {
return this.canvas2dContext.getImageData(percentage , 0, 1, 1).data;
}
}