Reputation: 151
Here beginner in typescript, more with css and first time playing with SVG.
I'm trying to make an heater svg icon that the four wave change color in function of the heater heating stage.
In the console log, it seem to work on the controller but I'm unable to display the color properly.
<div>
<svg width="20%" height="30%" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon">
<g>
<title>background</title>
<rect x="-1" y="-1" width="1026" height="1026" id="canvas_background" fill="none"/>
</g>
<g>
<title>Layer 1</title>
<!--top line-->
<path d="m910,782.001l-800,0c-8.837,0 -16,-7.163 -16,-16s7.163,-16 16,-16l800,0c8.837,0 16,7.163 16,16s-7.163,16 -16,16zm-800,112l800,0c8.837,0 16,7.163 16,16s-7.163,16 -16,16l-800,0c-8.837,0 -16,-7.163 -16,-16s7.163,-16 16,-16z" id="svg_5"/>
<!--wave 1-->
<path d="m29,844.001zm188.237,-149.935c-0.078,0.081 -0.145,0.169 -0.225,0.249c-0.048,0.048 -0.101,0.087 -0.149,0.135c-0.188,0.19 -0.37,0.384 -0.559,0.573l-0.036,-0.036c-6.289,5.554 -15.887,5.342 -21.902,-0.672c-6.014,-6.014 -6.227,-15.611 -0.672,-21.899l-0.036,-0.036c81.293,-81.282 81.293,-159.067 0,-240.35l0.708,-0.708c-93.799,-93.787 -93.799,-176.847 0,-270.634c6.253,-6.253 16.392,-6.253 22.645,0c6.253,6.252 6.253,16.39 0,22.642c-81.293,81.282 -81.293,144.067 0,225.35l-0.011,0.321l-0.696,0.386c93.484,93.472 93.787,190.818 0.933,284.679z" id="svg_1"/>
<!--wave 2-->
<path d="m218,843.001zm188.237,-149.935c-0.078,0.081 -0.145,0.169 -0.225,0.249c-0.048,0.048 -0.101,0.087 -0.149,0.135c-0.188,0.19 -0.37,0.384 -0.559,0.573l-0.036,-0.036c-6.289,5.554 -15.887,5.342 -21.902,-0.672c-6.014,-6.014 -6.227,-15.611 -0.672,-21.899l-0.036,-0.036c81.293,-81.282 81.293,-159.067 0,-240.35l0.708,-0.708c-93.799,-93.787 -93.799,-176.847 0,-270.634c6.253,-6.253 16.392,-6.253 22.645,0c6.253,6.252 6.253,16.39 0,22.642c-81.293,81.282 -81.293,144.067 0,225.35l-0.011,0.321l-0.696,0.386c93.484,93.472 93.787,190.818 0.933,284.679z" id="svg_2"/>
<!--wave 3-->
<path d="m426,843.001zm188.237,-149.935c-0.078,0.081 -0.145,0.169 -0.225,0.249c-0.048,0.048 -0.101,0.087 -0.149,0.135c-0.188,0.19 -0.37,0.384 -0.559,0.573l-0.036,-0.036c-6.289,5.554 -15.887,5.342 -21.902,-0.672c-6.014,-6.014 -6.227,-15.611 -0.672,-21.899l-0.036,-0.036c81.293,-81.282 81.293,-159.067 0,-240.35l0.708,-0.708c-93.799,-93.787 -93.799,-176.847 0,-270.634c6.253,-6.253 16.392,-6.253 22.645,0c6.253,6.252 6.253,16.39 0,22.642c-81.293,81.282 -81.293,144.067 0,225.35l-0.011,0.321l-0.696,0.386c93.484,93.472 93.787,190.818 0.933,284.679z" id="svg_3"/>
<!--wave 4-->
<path d="m631,843.001zm188.237,-149.935c-0.078,0.081 -0.145,0.169 -0.225,0.249c-0.048,0.048 -0.101,0.087 -0.149,0.135c-0.188,0.19 -0.37,0.384 -0.559,0.573l-0.036,-0.036c-6.289,5.554 -15.887,5.342 -21.902,-0.672c-6.014,-6.014 -6.227,-15.611 -0.672,-21.899l-0.036,-0.036c81.293,-81.282 81.293,-159.067 0,-240.35l0.708,-0.708c-93.799,-93.787 -93.799,-176.847 0,-270.634c6.253,-6.253 16.392,-6.253 22.645,0c6.253,6.252 6.253,16.39 0,22.642c-81.293,81.282 -81.293,144.067 0,225.35l-0.011,0.321l-0.696,0.386c93.484,93.472 93.787,190.818 0.933,284.679z" id="svg_4"/>
</g>
</svg>
</div>
import { Component, Input, OnChanges } from '@angular/core';
@Component({
selector: 'heater-svg',
templateUrl: 'heater-svg.html'
})
export class HeaterSvgComponent implements OnChanges {
@Input() stage: number = 0;
constructor() {
}
ngOnChanges() {
this.stageSet(this.stage);
}
stageSet(stagePercent: number) {
let idList = ["svg_1", "svg_2", "svg_3", "svg_4" ];
let stage: number = 0;
if (stagePercent > 99) {
stage = 4;
} else if (stagePercent > 70) {
stage = 3;
} else if (stagePercent > 30) {
stage = 2;
} else if (stagePercent > 0) {
stage = 1;
}
console.log(stage); // <<<-----------------
for (let i = 1; i < 5; i++) {
let state = false;
if (stage >= i) {
state = true;
}
this.displayStage(idList[i-1], state);
}
}
displayStage(id: string, state: boolean) {
let el = document.getElementById(id);
if (el) {
if (state) {
console.log("fill in red");
el.style.fill = '#ff3300';
} else {
el.style.fill = '#dadada';
}
}
}
}
This is used in an ionic4 app, inside an ion-slide oc 10 slide:
<heater-svg [stage]="channel.percentOut"></heater-svg>
displayStage
fires and console.log
logs the data correctly, but el.style.fill
does not work when I do not mute the else one, and even so, it only change the icon in the first slide...
Is component use some kind of instance for each use of the ccomponent or resource are some share?
Is getElementById
a good way of doing it? Or is fill
the better way to change the svg color? I think the data [stage] is processed correctly.
Upvotes: 0
Views: 1621
Reputation: 151
As suggested by @smnbbrv, I dig into angular, but also some css and sass rules... Most of my problem was name scoping. I add to go trough getbyName instead of ById.
Also, I add to add and input to link the class instance to my data.
import { Component, Input, OnChanges } from '@angular/core';
@Component({
selector: 'heater-svg',
templateUrl: 'heater-svg.html',
})
export class HeaterSvgComponent implements OnChanges {
@Input() id: number = 0;
@Input('stage') stagePercent: number = 0;
constructor() {
}
ngOnChanges() {
let stage = this.getStageLevel(this.stagePercent);
let els = document.getElementsByClassName('heater')[this.id];
for (let i = 1; i <= 4; i++) {
let state = false;
if (stage >= i) {
state = true;
}
if (els) {
let el = els.getElementsByClassName('wave')[i-1];//wave 0 is stage 1
if (state) {
this.setColor(el, '#ff3300');
} else {
this.setColor(el, '#dadada');
}
}
}
}
getStageLevel(percent: number) : number {
let stage: number = 0;
if (percent > 99) {
stage = 4;
}
else if (percent > 70) {
stage = 3;
}
else if (percent > 30) {
stage = 2;
}
else if (percent > 0) {
stage = 1;
}
return stage;
}
setColor(item, color) {
item.style["fill"] = color;
}
}
Upvotes: 1