Updating styles outside of a components scope - Angular 2 - css

I am creating a very simple web app using Angular 2 that asks the user to input an RGB color code. After the user inputs the code, the page background should change to the inputted color.
Currently, this is what I have in my app.component.ts file:
/**
* Fired when the user clicks the #update-background button. This function will read the current input values and set the background color to these values.
*
* #param rgb: RGB object bound to the input fields. Holds the rgb(,,) values for the new background
*/
updateBackgroundColor(rgb) {
// 1. Construct the new background color
var updatedBackgroundColor = "rgb(" + rgb.r + "," + rgb.g + "," + rgb.b + ")";
// 2. Set the background of the <body> to the new background color. Right now I am using direct DOM manipulation because I could not find a way to access the <body> via typescript.
document.body.style.background = updatedBackgroundColor;
}
Is this best way to update the <body> element's style? The code is currently working (demo), but I just want to be sure this is the most efficient way to access the <body> element via typescript and Angular 2.

Your answer is right, we can't dynamically change style of an element using class selector.

Related

How would I make a color relative to images in the background?

For example, if you go to Twitter and click on an image, you can see they have a nice color that is close to what you see on the image. I tried looking up ways to achieve this as well as trying to figure it out on my own but no luck. I'm not sure if there's a color: relative property or not.
if you want to use the a colour that exists in your image and set it as a background colour you need to use the canvas element in the following manner:
HTML (this is your image)
<img src="multicolour.jpg" id="mainImage">
JS
window.onload = function() {
// get the body element to set background (this can change dependending of your needs)
let body = document.getElementsByTagName("body")
// get references to the image element that contains the picture you want to match with background
let referenceImage = document.getElementById("mainImage");
// create a canvas element (but don't add it to the page)
let canvas = document.createElement("canvas");
// make the canvas size the same as your image
canvas.width = referenceImage.offsetWidth
canvas.height = referenceImage.offsetHeight
// create the canvas context
let context = canvas.getContext('2d')
// usage your image reference to draw the image in the canvas
context.drawImage(referenceImage,0,0);
// select a random X and Y coordinates inside the drawn image in the canvas
// (you don't have to do this one, but I did to demonstrate the code)
let randomX = Math.floor(Math.random() * (referenceImage.offsetWidth - 1) + 1)
let randomY = Math.floor(Math.random() * (referenceImage.offsetHeight - 1) + 1)
// THIS IS THE MOST IMPORTANT LINE
// getImageData takes 4 arguments: coord x, coord y, sample size w, and sample size h.
// in our case the sample size is going to be of 1 pixel so it retrieves only 1 color
// the method gives you the data object which constains and array with the r, b, g colour data from the selected pixel
let color = context.getImageData(randomX, randomY, 1, 1).data
// use the data to dynamically add a background color extracted from your image
body[0].style.backgroundColor = `rgb(${color[0]},${color[1]},${color[2]})`
}
here is a gif of the code working... hopefully this helps
UPDATE
Here is the code to select two random points and create a css3 background gradient
window.onload = function() {
// get the body element to set background (this can change dependending of your needs)
let body = document.getElementsByTagName("body")
// get references to the image element that contains the picture you want to match with background
let referenceImage = document.getElementById("mainImage");
// create a canvas element (but don't add it to the page)
let canvas = document.createElement("canvas");
// make the canvas size the same as your image
canvas.width = referenceImage.offsetWidth
canvas.height = referenceImage.offsetHeight
// create the canvas context
let context = canvas.getContext('2d')
// usage your image reference to draw the image in the canvas
context.drawImage(referenceImage,0,0);
// select a random X and Y coordinates inside the drawn image in the canvas
// (you don't have to do this one, but I did to demonstrate the code)
let randomX = Math.floor(Math.random() * (referenceImage.offsetWidth - 1) + 1)
let randomY = Math.floor(Math.random() * (referenceImage.offsetHeight - 1) + 1)
// THIS IS THE MOST IMPORTANT LINE
// getImageData takes 4 arguments: coord x, coord y, sample size w, and sample size h.
// in our case the sample size is going to be of 1 pixel so it retrieves only 1 color
// the method gives you the data object which constains and array with the r, b, g colour data from the selected pixel
let colorOne = context.getImageData(randomX, randomY, 1, 1).data
// THE SAME TO OBTAIN ANOTHER pixel data
let randomX2 = Math.floor(Math.random() * (referenceImage.offsetWidth - 1) + 1)
let randomY2 = Math.floor(Math.random() * (referenceImage.offsetHeight - 1) + 1)
let colorTwo = context.getImageData(randomX2, randomY2, 1, 1).data
// use the data to dynamically add a background color extracted from your image
//body[0].style.backgroundColor = `rgb(${allColors[0]},${allColors[1]},${allColors[2]})`
body[0].style.backgroundImage = `linear-gradient(to right, rgb(${colorOne[0]},${colorOne[1]},${colorOne[2]}),rgb(${colorTwo[0]},${colorTwo[1]},${colorTwo[2]}))`;
}
The following are your options.
1. Use an svg.
As far as I know there's no way to have javascript figure out what color is being used in a png and set it as a background color. But you can work the other way around. You can have javascript set the background color and an svg image to be the same color.
See this stackoverflow answer to learn more about modifying svgs with javascript.
2. Use a custom font.
There are fonts out there that provide a bunch of icons instead of letters, you can also create your own font if you feel so inclined to do so. With css you just have to set the font-color of that icon to be the same as the background-color of your other element.
Font Awesome provides a bunch of useful custom icons. If the image you need to use happens to be similar to one of theirs, you can just go with them.
3. Use canvas
If you really want to spend the time to code it up you can use a html <canvas/> element and put the image into it. From there you can inspect certain details about the image like its color, then apply that color to other elements. I won't go into too much detail about using this method as it seems like it's probably overkill for what you're trying to do, but you can read up more about from this stackoverflow answer.
4. Just live with it.
Not a fun solution, but this is usually the option I go with. You simply have to hard-code the color of the image into your css and live with it. If you ever need to modify the color of the image, you have to remember to update your css also.

