I am creating a CSS editor using Javascript. I would like the User to be able to change the attributes of the CSS box-shadow. I imagine the function would look something like this:
var box = document.getElementById("boxDiv");
var h-offset; //= getUserInput (= document.getElementById("textareaID").value;)
var v-offset; //= getUserInput
var blur; //= getUserInput
var spread; //= getUserInput
var color; //= getUserInput
box.style.boxShadow =; //(h-offset,v-offset,blur,spread,color)
I am not sure how to format the String in a way the CSS box-shadow can understand it.
Thanks!
You can just concatenate the strings together. Keep in mind, that you need to validate the user input first. Otherwise, the box-shadow is not properly shown, if the user inserts a wrong value.
box.style.boxShadow = offsetX + ' ' + offsetY + ' ' + blurRadius + ' ' + spreadRadius + ' ' + color;
With ES6, you can also use template strings:
box.style.boxShadow = `${offsetX} ${offsetY} ${blurRadius} ${spreadRadius} ${color}`;
Here is a live example:
function apply() {
var box = document.getElementById('box');
var offsetX = document.getElementById('offsetX').value;
var offsetY = document.getElementById('offsetY').value;
var blurRadius = document.getElementById('blurRadius').value;
var spreadRadius = document.getElementById('spreadRadius').value;
var color = document.getElementById('color').value;
box.style.boxShadow = offsetX + ' ' + offsetY + ' ' + blurRadius + ' ' + spreadRadius + ' ' + color;
}
#box {
width: 100px;
height: 100px;
background: #f2f2f2;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
input {
display: block;
}
<div id="box"></div>
<input id="offsetX" placeholder="offsetX" />
<input id="offsetY" placeholder="offsetY" />
<input id="blurRadius" placeholder="blurRadius" />
<input id="spreadRadius" placeholder="spreadRadius" />
<input id="color" placeholder="color" />
<button onclick="apply()">Apply</button>
Thanks. I realized that I was not formatting the String correctly.
What I was coding:
box.style.boxShadow = String(h-offset + v-offset + blur + spread + color);
What I needed to code:
box.style.boxShadow = String(h-offset + " " + v-offset + " " + blur + " " + spread + " " + color);
Almost a 'Well Duh' moment XD
var first = "10px";
var second = "20px";
var third = "red";
$("#bshadow_jquery").css('box-shadow', first + " " + second + " " + third);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<head>
<style>
#bshadow_css {
border: 1px solid;
padding: 10px;
box-shadow: 5px 10px;
}
#bshadow_jquery {
border: 1px solid;
padding: 10px;
}
</style>
</head>
<body>
<h2>box-shadow css: 5px 5px #990000:</h2>
<div id="bshadow_css">
<p>this is a block-shadow by css</p>
</div>
<hr style="margin: 50px 0px">
<h2>box-shadow jquery: 5px 5px #990000:</h2>
<div id="bshadow_jquery">
<p>this is a block-shadow by JQuery</p>
</div>
</body>
</html>
Related
Attempting to transform an images scale (zoom) BUT maintain it inside it's parents left and top div so only trying to transform it down and to the right. Setting the transform orgin does not seem to work, what am I missing?
the following code zooms the image on each button click, but pushes the left and top out of the parent div.
$('element').click(function{
$('#element').css({'transform':'scale(' + scale + ')' });
$('#element').css({'transform-orgin':'top left'});
})
<div style "max-wdith:1080px; height: 700px; overflow-x:scroll; overflow-y:scroll">
<img id="element" src=" src="https://images.techhive.com/images/article/2017/03/castle_moat-100714623-large.jpg" " class="img-flud">
</div>
You can try the below code
var x = 400 + 'px';
var y = 300 + 'px';
$('#element').css({
'transform-origin': x + ' ' + y + ' 0px',
'-webkit-transform-origin': x + ' ' + y + ' 0px'
});
Updated answer!
const btn = document.querySelector('button');
function zoomIn(e) {
const scale = 0.1;
const img = document.querySelector('#my-image');
$('#my-image').css({transformOrigin: "top left", transform: 'scale(' + scale + ')'});
}
btn.addEventListener('click', zoomIn);
div {
width: 400px;
height: 400px;
border: 1px solid black;
overflow: hidden;
float: left;
}
div > img {
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<img id="my-image" src="https://images.techhive.com/images/article/2017/03/castle_moat-100714623-large.jpg" />
</div>
<button>Zoom In</button>
$('#cypher-branding-letter-spacing').change(function(e) {
$('#cypher-branding-main-edit-right-txt-text').css('letter-spacing', $('#cypher-branding-letter-spacing').val() + 'px');
});
//add text to design
$(document).on('click', '#cypher-branding-btn-add-to-design-text', function() {
//remove the canvas border before creating the image, then add it back
$("#cypher-branding-main-edit-right-txt-text-wrapper").css('border', 'none');
html2canvas($("#cypher-branding-main-edit-right-txt-text-wrapper"), {
onrendered: function(canvas) {
var id = guid();
var img = new Image();
img = $('#cypher-branding-text-temp-img').find('img')[0];
img.src = canvas.toDataURL('image/png');
var w = canvas.width;
var h = canvas.height;
//var elem = $('<div id="cypher_container_' + id + '" class="cypher-container"><div id="cypher_container_inner_' + id + '" class="tooltip"><img id="cypher_container_img' + id + '" onclick=showLogoCommands("' + id + '"); src="' + img.src + '" class="cypher-blocks" style="width:' + w + 'px; height:' + h + 'px" /><span class="tooltiptext"><a href="#" onclick=rotatePlus("' + id + '");>Rotate +</a><a href="#" onclick=rotateMinus("' + id + '");>Rotate -</a><a href="#" onclick=removeFromDesign("' + id + '");>Remove</a><br /></span></div></div>');
var elem = $('<div id="cypher_container_' + id + '" class="cypher-container" style="width:100px;"><div id="cypher_container_inner_' + id + '" class="tooltip"><span class="tooltiptext"><a href="#" onclick=removeFromDesign("' + id + '");>x</a><br /></span><img id="cypher_container_img' + id + '" onclick=showLogoCommands("' + id + '"); src="' + img.src + '" class="cypher-blocks" style="width:' + w + 'px; height:' + h + 'px" /></div></div>');
$('.cypher-block').append(elem);
elem.draggable({
cancel: ".ui-rotatable-handle"
});
//rotate handles
var nw = $("<div>", {
class: "ui-rotatable-handle"
});
var ne = nw.clone();
var se = nw.clone();
elem.find('.cypher-blocks:first').resizable();
elem.rotatable();
elem.addClass("ui-rotatable-handle-sw");
elem.addClass("ui-rotatable-handle-nw");
elem.addClass("ui-rotatable-handle-ne");
elem.addClass("ui-rotatable-handle-se");
// Assign handles to box
elem.find('.cypher-blocks:first').append(nw, ne, se);
elem.find("div[class*='ui-rotatable-handle-']").bind("mousedown", function(e) {
elem.find('.cypher-blocks:first').rotatable("instance").startRotate(e);
});
}
});
//$("#cypher-branding-main-edit-right-txt-text-wrapper").css('border', '1px dashed #777');
});
.cypher-blocks {
display: inline-block;
width: initial;
cursor: move;
}
.cypher-block {
padding: 10px;
border: none;
margin: 0px;
margin-left: auto;
margin-right: auto;
overflow-x: hidden;
overflow-y: hidden;
background: transparent;
height: 100%;
width: 100%;
}
.cypher-block .ui-resizable-handle,
.cypher-block .ui-resizable-se {
border: none;
background-color: none;
color: none;
background-image: url("")
}
.cypher-block .ui-resizable-handle {}
.cypher-block .ui-rotatable-handle {
background-image: url("")
}
.cypher-block:hover .ui-resizable-handle,
.cypher-block:hover .ui-resizable-se {
border: 1px dotted #fff;
background-color: #f00;
color: #fff;
resize: both;
}
.cypher-block:hover .ui-rotatable-handle {
background: url('cypher-brand/rotate.png');
background-repeat: no-repeat;
background-size: 100% 100%;
height: 16px;
width: 16px;
position: absolute;
}
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.ui.rotatable/1.0.1/jquery.ui.rotatable.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div class="cypher-block" style="margin-top:20px;"></div>
<div id="cypher-branding-main-edit-right-txt-text-wrapper" style="width:300px;height:170px;padding:0;">
<div id="cypher-branding-main-edit-right-txt-text">Sample Text</div>
</div>
<input type="number" id="cypher-branding-letter-spacing" class="cypher-branding-text-input" value="0" />
<span id="cypher-branding-btn-add-to-design-text" class="cypher-branding-input-btn cypher-branding-command-padding">Add to Product Design</span>
I'm trying to create an image from text, then add it to another div.
The issue is with 'letter-spacing' CSS style.
After applying the CSS, then creating an image using html2canvas, the CSS on the image does not show.
Just to note, all other CSS styles I apply to the div shows, like line-spacing, color, font etc. It's only letter-spacing that is the issue.
I've added a snippet, however it's giving me a 'Script error' this is only when adding the external scripts. Not sure yet on how to resolve it as I'm new to snippets.
You need to set letterRendering:true
html2canvas($("#cypher-branding-main-edit-right-txt-text-wrapper"), {
onrendered: function(canvas) {
var id = guid();
var img = new Image();
img = $('#cypher-branding-text-temp-img').find('img')[0];
img.src = canvas.toDataURL('image/png');
var w = canvas.width;
var h = canvas.height;
//var elem = $('<div id="cypher_container_' + id + '" class="cypher-container"><div id="cypher_container_inner_' + id + '" class="tooltip"><img id="cypher_container_img' + id + '" onclick=showLogoCommands("' + id + '"); src="' + img.src + '" class="cypher-blocks" style="width:' + w + 'px; height:' + h + 'px" /><span class="tooltiptext"><a href="#" onclick=rotatePlus("' + id + '");>Rotate +</a><a href="#" onclick=rotateMinus("' + id + '");>Rotate -</a><a href="#" onclick=removeFromDesign("' + id + '");>Remove</a><br /></span></div></div>');
var elem = $('<div id="cypher_container_' + id + '" class="cypher-container" style="width:100px;"><div id="cypher_container_inner_' + id + '" class="tooltip"><span class="tooltiptext"><a href="#" onclick=removeFromDesign("' + id + '");>x</a><br /></span><img id="cypher_container_img' + id + '" onclick=showLogoCommands("' + id + '"); src="' + img.src + '" class="cypher-blocks" style="width:' + w + 'px; height:' + h + 'px" /></div></div>');
$('.cypher-block').append(elem);
elem.draggable({
cancel: ".ui-rotatable-handle"
});
//rotate handles
var nw = $("<div>", {
class: "ui-rotatable-handle"
});
var ne = nw.clone();
var se = nw.clone();
elem.find('.cypher-blocks:first').resizable();
elem.rotatable();
elem.addClass("ui-rotatable-handle-sw");
elem.addClass("ui-rotatable-handle-nw");
elem.addClass("ui-rotatable-handle-ne");
elem.addClass("ui-rotatable-handle-se");
// Assign handles to box
elem.find('.cypher-blocks:first').append(nw, ne, se);
elem.find("div[class*='ui-rotatable-handle-']").bind("mousedown", function(e) {
elem.find('.cypher-blocks:first').rotatable("instance").startRotate(e);
});
},
letterRendering:true
});
That should work I think.
Based on this Letter-spacing isn't supported
I create via a String some DOM-Elements and assign it via innerHTML to a div.
Now I need a flexible width of the span element (span_homebase). What I experience is that sometimes (for me it looks randomly) it returns other width than expected. I need the width of this span element because after this in the same line there is an Information Button but the width of the span could be different. So I use the width of span element as margin for the information button. Code is as follows. I searched for a async handler of innerHTML but in another post somebody said that it is not required because it is assigned instantly.
Are there any thoughts what to try? Because the information is now sometimes on the right place and sometimes not.
string = string + "<span id ='span_homebase'>" + homebaseCity + "</span>";
string = string + "<div class='section-end'></div>";
element.innerHTML = string;
var marginInfoHomebase = document.getElementById('span_homebase').offsetWidth + 20;
document.getElementById("information_button_homebase").style.margin = "5px 0 0 " + marginInfoHomebase + "px";
Now if I open the respective site for me sometimes the marginInfoHomebase sometimes returns 108 and sometimes 183 even if the same value is assigned to span element. Very strange. Any thoughts?
EDIT:
Working Example:
function createHomeSettingsView(settingsA){
var element = document.getElementById("table-settings");
var string = "";
for(var i = 0; i < settingsA.length; i++){
for(var z = 0; z < settingsA[i].length; z++){
if(i == 1){
//Notification buttons
if(z == 1){
//homebase setting
if(window.localStorage.getItem("switch_homebase") == 1){
//homebase on
var homebaseCity = settingsA[i][z] + ": " + window.localStorage.getItem("homebase_loc");
string = string + " \
<div class='row' style='height:100px;' id='settings-sec-"+ i +"-row-" + z +"'> \
<div class='text'> \
<span id='span_homebase'>" + homebaseCity + "</span> \
</div> \
<div onClick='homebaseInfoClick();' class='information_button' id='information_button_homebase'></div>\
<div id='handleAutoSwitcherHomebase'></div>\
<div id='showRadiusRangeHomebase'>Radius: 30km</div>\
<input class='sliders' id='changeRadiusRangeHomebase' type='range' min='5' max='100' step='5' oninput='handleChangeHomebase(this.value)' onchange='handleInputHomebase(this.value)' >\
</div>";
}
else{
//homebase off
string = string + " \
<div class='row' id='settings-sec-"+ i +"-row-" + z +"'> \
<div class='text'>\
<span id='span_homebase'>" + settingsA[i][z] + "</span> \
</div> \
<div onClick='homebaseInfoClick();' class='information_button' id='information_button_homebase'></div>\
<div id='handleAutoSwitcherHomebase'></div>\
</div>";
}
}
}
}
}
element.innerHTML = string;
var marginInfoHomebase = document.getElementById("span_homebase").offsetWidth + 25;
var marginText = "5px 0 0 " + marginInfoHomebase + "px";
console.log("Span: " + marginInfoHomebase);
document.getElementById("information_button_homebase").style.margin = marginText;
}
CSS:
.container .table-settings{
top: 64px;
position: absolute;
padding:0;
left: 0;
right: 0;
bottom:0;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
background-color: #ECEBF3;
}
.container .table-settings .row{
background-color: white;
padding-top: 14px;
height:50px;
border-bottom: 1px solid LightGray;
}
.container .table-settings .row .text{
margin-left: 15px;
color: black;
float: left;
}
#span_homebase{
display: inline-block;
}
To get an inline element's width use getBoundingClientRect method:
var mySpan = document.getElementById("mySpan");
var spanWidth = mySpan.getBoundingClientRect().width;
var spanHeight = mySpan.getBoundingClientRect().height;
By default a span element has no dimension because its CSS display property is inline.
If you want to give it a width, you should change that property to inline-block.
<style>
span {
display: inline-block ;
}
</style>
Now you can play with its dimensions.
I am building a demo of a lotto site where a user is presented with one section full of the balls and a second section that will fill up with his/her selections.
What I am trying to do is create a jQuery function that will run when a user clicks on a ball, this function must retrieve the number of the ball that was clicked as well as the color of the ball (background-image) and then set the number and the background-image to the next available ball.
Here is a jsFiddle: http://jsfiddle.net/8kq5p6gb/1/
This is my jQuery function, it stores the number and background of the clicked ball and then tries to find the next available ball open and applies that text and background to it but it currently does not work. When I click on a ball I get this error :
Uncaught Error: Syntax error, unrecognized expression: [object Object] a:nth-child(1)
For Code :
$(document).ready(function () {
var line_counter = 1;
var number_counter = 1;
$('.draw-selection-wrapper.choice .draw-number').click(function (e) {
event.preventDefault(e);
var number = $(this).text(); ;
var background = $(this).css('background-image');
var row = $('.draw-selection-wrapper.selections div:nth-child(' + line_counter + ')');
var link = $(row + ' a:nth-child(' + number_counter + ')');
link.text(number);
link.css('background-image', background);
number_counter = number_counter + 1;
if (number_counter == 8) {
line_counter = line_counter + 1;
number_counter = 1;
}
});
});
Here is my HTML:
<div class="draw-numbers-outer-wrapper">
<div class="draw-selection-wrapper choice">
<div class="draw-number-row one">
1
2
3
4
5
6
7
</div>
<div class="draw-number-row two">
8
9
10
11
12
13
14
</div>
</div>
<div class="draw-selection-wrapper selections">
<div class="draw-number-row">
</div>
<div class="draw-number-row">
</div>
</div>
</div>
And my CSS:
.draw-selection-wrapper {
width: 50%;
float: left;
}
.draw-number-row {
height: 36px;
border: 1px solid #C6C4C5;
padding-left: 10px;
}
.line-number {
float: left;
height: 100%;
width: 12px;
}
.draw-number {
width: 9%;
float: left;
height: 100%;
line-height: 36px;
margin: 0px 2.5% 0px 2.5%;
color: #000;
text-align: center;
background-color: green;
}
.draw-selection-wrapper.selections .draw-number {
margin: 0px 2% 0px 2%;
}
.draw-number-row.one .draw-number {
background-color: red;
}
.draw-number-row.two .draw-number {
background-color: teal;
}
row is a jQuery object, not a string, and as such you end up with [Object, object] when you try to concantenate the object into a string.
You could use the context selector instead
var row = $('.draw-selection-wrapper.selections div:nth-child(' + line_counter + ')');
var link = $('a:nth-child(' + number_counter + ')', row);
FIDDLE
var link = row.find('a:nth-child(' + number_counter + ')');
Fiddle
replace this
var row = $('.draw-selection-wrapper.selections div:nth-child(' + line_counter + ')');
var link = $(row + ' a:nth-child(' + number_counter + ')');
by
var row = '.draw-selection-wrapper.selections div:nth-child(' + line_counter + ')';
var link = $(row + ' a:nth-child(' + number_counter + ')');
Looking for a second set of eyes here...
I am calling this function:
customPanel(map, "map2", dirn, document.getElementById("path2"), 1);
In customPanel, I am then building html, then trying to assign it to the page:
Here is the function, the innerHTML is near the very bottom. If I throw an alert before I try to assign the html to the innerHTML of div, it alerts correctly:
<script type="text/javascript">
var map = "";
function customPanel(map, mapname, dirn, div) {
var html = "";
function waypoint(point, type, address) {
var target = '"' + mapname + ".showMapBlowup(new GLatLng(" + point.toUrlValue(6) + "))" + '"';
html += '<table style="border: 1px solid silver; margin: 10px 0px; background-color: rgb(238, 238, 238); border-collapse: collapse; color: rgb(0, 0, 0);">';
html += ' <tr style="cursor: pointer;" onclick=' + target + '>';
html += ' <td style="padding: 4px 15px 0px 5px; vertical-align: middle; width: 20px;">';
html += ' <img src="http://maps.gstatic.com/intl/en_us/mapfiles/marker_green' + type + '.png">'
html += ' <\/td>';
html += ' <td style="vertical-align: middle; width: 100%;">';
html += address;
html += ' <\/td>';
html += ' <\/tr>';
html += '<\/table>';
}
function routeDistance(dist) {
html += '<div style="text-align: right; padding-bottom: 0.3em;">' + dist + '<\/div>';
}
function detail(point, num, description, dist) {
var target = '"' + mapname + ".showMapBlowup(new GLatLng(" + point.toUrlValue(6) + "))" + '"';
html += '<table style="margin: 0px; padding: 0px; border-collapse: collapse;">';
html += ' <tr style="cursor: pointer;" onclick=' + target + '>';
html += ' <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px; vertical-align: top; text-align: right;">';
html += ' <a href="javascript:void(0)"> ' + num + '. <\/a>';
html += ' <\/td>';
html += ' <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px; vertical-align: top; width: 100%;">';
html += description;
html += ' <\/td>';
html += ' <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px 0.3em 0.5em; vertical-align: top; text-align: right;">';
html += dist;
html += ' <\/td>';
html += ' <\/tr>';
html += '<\/table>';
}
function copyright(text) {
html += '<div style="font-size: 0.86em;">' + text + "<\/div>";
}
// === read through the GRoutes and GSteps ===
for (var i = 0; i < dirn.getNumRoutes(); i++) {
if (i == 0) {
var type = "A";
} else {
var type = "B";
}
var route = dirn.getRoute(i);
var geocode = route.getStartGeocode();
var point = route.getStep(0).getLatLng();
// === Waypoint at the start of each GRoute
waypoint(point, type, geocode.address);
routeDistance(route.getDistance().html + " (about " + route.getDuration().html + ")");
for (var j = 0; j < route.getNumSteps(); j++) {
var step = route.getStep(j);
// === detail lines for each step ===
detail(step.getLatLng(), j + 1, step.getDescriptionHtml(), step.getDistance().html);
}
}
// === the final destination waypoint ===
var geocode = route.getEndGeocode();
var point = route.getEndLatLng();
waypoint(point, "B", geocode.address);
// === the copyright text ===
copyright(dirn.getCopyrightsHtml());
// === drop the whole thing into the target div
div.innerHTML = html;
}
</script>
EDIT:
Here is the HTML as requested. It's just two divs:
<div class="mapWrapper">
<div id="path2"> </div>
<div id="map2"> </div>
</div>
To clarify, the path2 and map2 are being generated dynamically by looping through $_POST values in PHP. Here is a snippit:
foreach($post_entries as $e){
echo "
<div class=\"mapWrapper\">
<div id=\"path" . $increased_counter ."\"> </div>
<div id=\"map" . $increased_counter ."\"> </div>
</div>";
}
EDIT #2
As requested by #user1090190, a public version of the page:
http://qxxiv6yc.myutilitydomain.com/trip-planned
I suspect that path2 has not already been loaded when you call that function. It doesn't matter that you're generating it via PHP. You have to wait for the DOM to load in the browser first before you can reference specific elements. There are two solutions to this:
Call the function after page load. I.e.
<body onload="customPanel(map, "map2", dirn, document.getElementById("path2"), 1);">
Put all your Javascript at the bottom