Dynamically create one or more borders around image - javascript

Need to have an unknown number of borders around an image, already made a solution, just want to know whether there are better possibilities.
I have a website with many photo shows. Each show is a JSON file in which each photo is an array entry in that file, e.g.
{
"filename": "02.jpg",
"short": "text under thumbnail",
"title": "A description or explanation above the photo"
}
Normally the photos get a small white border, but sometimes I want to show the location of that photo so in the JSON file I have this additional info for that photo:
"latitude": "51 02 39.73 N",
"longitude": "114 03 47.37 W",
I put a yellow border around the photo as indication that there is location info, so a click on the photo or one of the coordinates (or keyboard M) opens googleMaps to show the location.
Recently I added some videos to some of the photos, so double click the photo (or keyboard V) to start that video. I put a turquoise border around the photo to indicate that there is a video.
In the JSON file it looks like this:
"video": "myvideo.mp4",
Of course all of a sudden I had a photo with location info AND a video, so now I needed 2 borders: a yellow one and a turquoise one...
To complicate matters, I once in a while have a photo with a soundclip and a green border, defined in the JSON file as:
"sound": "myclip.mp3",
thus a photo with 3 different colored borders could also happen.
After reading some stackoverflow box-shadow articles, I came up with the following solution in Javascript to create 1,2,3 or even more borders:
var borderStyle = "";
if (elt.longitude) {
borderStyle = "coordbrdr";
}
if (elt.sound) {
borderStyle += "soundbrdr";
}
if (elt.video) {
borderStyle += "videobrdr";
}
if (borderStyle == "") {borderStyle = "normalbrdr";}
$(elt.imgHTML).attr('class', borderStyle);
and the accompanying css:
.normalbrdr {border:6px solid white;}
.coordbrdr {border:6px solid yellow; cursor:pointer;}
.soundbrdr {border:6px solid lightgreen; cursor:pointer;}
.videobrdr {border:6px solid turquoise; cursor:pointer;}
.coordbrdrsoundbrdr {box-shadow: 0 0 0 6px yellow, 0 0 0 12px green; cursor:pointer}
.coordbrdrvideobrdr {box-shadow: 0 0 0 6px yellow, 0 0 0 12px turquoise; cursor:pointer}
.coordbrdrsoundbrdrvideobrdr {box-shadow: 0 0 0 6px yellow, 0 0 0 12px green, 0 0 0 18px turquoise; cursor:pointer}
.soundbrdrvideobrdr {box-shadow: 0 0 0 6px green, 0 0 0 12px turquoise; cursor:pointer}
So in this way I managed to build the various class values.
My question: Would there be a shorter, or better method to dynamically create different borders ??

Related

Style text track using videojs

Is there a way to style videojs captions?
The nativeTextTracks is set to false and I can see that the plugin is rendering his own caption.
A new div created for each row of text and the style of that div is inline.
I tried to send settings to the player init but videojs documentation is a bit lacking in this respect.
var player = videojs('my_video', {
'html5': {
nativeTextTracks: false
},
textTracks: {
??? maybe something here ???
},
'fluid': true,
controlBar: {
children: {
'playToggle':{},
'currentTimeDisplay':{},
'timeDivider':{},
'durationDisplay':{},
'progressControl':{},
'fullscreenToggle':{},
}
}
});
This is an undocumented feature, but I managed to find it out by reading the TextTrackSettings source code. Basically, you need to call setValues on the settings of your player, and then to apply the settings with updateDisplay:
let player = videojs('my_video');
player.ready(function(){
var settings = this.textTrackSettings;
settings.setValues({
"backgroundColor": "#000",
"backgroundOpacity": "0",
"edgeStyle": "uniform",
});
settings.updateDisplay();
});
I've done with the css selector >.
This will override the default black background and add a black border around the letters:
.vjs-text-track-cue > div {
background: transparent!important;
text-shadow: 2px 0 black, -2px 0 black, 0 2px black, 0 -2px black,
1px 1px black, -1px -1px black, 1px -1px black, -1px 1px black;
}
I have also faced the same issue when I was needed to add padding. I have investigated a lot and found that cue can only work on following properties:
color
opacity
visibility
text-decoration
text-shadow
background
outline
font
line-height
white-space
For example :
Ex : 1
video::cue {
color:#ccc;
}
Ex : 2
video::cue {
outline:5px solid gray;
}
So we just need to apply css for video::cue to play with Caption Track Text in any Video Player

Make a div that go somewhat curved

