Is there is a way in CSS to make it pick a random font color from an array? I know I can do this with server side or javascript, but I am wondering if there is pure CSS way to do this.
CSS expressions (allowing for dynamic script content via CSS) were abominations cast in the bowels of the hell of inefficiency alongside Web Forms, only ever supported by IE7 and below. But since you asked.
<style>
blink marquee {
color: expression("rgb(" + Math.floor(Math.random() * 255)
+ "," + Math.floor(Math.random() * 255) + ","
+ Math.floor(Math.random() * 255) + ")");
}
</style>
<blink>
<marquee>
color me beautiful
</marquee>
</blink>
This is not possible in CSS, which is firmly deterministic. You could do this with client-side JavaScript, though:
var colors = ['#ff0000', '#00ff00', '#0000ff'];
var random_color = colors[Math.floor(Math.random() * colors.length)];
document.getElementById('title').style.color = random_color;
If you're using jQuery, the last line could become
$('#title').css('color', random_color);
Simple in JavaScript with JQuery.
You could do something like:
var hexArray = ['#hexVal','#hexVal','#hexval', '#hexval']
var randomColor = hexArray[Math.floor(Math.random() * hexArray.length)];
$("#divId").css("color",randomColor); //A class selector would work too
Which would select a new color every time the page refreshes.
This is how I did it.
The first part is a sequential order, element 1 gets color 1 etc.
Then when you are out of colors it will randomize it.
//Specify the class that you want to select
var x = document.getElementsByClassName("ms-webpart-chrome-title");
var i;
var c;
//specify the colors you want to use
var colors = ["#009933", "#006699", "#33cccc", "#99cc00", "#f60"];
var d = colors.length;
for (i = 0; i < x.length; i++){
while (i < d) {
c = i;
var random_color = colors[c];
x[i].style.borderTopColor = random_color;
i++;
}
while (i >= d) {
var random_color = colors[Math.floor(Math.random() * colors.length)];
x[i].style.borderTopColor = random_color;
i++;
}
}
without using predefined color set, to get a uniformly randomized color function
function randomColor(){
rc = "#";
for(i=0;i<6;i++){
rc += Math.floor(Math.random()*16).toString(16);
}
return rc;
}
or inline
"#"+Math.floor(Math.random() * 0x1000000).toString(16)
Related
I am currently trying to add some text, which is added dynamically, using RaphaelJS. I want the text to break at 200 pixels, then continue on the next line. Just like if you had a regular DIV with a width in HTML.
https://jsfiddle.net/qLvuztcy/
I've tried something like:
.text {
width: 200px;
max-width: 200px; //and this
}
But that's not how it works, unfortunately. Does anyone know how I can achieve this? I know that adding a \n to the text will make a new line, but I'm not sure how to achieve what I want.
I found an answer for Snap.svg which I've modified a bit. It works perfectly, however.
function text(x, y, txt, max_width, element_class) {
var abc = "abcdefghijklmnopqrstuvwxyzæøåABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ";
var temp = rsr.text(50, 50, abc);
temp.node.classList.add("text");
var letter_width = temp.getBBox().width / abc.length;
temp.remove();
var heights = [];
var loopLines = txt.split("\n");
for (j = 0; j < loopLines.length; j++) {
var words = loopLines[j].split(" ");
var width_so_far = 0,
current_line = 0,
lines = [''];
for (var i = 0; i < words.length; i++) {
var l = words[i].length;
if (width_so_far + (l * letter_width) > max_width) {
lines.push('');
current_line++;
width_so_far = 0;
}
width_so_far += l * letter_width;
lines[current_line] += words[i] + " ";
}
if (j > 0) {
y += heights[j - 1];
}
lines = lines.join("\n");
var t = rsr.text(x, y, lines);
$(t.node).find("tspan").attr("dy", "1.2em");
t.node.classList.add(element_class);
heights.push(t.getBBox().height);
}
}
Requires jQuery, as I am doing the find("tspan") with jQuery (might as well, since I use it other places as well).
I've modified it to now support \n in your strings as well.
SVG doesn't have automatic text wrapping. Well not in the current version anyway.
You have to split the text up into lines yourself. Or if you are displaying the SVG in a browser, you have the option of embedding HTML in the SVG. You can do this with the <foreignObject> element.
I'm not sure whether Raphael has an API for creating foreignObject elements. You'll need to investigate.
Basically, I've built a grid in AS3. Now, I would like to turn it into html5/JS with the new CreateJS ToolKit.
My problem - when I 'publish' to html, I get an empty canvas.
Here is my AS3 code:
var boxNum:int = 2151;
// we need to know how many columns our
// grid is going to have
var cols:int = 72;
// calculate how many rows we need based on
// boxNum and cols
var rows:int = Math.ceil(boxNum / cols);
// the number of boxes attached to the stage
var boxCount:int = 0;
for (var py:int = 0; py<rows; py++) {
for (var px:int = 0; px<cols; px++) {
// make sure we haven't exceeded boxNum
if (boxCount < boxNum) {
var box:Box = new Box();
box.x = 10 + (box.width + 2) * px;
box.y = 10 + (box.height + 2) * py;
addChild(box);
boxCount++;
}
}
}
AS3 code is not converted by the Toolkit. Currently, you have to write JavaScript, and wrap it in /*js */ tags on the timeline, or do all the coding outside of Flash.
Note that JavaScript doesn't support typed variables, you need to use "this" when referencing the current scope, and the "Box" will likely be available as a property of the generated "libs" object.
The Toolkit exported content should already set up a Ticker for you, and add your main Flash root (called "exportRoot" in the default exported code) to the Stage.
/* js
var boxNum = 2151;
var cols = 72;
var rows = Math.ceil(boxNum / cols);
var boxCount = 0;
for (var py = 0; py<rows; py++) {
for (var px = 0; px<cols; px++) {
if (boxCount < boxNum) {
var box = new libs.Box();
box.x = 10 + (box.width + 2) * px;
box.y = 10 + (box.height + 2) * py;
this.addChild(box);
boxCount++;
}
}
}
*/
Future versions of Flash will hopefully allow you to code this right on the timeline, instead of in a code comment block.
I need to reproduce the effect created on this site about Team : http://www.case-3d.com/#about
I try to look on the web but I can not find a tutorial or site that talks about this html5 effect .... I was wondering if someone could help me ?
thanking you in advance
If you inspect the element you can find out they use a canvas. Looking further you can see the script that uses the canvas (by searching in the inspector for the ID or some similar techinque) is called "1". I pulled some of the basic structure so you can follow it:
//This part sets up the canvas and gets the pictures
function setupCanvas() {
// Get canvas and context references
teamCanvas = document.getElementById("stage1");
teamContext = teamCanvas.getContext("2d");
// Get images references
img1 = document.getElementById("01");
img2 = document.getElementById("02");
...
// This part sets the initial position of the shapes
// You can see that it is based of the window size and in reference to each other
// Shape #1
x1_1 = teamCanvas.width / 2;
x1_2 = teamCanvas.width;
x1_3 = teamCanvas.width;
x1_4 = 0;
x1_5 = 0;
y1_1 = ssp1_1 = 929 + diff;
y1_2 = ssp1_2 = 2000 + diff;
y1_3 = ssp1_3 = 4000;
y1_4 = ssp1_4 = 4000;
y1_5 = ssp1_5 = 2000 + diff;
// Shape #2
x2_1 = 0;
x2_2 = teamCanvas.width / 2;
x2_3 = teamCanvas.width;
x2_4 = teamCanvas.width;
x2_5 = 0;
y2_1 = ssp2_1 = 3000;
y2_2 = ssp2_2 = 4000;
y2_3 = ssp2_3 = 3000;
y2_4 = ssp2_4 = 6000;
y2_5 = ssp2_5 = 6000;
...
// Some other stuff goes here, I didn't copy all of it
}
// Then it goes into this function to handle the scroll and redraw it on the canvas
function redrawAbout(scrollPosition) {
// Refresh canvas
teamContext.clearRect(0, 0, teamCanvas.width, teamCanvas.height);
var scrollAmt = scrollPosition / maskModifier;
// Redraw
// Mask #1
if (scrollPosition > -4000) {
teamContext.save();
teamContext.beginPath();
teamContext.moveTo(x1_1, ssp1_1 + scrollAmt);
teamContext.lineTo(x1_2, ssp1_2 + scrollAmt);
teamContext.lineTo(x1_3, ssp1_3 + scrollAmt);
teamContext.lineTo(x1_4, ssp1_4 + scrollAmt);
teamContext.lineTo(x1_5, ssp1_5 + scrollAmt);
teamContext.lineTo(x1_1, ssp1_1 + scrollAmt);
teamContext.clip();
teamContext.drawImage(img1, 0, -200);
teamContext.restore();
}
// Mask #2
if (scrollPosition <= -2100 && scrollPosition > -5900) {
teamContext.save();
teamContext.beginPath();
teamContext.moveTo(x2_1, ssp2_1 + scrollAmt);
teamContext.lineTo(x2_2, ssp2_2 + scrollAmt);
teamContext.lineTo(x2_3, ssp2_3 + scrollAmt);
teamContext.lineTo(x2_4, ssp2_4 + scrollAmt);
teamContext.lineTo(x2_5, ssp2_5 + scrollAmt);
teamContext.lineTo(x2_1, ssp2_1 + scrollAmt);
teamContext.clip();
teamContext.drawImage(img2, 0, -200);
teamContext.restore();
}
In essence, they create some geometric shapes based on x and y co-ordinates, cut the images to fit within their respective geometric area based on those variables, calculate how much is being scrolled (through another plug in I believe), and redraw everything based on how far a user has scrolled.
Inspect element is an incredibly useful tool, learn to use it
When asking questions on StackOverflow, stay away from generics like this. Try to solve it yourself and post what you've tried so far and what is giving you trouble. Give detail and be articulate. If you do that you won't be down voted and you'll get relevant, all around good answers
I'm making an image gallery and I want to have a bunch of thumbnails on the bottom of the screen that smoothly slide from side to side when the mouse moves.
I'm working with a custom class for the container (Tiles) and a custom class for the thumbnails (ImageIcon).
I have a ComboBox which allows users to to choose a gallery. When the user chooses a gallery, the following code is run and the thumbnails should reload. The problem here is that the icons appear on top of each other instead of side by side, also switching categories should remove the old one (see the first for loop), but it does not. Also, the Icons are not animating properly. The animation code is below as well. Right now, only one of the icons will move. The icons should move in order from side to side, stopping when the last few icons hit the edge of the screen, so that they don't get "lost" somewhere off to the side.
Gallery Loader Code:
public function loadCategory(xml:XML = null) {
if (xml != null) {
dp = new DataProvider(xml);
for (var k:int = 0; k < this.numChildren; k++) {
this.removeChild(this.getChildAt(k));
}
var black:DropShadowFilter = new DropShadowFilter(0, 45, 0x000000, 1, 3, 3, 1, 1);
var white:DropShadowFilter = new DropShadowFilter(0, 45, 0xFFFFFF, 1, 2, 2, 1, 1);
for (var i:int = 0; i < dp.length; i++) {
var imgicon:ImageIcon = new ImageIcon();
imgicon.addEventListener(MouseEvent.CLICK, showImage);
imgicon.width = 100;
imgicon.x = (i * (imgicon.width + 20));
imgicon.path = dp.getItemAt(i).data;
imgicon.loadIcon();
imgicon.filters = [black, white];
stage.addEventListener(Event.ENTER_FRAME, moveIcon);
this.addChild(imgicon);
}
} else {
//Failed to load XML
}
}
Icon Animation Code:
public function moveIcon(e:Event){
var speed = 0;
speed = Math.floor(Math.abs(this.mouseX/20));
var image = this.getChildAt(k);
var imagebox = image.width + 20;
var edge:Number = (800/2);
if (this.mouseX > 0) {
for (var k:int = 0; k < this.numChildren; k++) {
if (image.x - (imagebox/2) + speed < -edge + (k * imagebox)) {
speed = 0;
}
image.rotationY = Math.floor(image.x/20);
image.x -= Math.floor(speed);
}
} else {
for (var j = this.numChildren; j >= 0; j--) {
if (image.x + speed > edge - ((imagebox * j) )) {
speed = 0;
}
image.rotationY = Math.floor(image.x/20);
image.x += Math.floor(speed);
}
}
}
As I see it, you have three questions (You should have put these at the end of your question instead of "What is wrong with my code?"). One of the main principles of programming is breaking problems into smaller parts.
How do I line up the ImageIcon beside each other?
How do I remove the old ImageIcon, when switching categories?
How do I animate ALL the ImageIcons together, based on the mouse position, with constraints on either side?
Question 1
I can't see anything wrong, but just check that when you are setting imgicon.x, that imgicon.width is actually set.
Question 2
Instead of relying on numChildren and getChildAt(), I would create a currentIcons array member variable, and when you create a new ImageIcon, just push it onto the array. Then when you want to remove them, you can just loop through the array like this:
for each (var cIcon:ImageIcon in currentIcons)
{
cIcon.removeEventListener(MouseEvent.CLICK, showImage);
removeChild(cIcon);
}
currentIcons = [];
As you can see, I am also removing any listeners that I have added. This is best practice. Then clearing the array when I have removed all the icons.
Question 3
I can see a few things wrong with your code. First, in the line where image is set, k is not set yet!
Here you can also use the currentIcons array, but you probably can't use a for each in loop, because that gives you the items out of order. Just a normal for loop will be better.
I haven't tested this code for the moveIcon method, but the idea should work. You may have to tweek it though:
public function moveIcon(e:Event):void
{
var speed:Number = Math.floor(this.mouseX / 20); // Removed "abs".
var imageBox:Number = currentIcons[0].width;
var edge:Number = 800 / 2;
for (var i:int = 0; i < currentIcons.length; i++)
{
var image:ImageIcon = currentIcons[i] as ImageIcon;
image.x += speed;
image.rotationY = Math.floor(image.x / 20);
var min:int = -edge + (i * imagebox);
if (image.x < min) image.x = min;
var max:int = edge - (imagebox * i);
if (image.x > max) image.x = max;
}
}
EDIT* Sorry, it was supposed to be a greater than in the last if statement, but I had a less than by accident.
Last Edit: Resolved!
Well, i was unable to find the ENTIRE answer here but i finally got what i was after. thanks very much for all of your help and patience.
as a side note: i think i may have been having problems with using the int and Number types, upon closer inspection of my solution, i realised that Number was being used and not int. turns out number contains floating points and int doesn't. my numbers were probably rounding whenever i tried to fix this my self. for all i know, TDI's answer might have been spot on and the use of int for the padding might have accumulated rounded numbers.. Oh well, you learn something every day..
the correct code to constrain movie clips to a container movie clip (or sprite or whatever) in the fashion i was looking for is this:
var picContainer:PicContainer = new PicContainer();
picContainer.x = stage.stageWidth / 2 - picContainer.width / 2;
picContainer.y = stage.stageHeight / 2 - picContainer.height / 2;
addChild(picContainer);
var totalPics:int = 17;
var pic:Pic = new Pic(); //make an instance just to get its width
var xRange:Number = picContainer.width - pic.width;
var spacing:Number = xRange / (totalPics - 1);
//A little optimization: only need to calculate this number ONCE:
var yLoc:Number = picContainer.height / 2 - pic.height / 2;
for(var i:int = 0; i < totalPics; i++) {
pic = new Pic();
pic.x = i * spacing;
pic.y = yLoc;
picContainer.addChild(pic);
}
the logic is pretty simple, and i don't know why i couldn't get it my self, because i drew diagrams that say exactly this logic. however, i must not have put the numbers in the right places or i wouldn't have had to ask, would i ;P
BONUS CONTENT!
as an added bonus (if anyone finds this thread looking for answers..)
you could also have the 'pic's fan out from the center point (but they'd still be in order of left to right) by using this code:
var picContainer:PicContainer = new PicContainer();
picContainer.x = stage.stageWidth / 2 - picContainer.width / 2;
picContainer.y = stage.stageHeight / 2 - picContainer.height / 2;
addChild(picContainer);
var totalPics:int = 5;
var pic:Pic = new Pic(); //make an instance just to get its width
var padding:Number = (picContainer.width - (pic.width * totalPics)) / (totalPics + 1);
for(var i:int = 0; i < totalPics; i++) {
pic = new Pic();
pic.x = padding + i * (pic.width + padding);
pic.y = picContainer.height / 2 - pic.height / 2;
picContainer.addChild(pic);
}
Try it out, these make for great thumbnail dock engines!
First Edit: Well, there is some progress thanks to TDI but not a complete solution.
you see, the problem remains that the movie clips do not squash completely into the container, the last one or two are left sticking out.
example:
my revised code looks like this:
var newPicContainer:picContainer = new picContainer();
var newPic:pic;
var picwidth:int = 100;
var amountofpics:int = 22;
var i:int;
//add a container
addChild(newPicContainer);
//center our container
newPicContainer.x = (stage.stageWidth/2)- (newPicContainer.width/2);
newPicContainer.y = (stage.stageHeight/2)- (newPicContainer.height/2);
var totalpicwidth:int = picwidth*amountofpics;
var totalpadding:int = newPicContainer.width - totalpicwidth;
var paddingbetween:int = (totalpadding / amountofpics);
for (i = 0; i < amountofpics; ++i)
{
//make a new mc called newPic(and i's value) eg. newPic1
this['newPic' + i] = new pic();
this['newPic' + i].width = picwidth;
//add our pic to the container
newPicContainer.addChild(this['newPic' + i]);
//set the new pics X
if (i != 0)
{
// if i is not 0, set newpic(i)s x to the previous pic plus the previous pics width and add our dynamic padding
this['newPic' + i].x = this['newPic' + (i-1)].x + picwidth + paddingbetween;
}
else
{
this['newPic' + i].x = 0;
}
}
thanks again to anyone in advance!
Original Post:
Hello, First time posting here. I hope I'm not getting anything wrong . my problem is as follows:
I've got a pretty basic for loop that creates a 'thumbnail' and puts it next to the previous one (With a little padding) inside a containing movie clip.
var newPicContainer:picContainer = new picContainer();
var newPic:pic;
var amount:int = 9;
var i:int;
//Add our container
addChild(newPicContainer);
//center our container
newPicContainer.x = (stage.stageWidth/2)- (newPicContainer.width/2);
newPicContainer.y = (stage.stageHeight/2)- (newPicContainer.height/2);
for (i = 0; i < amount; ++i)
{
newPic = new pic();
newPicContainer.addChild(newPic);
//just so i know it's adding them..
trace(newPic.thisOne);
newPic.thisOne = i;
// set this one to its self (+5 for padding..) Times, the amount already placed.
newPic.x = (newPic.width+5) *i;
}
I'm wondering if there is some equation or 'magic math' that I can use to figure out what the length of the container is and have the 'thumbnails' be added relative to that number. basically squashing the thumbnails against each other to make them all fit inside..
something along the lines of:
newPic.x = (newPic.width *i) - stuff here to make it know not to go past the containing width;
I must admit i'm not too great with math and so this part of coding escapes me..
thanks to any takers in advance..
you can get the length of your container by either calling its width property explicitly:
//Container Width
newPicContainer.width;
or the newContainer is also the parent of the added pics:
//Container Width
newPic.parent.width;
then you need to get the total length occupied by you pics:
var arrayOfPics:array = [pic1, pic2, pic3, pic4, pic5];
var picsWidth:Number;
for each (var element:pic in arrayOfPics)
picsWidth =+ element.width;
after than you can subtract the length of the total pics from the container to know your available padding for separation:
var totalPadding:Number = newPicContainer.width - picsWidth;
now you can determine how much padding you can afford between the pics and both sides of the container by dividing the totalPadding by the number of pics, and add an extra padding for the end.
var padding:Number = totalPadding / arrayOfPics.length + 1;
now you can simply add your pics by including the padding
for (var i:int = 0; i < arrayOfPics.length; i++)
{
newPicContainer.addChild(arrayOfPics[i]);
(i == 0) ? arrayOfPics[i].x = padding : arrayOfPics[i].x = arrayOfPics[i - 1].x + arrayOfPics[i - 1].width + padding;
}
Try this...
//maximum available length
var maxLength:int;
// a single thumbnail width
var picWidth:int = 100;
// total number of pics in a container
var maxNumPics:int;
// as long as the maximum available length
// is inferior to the container length
// add a new thumbnail
while( maxLength < newPicContainer.length - 100 )
{
maxLength += 100;
maxNumPics += 1;
}
// calculate the amount of available padding.
var padding:Number = ( newPicContainer.length - maxLength )/ maxNumPics;
//add your thumbs
var picX:int;
for( var i:int ; i < maxNumPics ; ++i )
{
var newPic:Pic = new Pic();
newPic.x = picX;
picX += padding + picWidth;
newPicContainer.addChild( newPic );
}
I'd recommend you look at using the Flex framework (it's a Flash framework), it will make building this sort of view much easier.
You can set a container's layout property, so that items are placed in horizontal, vertical or tiled layouts, and then just add items to the container.
For more info on Flex look here
For info on Flex Layouts