JavaFX change single style in CSS stylesheet

I've created a small text editor window that allows the user to change some basic properties of a text area included within the screen. Two of the options available to change the properties of the textArea are font color and font color fill, which are both handled by separate color pickers.
I ran into an issue when testing these buttons using the setStyle method that only one property could be saved at a time. Example, if text color was set to BLUE, and afterwards fill color was set to YELLOW, text color would not remain blue, but instead revert back to its default defined in the stylesheet (black).
To fix this problem, I have created the following method;
private void updateTheSyle()
{
this.textArea.setStyle("-fx-control-inner-background: " + toRgbString(this.colorPickerFill.getValue()) +
"; -fx-text-fill: " + toRgbString(this.colorPickerFont.getValue()) + ";");
}
The toRgbString() method is also called, this is simply passing the user input from the color picker into a string such that the setStyle method can pass the correct parameters to the stylesheet.
This solution does work, as it enables me to change both the fill and the font color without reverting back to default upon selection. However, my program includes more than just fill and font color, which will contribute to a far longer setStyle statement as these options are added.
TLDR: Is there a way to edit a single style included in a CSS stylesheet without affecting the other styles in a given class?
For your first question (longer setStyle statement), If we take into account that the style is defined by a String, and it takes a whole set of details to provide for a single Style, so why not use a List<String> :
List<String> example = new ArrayList<>();
String style = "";
//For example if you use 2 textField to get the (value) and (type):
example.add("-fx-"+textFieldType+":"+textFieldValue + "; ");
//To gather all the properties in a single string
for(String property: example){
style += example;
}
yourNode.setStyle(style);
I do not know if there is a better approach but it works, good luck !
Edit :
I think this tip answers your second question:
private void Update(String type,String newValue){
for(int i = 0; i < example.size(); i++){
if(example.get(i).contains(type)){
example.set(i, "-fx-"+type+":"+newValue + "; ");
//Here you add a (break;) to not alter the other similar styles !
}
}
//Here you use a loop to update the new elements changed
}
I hope this will help you solve your problem !

Automatically change image-url by 1 for next div?