This question have been asked a billion times I think, but just another case.
How to make this with HTML / CSS (and, if no other option, JS - I'm thinking of canvas or SVG) :
Notes : the div should be able to contain a scrolling background image on the whole green part. And this should work on IE9+ and common mobile devices (default browser). Also, the space around the shape needs to stay transparent (no white element to create the rounded shape can be used)
What's the better option ?
CSS Implementation
You can create a border shape within a container and hide the unwanted parts. I have used view port sized units to be scalable. It can be further improved to your requirement by manipulating with the values.
body {
background: #F5F5F5;
}
.container {
height: 70vh;
overflow: hidden;
display: inline-block;
width: 30vh;
background: white;
margin: 0 10px;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);
}
.curve {
background: transparent;
border: 20vh solid #7cc576;
border-radius: 35%;
height: 100vh;
transform: translateY(-20vh);
width: 50vh;
}
.container-left-curved {
transform: rotateY(180deg);
}
.container-right-curved {
transform: rotateY(0deg);
}
<div class="container container-left-curved">
<div class="curve">
</div>
</div>
<div class="container container-right-curved">
<div class="curve">
</div>
</div>
SVG Implementation
I saved your image and generated the optimized SVG code through Inkscape editor. This looks a lot better than a pure CSS solution.
body {
background: lightgray;
}
<svg height="300px" width="200px" version="1.1" viewBox="0 0 492 746.00001" fill="#000">
<g id="layer1" transform="translate(-119.71 -187.93)">
<path id="path3349" d="m189.71 620.93c0-206.67-0.33548-311-1-311-0.55 0-1-2.25-1-5s-0.45-5-1-5-1-1.9984-1-4.441c0-2.4425-0.45-4.7191-1-5.059-0.55-0.33992-1-1.9415-1-3.559s-0.45-2.941-1-2.941-1-1.0984-1-2.441c0-1.3425-0.45-2.7191-1-3.059-0.55-0.33992-1-1.9415-1-3.559s-0.45-2.941-1-2.941-1-0.88631-1-1.9696-0.9-3.572-2-5.5304c-1.1-1.9585-2-4.2222-2-5.0304 0-0.80827-0.45-1.4696-1-1.4696s-1-0.9-1-2-0.45-2-1-2-1-0.9-1-2-0.45-2-1-2-1-0.9-1-2-0.45-2-1-2-1-0.9-1-2-0.45-2-1-2-1-0.59015-1-1.3114c0-0.72129-0.9-2.2775-2-3.4582s-2-2.7323-2-3.448-0.9-1.8633-2-2.5503c-1.1-0.68696-2-2.0459-2-3.0198 0-0.97393-0.9-2.4195-2-3.2123-1.1-0.79284-2.0021-1.9047-2.0046-2.4708-0.002-0.56608-1.3525-2.4673-3-4.225-1.6474-1.7577-3-3.5577-3.0056-4-0.006-0.44232-2.2557-3.1613-5-6.0422-2.7444-2.8809-4.9897-5.6545-4.9897-6.1636 0-0.50907-2.534-3.4395-5.6312-6.512l-5.6312-5.5864h207.31 207.31l11.311 11.25c6.2212 6.1875 11.317 11.7 11.325 12.25 0.007 0.55 1.788 2.8 3.9571 5s3.9659 4.7875 3.9929 5.75 0.52562 1.75 1.1081 1.75c0.58246 0 0.73793 0.51953 0.34549 1.1545-0.39555 0.64-0.27852 0.88566 0.2626 0.55123 0.98336-0.60775 4.3329 2.601 4.3329 4.1507 0 0.45847 0.9 1.6481 2 2.6436 1.1 0.99549 2 2.6402 2 3.655s0.45 1.845 1 1.845 1 0.59015 1 1.3114c0 0.72129 0.9 2.2775 2 3.4582s2 2.8406 2 3.6886c0 0.84799 0.45 1.5418 1 1.5418s1 0.9 1 2 0.45 2 1 2 1 0.9 1 2 0.45 2 1 2 1 0.9 1 2 0.47656 2 1.059 2c0.58246 0 0.81241 0.39901 0.51101 0.88669-0.30141 0.48768 0.12204 1.4428 0.94098 2.1224 0.81894 0.67966 1.489 2.0806 1.489 3.1133s0.45 1.8776 1 1.8776 1 1.35 1 3 0.45 3 1 3 1 1.1516 1 2.559c0 1.4514 0.43284 2.2915 1 1.941 0.58342-0.36057 1 0.65628 1 2.441 0 1.6825 0.45 3.059 1 3.059s1 1.8 1 4 0.45 4 1 4 1 1.8 1 4 0.45 4 1 4 1 2.25 1 5 0.45 5 1 5c0.66452 0 1 104 1 310v310h-210-210v-311z"
fill="#7ac474" />
</g>
</svg>
Finally, after looking for the good way to achieve that, here's my notes:
1. RaphaelJS
I think RaphaelJS makes it easy and offers extended compatibility (I tested on IE8 and IE7, it works, even if I don't need it) and easier manipulation.
Here's a live example : http://jsfiddle.net/bkfssykp/
As you can see, this is somewhat a SVG based solution :
paper.path("M0,0h259.478c0,0,42.939,36.419,42.939,88.694 c0,132.905,0,368.306,0,368.306H42.939c0,0,0-235.587,0-368.464C42.939,36.345,0,0,0,0z");
I just pasted the code of my svg shape directly into it. Now, I can play with it : animation, modification, etc.
2. SVG clip-path
My first attempt was an SVG image with a SVG clip-path, as said in the article mentionned by #Deepak : https://css-tricks.com/clipping-masking-css/
Here's a live example : http://jsfiddle.net/xptycnkg/3/
Still SVG : this looks like CSS clip-path, but applied on SVG element. Works on IE9.

Animated Ripples using jquery

I would like to create an animated visualisation (responsive if possible) where the ripples are originating from a central point and when those ripples reach outer nodes in a circle, those nodes create similar ripples of variable size.
So far, I have found these libraries:
https://github.com/mbostock/d3/wiki/Gallery
http://flare.prefuse.org/
But none of them seem to have exactly what I am after and they also seem like an overkill.
What is be the best approach to achieve this?
P.S: I am open to using Adobe's Edge Animate if it offers an easy solution since I create a lot of data visualisations for the new company I am working with.
I think the best approach would be either to use some CSS animations or possibly to use HTML5 canvas and JavaScript with requestAnimationFrame
here is an example of creating a ripple effect with CSS animations on CodePen
.ripple:before,.ripple:after {
content:'';
position:absolute;
}
.ripple:before {
-webkit-animation-delay:.2s;-moz-animation-delay:.2s;top:5px;left:25px;
}
.ripple:after {
-webkit-animation-delay:.8s;-moz-animation-delay:.8s;top:25px;left:0;
}
#-webkit-keyframes rip
{
0% {
box-shadow:0 0 0 0 transparent,
0 0 0 0 transparent,
0 0 0 0 transparent,
0 0 0 0 transparent;
}
5% {
box-shadow:0 0 0 0 #45c2c5,
0 0 0 0 rgba(255,255,255,0.4),
0 0 0 0 #45c2c5,
0 0 0 0 rgba(0,0,0,0.08);
}
100% {
box-shadow:0 0 40px 200px #45c2c5,
0 0 10px 210px transparent,
0 0 30px 220px #45c2c5,
0 0 5px 230px transparent;
}
}

How to put css code in javascript

i want to add a css code in a javascript function, this is the function that I have
function test1() {
document.getElementById("p1").innerHTML = "test";
}
and i want this css code in it
p1 {
text-shadow: 0 1px 0 #ccc,
0 2px 0 #c9c9c9,
0 3px 0 #bbb,
0 4px 0 #b9b9b9,
0 5px 0 #aaa,
0 6px 1px rgba(0,0,0,.1),
0 0 5px rgba(0,0,0,.1),
0 1px 3px rgba(0,0,0,.3),
0 3px 5px rgba(0,0,0,.2),
0 5px 10px rgba(0,0,0,.25),
0 10px 10px rgba(0,0,0,.2),
0 20px 20px rgba(0,0,0,.15);
}
-
Basically, I have a paragraph (p1) and I use javascript because I made a button which onclick="test1()" so when it clicks it it will change the text to the one I put which is "test", but I don't want the whole paragraph to have the shadows, I only want the 'test' to have it, hope I was clear enough!
thank you
Try this,
<p id="p1">
This is a <span>test.</span>
</p>
<button id="button1">Button</button>
From what I understand from your question, you want the function to add a shadow to JUST the word test. In that case using a <span> element might be the easiest way to achieve that. .innerHTML() does not select the text inside the <p> instead it sets the text so you would have been left with an element with just the word 'test' inside.
And the javascript below can be modified to your liking, but the basic concept is there.
var button = document.getElementById("button1");
button.addEventListener("click", function(){
var p = document.getElementById("p1");
var test = p.getElementsByTagName("span")[0];
test.style.textShadow = "5px 5px 1px #ff0000,10px 10px 1px #0000ff";
});
Fiddle: https://jsfiddle.net/0Lhc4tav/
Something like that ?
document.getElementById("p1").style.textShadow = "5px 5px 1px #ff0000,10px 10px 1px #0000ff";
Found here : http://www.w3schools.com/jsref/prop_style_textshadow.asp
It's hard to say, you should really post your HTML as well so we can better understand it. You can also try this if you can use jQuery:
$('.p1').css('text-shadow','0px 5px...etc');
But I agree that you may not need to do this via JS.

Make Div Smallest Possible Width

The Fiddle: http://jsfiddle.net/GosuWhite/sXgAY/
You input numbers separated by any characters and it calculates some summary statistics. The summary statistics are output in area designated for the calculator in this divs:
<div id="solWrap">
<div id="solTitles"></div>
<div id="solStats"></div>
</div>
So You'd basically have something like this:
Sample Variance: 12.212
Population Variace: 12.291
I wanted to essentially center these statistics in the calculator area, but I don't know the width, so I used this:
solWrap.offsetWidth = outputTitles.offsetWidth + outputStats.offsetWidth + "px";
Cool, should work right? It turns out it doesn't and that's because outputStats is HIGHLY greedy and uses more width than it needs, and in fact, it actually uses all the remaining width available.
What can I do? Don't throw Jquery at me. Libraries are nice but I prefer sweet, sweet vanilla.
Edit: This is what I want: http://i.imgur.com/l6l4XD5.jpg
I want that effect, but that was achieved through actually literally setting the width of the solWrap div. Since this calculator is dynamic, I want the width dynamically generated.
New Edit: No one has answered correctly yet.
Here is what is going on:
JavaScript is generating content inside two divs:
Sample Variance: 12.212
Population Variace: 12.291
Div 1 will contain "Sample Variance Populati..."
And the other div will contain the data.
These are inside of the calculator text area which has a width of 400px and are both being displayed as inline-blocks.
The thing is when JavaScript generates this content inside of the divs, it does it corrently for the "sample variance...". It sets the width to the smallest possible value it can have.
But when JavaScript generates the content inside the div for the numbers, it sets the width way bigger than it needs to be and in fact takes up the rest of the area inside the calculator div.
How can I force the div that contains the numbers to be as small as it can?]
SOLUTION: I found a solution. Instead of display: inline-block, I used display: table and set the inner divs to display:table cell and it worked.
Try this:
Live demo
html
<form id="calcForm">
<div id="outercalcTextArea">
<div id="calcTextArea" contenteditable="true">
</div>
</div>
<div id="calcButton"><center><button id="submit" type="submit">Submit</button></center></div>
</form>
css
#outercalcTextArea{
background: none repeat scroll 0 0 #FFFFFF;
border: 1px solid #C9C9C9;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15) inset, -5px -5px 0 0 #F5F5F6, 5px 5px 0 0 #F5F5F6, 5px 0 0 0 #F5F5F6, 0 5px 0 0 #F5F5F6, 5px -5px 0 0 #F5F5F6, -5px 5px 0 0 #F5F5F6;
border-radius: 2px 2px 2px 2px;
min-width: 400px;
width:auto;
font-size:12px;
height:200px;
white-space:nowrap;
}
#calcTextArea {
width:100%;
height:100%;
padding: 8px;
padding-left:21%;
box-sizing:border-box;
}
html
<div id="solWrap" class='parentDiv'>
....Child divs
css
.parentDiv {
width: 100%;
text-align:center;
}
.chilDiv {
width: 90%;
text-align:left;
margin-left:auto;
margin-right:auto;
}
I apologize if I'm way off here but why can't you use a table?
<table id="stats_table">
<tbody id="stats_table_body">
<tr>
<td class="title">Sample Variance:</td>
<td class="value">12.212</td>
</tr>
<tr>
<td class="title">Population Variace:</td>
<td class="value">12.291</td>
</tr>
</tbody>
</table>
If you need to create though javascript:
var myStats = [{title: 'Sample Variance', value: 12.212},
{title: 'Population Variace', value: 12.291}];
function makeStatsTable(stats){
var table = document.getElementById("stats_table_body");
stats.forEach(function(stat){
var tr = document.createElement("tr");
var title = document.createElement("td");
title.className = "title";
title.textContent = stat.title;
tr.appendChild( title );
var value = document.createElement("td");
value.className = "value";
value.textContent = stat.value;
tr.appendChild( value );
table.appendChild( tr );
});
}
makeStatsTable( myStats );
Here is a jsfiddle: http://jsfiddle.net/xiondark2008/8X7MZ/

Categories