Since you have overriden the Blocks you can actually just use the RedstoneParticleData that's already there. The constructor parameters are RGBA 0.0-1.0
Interesting I guess particles don't really support being overriden. Which is not really friendly to you.
The only other way I see this as being possible is to override all of the redstone blocks and changing what particle they spawn.
Can you show a screenshot of two of what you have/mean? In general you should cancel the original and render your own only when the experience bar shouldn't be rendered to reduce some rendering calls.
First don't use event.getType() == ElementType.TEXT use ElementType.EXPERIENCE. Then use event.setCanceled(true). Then you will have to render the level and the bar.
.setRegistryName(modid, registryName)
or
setRegistryName("modid:registryName")
or
setRegistryName(new ResourceLocation(modid, registryName))
or
setRegistryName(new ResourceLocation(modid:registryName))
where modid is "minecraft"
If it works like other registries you just need to register your own ParticleType with the same registry name as the Minecraft one. So something like "minecraft:redstone_particle_data"
Minecraft uses a single AABB as collision boxes for a single Entity. I suppose you could do a calculation inside Entity::getCollisionBox based on the entity it is asking about. Like return the closest AABB to the entity passed in.
Or definitely do what Alpvax said and check out the EnderDragon code.
Just the rendering has to be client side only. Many things you want to animate in sync for players right? The only way to do that is by using the server to control the animation.