I'm making a bunch of stacked divs that will expand when moused-over to show an image, but I have a lot of images.
Is there a way in CSS or JS (I don't really know anything about JS) to have each div automatically use the next image in a folder? ex: the images are named map1.jpg, map2.jpg ... map91.jpg. and be able to use the same background-image:url but have something telling it to add 1 to the next image for each new div so I don't have to manually specify 90+ different images.
I hope I was able to explain that well enough. Thanks =)
In CSS this is impossible, cause you can't concatenate the url path for background-image.
in javascript this is pretty simple, using jQuery you can simply load all div you need when body is ready:
// on page load
$(document).ready(function(){
// 10 images to div #image-board
for(var i=0; i<10; i++){
// create a div with image #i
$('#image-board').append('<div><img src="my/collection/folder/Image'+i+'.jpg"></div>');
}
});
don't forget to create in your HTML page a <div id="image-board"></div> where all images will be listed to
I'll try to include lots of detail since you say you're unfamiliar with JavaScript. When you say stacked divs, I assume you mean one inside another. Start with a div with appropriate id and background in your html <div id="div0" style="background-image:url('map0.jpg')"></div> Here's some Javascript using jQuery (a very common javascript library you can include with a script tag) that will add a new div inside your first div with the updated url name.
for (var i = 0; i < number_of_images - 1; i++) {
var oldId = '#div' + i;
var newId = 'div' + (i + 1);
var newUrl = 'map'+(i+1)+'.jpg';
var newdiv = '<div id="' + newId + '" style="background-image:url('+newUrl+')></div>';
$(oldId).append(newdiv);
}
The for loop will go over every image, then a string is created in a series of concatenations that becomes your updated div. The '$' searches for the DOM element with that id, then adds the new div inside it. If by stacked you meant a new div underneath but not contained by the previous div, use .insertAfter instead of .append. Assuming your webpage can reach all of the images, this should work. Also notice I've 0 indexed this (the standard in Javascript) but your question referred to map1 as the first map. If you have already named these maps, you may need to re-index the for loop to 1.

How to create a button in TinyMCE 4 that increments font size

Has anyone managed to create a button in TinyMCE 4 that will increment the font size of the selected text by, say, 1px?
The problem I'm having is getting ahold of the selected text, whether it's in a span already or not.
I'm willing to modify the TinyMCE source.
Thanks for any ideas.
You don't need to modify the source code, you can create a plugin.
Here is the documentation of how to create a plugin for TinyMCE:
http://www.tinymce.com/wiki.php/Tutorials:Creating_a_plugin
based on that you can create your own button (see working example)
here is part of the code:
var currentFontSize = new Number($(tinyMCE.activeEditor.selection.getNode()).css('font-size').replace('px','')); //remove the px part
currentFontSize = currentFontSize + 1; //increase font by one
tinymce.activeEditor.formatter.register('mycustomformat', {
inline : 'span',
styles : {'font-size' : currentFontSize + 'px'} //this is the font size incremented by one
});
tinymce.activeEditor.formatter.apply('mycustomformat'); //apply the format to the selected text

Embed CSS attribute in HTML

I have the color theme of a website I'm working on change on refresh and would like to display the css background color attribute in my HTML. Is that possible?
i.e.
<footer>The color of the moment is <insert the background color attribute>. Refresh for a makeover</footer>
would display something like
"The color of the moment is #DB0C0C. Refresh for a makeover"
Since the hex color changes based on the style sheet loaded, I don't want to hardcode it. If I had a ruby variable #color which = #ff0000 and wanted to display it in html I could do something like
<%= #color%>
I'm wondering if there is any way to do something similar to access a CSS attribute.
You don't even need jQuery for this.. you can use just vanilla javascript with .getComputedStyle():
<span id='color-map'></span>
var element = document.getElementById("id-goes-here");
var style = window.getComputedStyle(element);
document.getElementById('color-map').innerHTML = style.backgroundColor;
However, it would appear that this does not give the color as a hex, but rather an 'rpg(x, y, z)' string. To get the hex from that, you can parse it using regex and return the result:
function rgbsToHex(str) {
var hex = "#";
var matches = str.match(/rgb\((\d+),\s(\d+),\s(\d+)\)/);
hex += Number(matches[1]).toString(16);
hex += Number(matches[2]).toString(16);
hex += Number(matches[3]).toString(16);
return hex;
}
DEMO
You can use the .css() function in jQuery.
$('footer').find('span').text($('.bg').css('background-color'));
This will give you the color in rgb, if you would like to show it in HEX then check this for more info.

Resources