Detect svg coordinates being hovered over - javascript

I have an SVG element
<svg id='win-frame' style='height: 500px; width: 500px;'>
</svg>
Say that the mouse is hovering over the svg element. Is there a way to display the coordinates of the point being hovered over by the mouse, either in a tooltip, or a div below the svg? This would preferably use javascript. Thanks!

Add text field to show coordinates:
<input type="text" id="coords" readonly></input>
Then handle the mousemove and mouseout events to fill the coords input with coordinates:
/* create an svg drawing */
var draw = SVG('win-frame');
/* draw rectangle */
var rect = draw.rect(200, 200).fill('#f09')
var coordsDiv = document.getElementById('coords');
rect.mousemove(function(evt) {
coordsDiv.value = evt.clientX + ' ' + evt.clientY;
}).mouseout(function() {
coordsDiv.value = '';
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.0.5/svg.js"></script>
<div id="win-frame"></div>
<input type="text" id="coords" readonly />
EDIT: Pure javascript solution
HTML part:
<svg id='win-frame' style='height: 200px; width: 200px;' >
<rect width="100%" height="100%" style="fill:rgb(0,0,255);" />
</svg>
<input type="text" id="coords" readonly />
And javascript part:
var coordsDiv = document.getElementById('coords');
var el1 = document.getElementById('win-frame');
el1.onmousemove = function(evt) {
coordsDiv.value = evt.clientX + ' ' + evt.clientY;
}
Demo fiddle: http://jsfiddle.net/7fh68sb5/2/

Related

Moving a rectangle up down left and right

I wanted to make a rectangle move in 4 directions with a click of a button on JavaScript. Only the Right and Down works and the other two does not work. I tried finding it on internet and so far had not have any luck.
var currentXpos = 0;
function moveRectRight() {
var rect = document.getElementById('rectangle');
currentXpos += 100; // move by 100 px to the right
rect.style.marginLeft = currentXpos + 'px'; // re-draw rectangle
}
function moveRectLeft() {
var rect = document.getElementById('rectangle');
currentXpos += 100; // move by 100 px to the right
rect.style.marginRight = currentXpos + 'px'; // re-draw rectangle
}
function moveRectUp() {
var rect = document.getElementById('rectangle');
currentXpos += 100; // move by 100 px to the right
rect.style.marginBottom = currentXpos + 'px'; // re-draw rectangle
}
function moveRectDown() {
var rect = document.getElementById('rectangle');
currentXpos += 100; // move by 100 px to the right
rect.style.marginTop = currentXpos + 'px'; // re-draw rectangle
}
#rectangle {
background-color: red;
width: 200px;
height: 100px;
margin-left: 0px;
}
<div id='rectangle'></div>
<input type="button" value="Right" onclick="moveRectRight()" />
<input type="button" value="Left" onclick="moveRectLeft()" />
<input type="button" value="Up" onclick="moveRectUp()" />
<input type="button" value="Down" onclick="moveRectDown()" />
Your problem lies on this code
function moveRectLeft() {
var rect = document.getElementById('rectangle');
currentXpos += 100; // move by 100 px to the right
rect.style.marginRight = currentXpos + 'px'; // re-draw rectangle
}
function moveRectUp() {
var rect = document.getElementById('rectangle');
currentXpos += 100; // move by 100 px to the right
rect.style.marginBottom = currentXpos + 'px'; // re-draw rectangle
}
when you move left you tried to add the margin right and when you move up you add margin bottom. This is a wrong concept, you shouldn't imagine it like the box is being pushed from 4 side like this image
When you code in HTML & CSS, try to imagine that in coordinate, the 0,0 (x and y) is on your upper left corner of browser, and to move them you can only move them away or closer to the 0,0, like below
I suggest you to learn/debug using the developer tools you can see where it goes wrong,
So the answer is just changing the code to marginLeft and marginTop
That aside, I made my own version maybe you want to check it out
<html>
<head>
<style>
#rectangle {
background-color: red;
width: 200px;
height: 100px;
position: fixed;
}
</style>
</head>
<body>
<div id='rectangle' style="top:100px;left:100px;"></div>
<input type="button" value="Right" onclick="moveRect(this)" />
<input type="button" value="Left" onclick="moveRect(this)" />
<input type="button" value="Up" onclick="moveRect(this)" />
<input type="button" value="Down" onclick="moveRect(this)" />
<script>
const distance = 10;
const directionMap = {
'Up': {
'prop': 'top',
'value': -1
},
'Down': {
'prop': 'top',
'value': 1
},
'Left': {
'prop': 'left',
'value': -1
},
'Right': {
'prop': 'left',
'value': 1
},
}
const parsePosition = (prop) => parseFloat(rectangle.style[prop]) || 0;
const moveRect = (element) => {
let {
prop,
value
} = directionMap[element.value];
rectangle.style[prop] = (parsePosition(prop) + (value * distance)) + "px";
}
</script>
</body>
</html>
Because margins in the HTML, depend on having a neightbor. So, you'll not see margin-right and margin-bottom working, hence you'll not see the box going up or left.
Instead, what you can do, is affect the same property with addition and substraction. For Y affect only margin-top and for X affect only margin-left
CSS Documentation
<html>
<head>
<style>
#rectangle {
background-color: red;
width: 200px;
height: 100px;
margin-left: 0px;
}
</style>
</head>
<body>
<div id='rectangle'>
</div>
<input type="button" value="Right" onclick="moveRectRight()" />
<input type="button" value="Left" onclick="moveRectLeft()" />
<input type="button" value="Up" onclick="moveRectUp()" />
<input type="button" value="Down" onclick="moveRectDown()" />
<script>
var currentXpos = 0;
function moveRectRight() {
var rect = document.getElementById('rectangle');
console.log(rect)
currentXpos += 100; // move by 100 px to the right
rect.style.marginLeft = currentXpos + 'px'; // re-draw rectangle
}
function moveRectLeft() {
var rect = document.getElementById('rectangle');
currentXpos -= 100; // move by 100 px to the right
rect.style.marginLeft = currentXpos + 'px'; // re-draw rectangle
}
function moveRectUp() {
var rect = document.getElementById('rectangle');
currentXpos -= 100; // move by 100 px to the right
rect.style.marginTop = currentXpos + 'px'; // re-draw rectangle
}
function moveRectDown() {
var rect = document.getElementById('rectangle');
currentXpos += 100; // move by 100 px to the right
rect.style.marginTop = currentXpos + 'px'; // re-draw rectangle
}
</script>
</body>
</html>
Thremulant gave a very good solution but there was something missed something the "current position" variable should be different for X and Y axis. This way it will not show abnormal behaviour.
<html>
<head>
<style>
#rectangle {
background-color: red;
width: 200px;
height: 100px;
margin-left: 0px;
}
</style>
<script>
var currentXpos = 0;
var currentYpos = 0;
function moveRectRight() {
var rect = document.getElementById('rectangle');
currentXpos += 100; // move by 100 px to the right
rect.style.marginLeft = currentXpos + 'px'; // re-draw rectangle
}
function moveRectLeft() {
var rect = document.getElementById('rectangle');
currentXpos -= 100; // move by 100 px to the right
rect.style.marginLeft = currentXpos + 'px'; // re-draw rectangle
}
function moveRectUp() {
var rect = document.getElementById('rectangle');
currentYpos -= 100; // move by 100 px to the right
rect.style.marginTop = currentYpos + 'px'; // re-draw rectangle
}
function moveRectDown() {
var rect = document.getElementById('rectangle');
currentYpos += 100; // move by 100 px to the right
rect.style.marginTop = currentYpos + 'px'; // re-draw rectangle
}
</script>
</head>
<body>
<div id='rectangle'></div>
<input type="button" value="Right" onclick="moveRectRight()" />
<input type="button" value="Left" onclick="moveRectLeft()" />
<input type="button" value="Up" onclick="moveRectUp()" />
<input type="button" value="Down" onclick="moveRectDown()" />
</body>
</html>

How do I add a download button that will download the image after making changes?

I am working on a photo editor and I want to add a download button that will download the image after the user makes the necessary changes. The changes are working fine but I am not able to figure out how to download the image (Please keep in mind that the filter value depends on the user and is not constant). Does anyone have any ideas on how I can proceed further?
(P.S. I searched all over Stack Overflow and tried to implement every solution in my code but nothing's working)
Here's my HTML:
<!-- upload image button -->
<p><input type="file" accept="image/*" name="image" id="file" onchange="loadFile(event)" style="display: none;"></p>
<p><label for="file" style="cursor: pointer;" id="fileBtn">UPLOAD IMAGE</label></p>
<p><img id="img"></p>
<!-- side nav -->
<div class="sidenav">
<label for="filter-select">FILTER AND ADJUST</label>
<div class="slider">
<p style="color: aliceblue;">Sepia</p>
<input id="sepia" type="range" oninput="setSepia(this);" value="0" step="0.1" min="0" max="1"><span id="Amount" style="color: white;"> 0</span><br/><br>
<p style="color: aliceblue;">Grayscale</p>
<input id="Grayscale" type="range" oninput="setGs(this);" value="0" step="0.1" min="0" max="1"><span id="Amount2" style="color: white;"> 0</span><br/><br>
</div>
<label onclick = "RotateImg()">ROTATE</label>
<label onclick = "flipping()">FLIP</label>
<label onclick = "invert()">INVERT COLOURS</label>
<label onclick = "original()">ORIGINAL</label>
</div>
Here's my JavaScript:
function loadFile(event) {
var image = document.getElementById('img');
image.src = URL.createObjectURL(event.target.files[0]);
}
const options = {
sepia: 0,
grayscale: 0,
rotation: 0,
scale: 1,
invertVal: 0
};
function setSepia(e){
options.sepia = e.value;
document.getElementById('Amount').innerHTML= e.value;
redraw();
}
function setGs(e){
options.grayscale = e.value;
document.getElementById('Amount2').innerHTML= e.value;
redraw();
}
let rotation = 0;
function RotateImg(){
rotation += 90;
if (rotation == 360) {
rotation = 0;
}
options.rotation = rotation;
redraw();
}
let scale = 1
function flipping() {
scale -= 2
if (scale <= -2) {
scale = 1;
}
options.scale = scale;
redraw();
}
let invertVal = 0
function invert() {
invertVal += 100
if (invertVal > 100) {
invertVal = 0
}
options.invertVal = invertVal;
redraw();
}
function original() {
document.getElementById("img").style["webkitFilter"] ="sepia(0) grayscale(0)";
document.querySelector("img").style.transform = "rotate(0deg) scaleX(1)";
}
function redraw() {
document.getElementById("img").style["webkitFilter"] ="sepia(" + options.sepia + ") grayscale(" + options.grayscale + ");
document.querySelector("img").style.transform = `rotate(${options.rotation}deg) scaleX(${options.scale})`;
}
Your best bet would be to use the Canvas API to apply your edits and then use toDataURL to set up the download.
Here's a proof of concept fiddle:
<div id="container">
<img src="//placekitten.com/400/400" crossorigin="anonymous"/>
<canvas width="400" height="400" />
</div>
const canvas = document.querySelector('canvas');
const image = document.querySelector('img');
image.addEventListener('load', () => {
const ctx = canvas.getContext('2d');
// draw the image into the canvas with a sepia filter:
ctx.filter = 'sepia(1)';
ctx.drawImage(image, 0, 0);
// set up the download link
addDownload(canvas);
})
function addDownload (canvas) {
// create an <a>
const a = document.createElement('a');
// set it up to download instead of navigating
a.setAttribute('download', 'kitten.jpg');
a.innerHTML = "download";
// set the href to a data url for the image
a.href = canvas.toDataURL('image/jpg');
// append it to the dom
container.appendChild(a);
}

How can I change the brightness of only part of an image (html/css/js)?

I have an image with tags underneath that correspond to different parts of the image. For instance, the image might be a dog, and one of the tags is 'nose', which corresponds to the portion of the image around the dogs nose. When the user hovers over a tag, I want the brightness around this corresponding part of the image to increase. How can I do this?
function fixLabel(c) {
var x_coor = document.getElementById('x').textContent;
var y_coor = document.getElementById('y').textContent;
var x2_coor = document.getElementById('x2').textContent;
var y2_coor = document.getElementById('y2').textContent;
var width = document.getElementById('w').textContent;
var height = document.getElementById('h').textContent;
var tag = document.createElement('input'); // Create a `input` element,
tag.setAttribute('type', 'text'); // Set it's `type` attribute,
tag.setAttribute('name', 'loc:' + round_2_decimals(x_coor) + "-" + round_2_decimals(y_coor) + "-" +
round_2_decimals(x2_coor) + "-" + round_2_decimals(y2_coor) + "-" + round_2_decimals(width) +
"-" + round_2_decimals(height));
/**
*Here's the area: How do I attach a mouseover function so the image's
*brightness increases whenever I hover over the tag?
*/
tag.onmouseover = function() {};
var br = document.createElement('br'); // Create a `br` element,
var button_div = document.getElementById('fix_label_area');
button_div.appendChild(br);
button_div.appendChild(tag);
button_div.appendChild(br);
};
<div>
<p id='x'></p>
<p id='y'></p>
<p id='x2'></p>
<p id='y2'></p>
<p id='w'></p>
<p id='h'></p>
<br/>
<button id='fix_label' onclick="fixLabel()">Fix Label Here</button>
</div>
<form action="" method="POST" id="canvas">
<div id='img_area'>
<img src="someImageFile.jpg" id="imageId" width="350" height="350" />
</div>
<div id='label_area'>
<input type="submit" name="submit" value="Label" id='input'>
</div>
<div id='fix_label_area'></div>
</form>
Personally Canvas and SVG are more powerful, but you can use CSS to clip a circle and opacity to dim the original. But you need to check the browser support to make sure it covers the browsers you need.
div.holder {
position: relative;
}
img.main {
opacity: .4;
}
img.circle {
position: absolute;
clip-path: circle(50px at 405px 135px);
}
<div class="holder">
<img class="circle" src="https://placedog.net/500" />
<img class="main" src="https://placedog.net/500" />
</div>

create a div with a text where i click an image

I have an image in HTML and i want the user to write an input in HTML and then if he click on the image it will create a colored div which is written inside the input, the position of this div is based of the coordinates where the user clicked (not centered, a little on top and to the left), for now I can create the rectangular div, but i don't know how to put a text in it.
let listaAre = [];
let quantiClic = 0;
document.getElementById('blah').addEventListener('click', event => {
document.getElementById('squareContaine').innerHTML =
document.getElementById('squareContaine').innerHTML +
'<div id="squar' + quantiClic + '" style="background-color: blue; height: 50px; width: 50px; position: absolute;"></div>';
document.getElementById('squar' + quantiClic).style.top = (event.pageY - Number(document.getElementById('dimensione').value) / 2) + 'px';
document.getElementById('squar' + quantiClic).style.left = (event.pageX - Number(document.getElementById('dimensione').value) / 2) + 'px';
document.getElementById('squar' + quantiClic).style.width = Number(document.getElementById('dimensione').value)/4 + 'px';
document.getElementById('squar' + quantiClic).style.height = Number(document.getElementById('dimensione').value)/10 + 'px';
document.getElementById('squar' + quantiClic).style.background =(document.getElementById('colorebordo').value);
listaAre.push({
x: (event.offsetX - Number(document.getElementById('dimensione').value) / 2),
y: (event.offsetY - Number(document.getElementById('dimensione').value) / 2),
width: Number(document.getElementById('dimensione').value),
height: Number(document.getElementById('dimensione').value),
background:(document.getElementById('colorebordo').value)
});
document.getElementById('squar' + quantiClic).addEventListener('click', function (e) {
this.style.display = 'none';
});
quantiClic = quantiClic + 1;
});
article, aside, figure, footer, header,
hgroup, menu, nav, section { display: block; }
.fasciaalta {
position: fixed;
background-color: white;
}
<div class="fasciaalta">
<input type="color" id="colorebordo">
<input type="text" id="nome">
<input type="number" id="dimensione" value="200">
<hr size="2px" color="blue" width="100">
</div>
<img id="blah" src="montagna.jpg" alt="your image" />
<div id="squareContaine"></div>
<div id="previewImage"></div>
You can get the coordinates of the mouse on the event click by accessing the clientX and clientY properties of the event object. Then you simply tell the new element to use them as top and left styles to position it.
Snippet
document.getElementById('blah').addEventListener('click', function(event) {
var div = document.createElement("DIV"); // Create a <div> element
var t = document.createTextNode("HELLO");// Create a text node
div.appendChild(t); // Append the text to <div>
document.body.appendChild(div); //Add <div> to document
div.style.position = 'absolute'; //Make its position absolute
//Set the coordinates
div.style.left = event.clientX + "px";
div.style.top = event.clientY + "px";
})
<div>
<img id="blah" src="http://img1.wikia.nocookie.net/__cb6/nyancat/images/5/50/Wiki-background" alt="your image" />
</div>
Extra
If instead of creating a new div, you want to use one simply access that element with getElementById and change its properties instead. I've made the example as simple as possible so that it can apply to not only your case but anyone else's trying to solve their issue.
If you need the text value then all you need is to change the first 2 statements of your click function. - Check this Codepen
1) Onclick, get the value of the textbox like so
var val = document.getElementById('nome').value;
2) Next insert this val into your innerHTML statement
document.getElementById('squareContaine').innerHTML =
document.getElementById('squareContaine').innerHTML +
'<div id="squar' + quantiClic + '" style="background-color: blue; height: 50px; width: 50px; position: absolute;">'+ val + '</div>';
Scroll the very end of the above statement to see the val inserted.
Also do not forget to change the color of the text if the background of the box is black.
document.getElementById('blah').addEventListener('click', event => {
var val = document.getElementById('nome').value; //added
//below statement changed
document.getElementById('squareContaine').innerHTML =
document.getElementById('squareContaine').innerHTML +
'<div id="squar' + quantiClic + '" style="background-color: blue; height: 50px; width: 50px; position: absolute;">'+ val + '</div>';
.. rest of the code remain the same ..
});

Letter Shadows from User Input

Goal: User types name into user input field, selects Animate button, and name is printed vertically with each letter containing a drop shadow of each letter. The Javascript library Raphael may be desirable.
Problem: So far what I have is the name being printed vertically twice side by side. Obviously the second column should be the letters as drop shadows, but I don't know how to change the style of them to look like shadows.
My manager gave me one hint: "I had to create a 2nd text line placed underneath the text...and I used the .blur() method on it. If I have to give you another hint I'll be hinting you to the door."
I'm in some real trouble here. If anyone has suggestions, solutions, anything it would be very much appreciated.
<html>
<head>
<script src="raphael-min.js"></script>
<script src="jquery-1.7.2.js"></script>
<script type="text/javascript">
function animate() {
var txt = document.getElementById("words").value;
var area = txt;
var splittxt = txt.split("");
document.getElementById("letters").innerHTML = "";
document.getElementById("letters2").innerHTML = "";
var i;
for (i = 0; i < splittxt.length; i++) {
document.getElementById("letters").innerHTML = document.getElementById("letters").innerHTML + splittxt[i] + "<br>";
document.getElementById("letters2").innerHTML = document.getElementById("letters2").innerHTML + splittxt[i] + "<br>";
}
//displays how many symbols are in text box and what is in text box
document.getElementById("num").innerHTML= txt.length;
document.getElementById("msg").innerHTML = txt;
r.clear();
// Make our pink rectangle
ellipse = r.ellipse(40, 15, 30, 5).attr({"fill": "#969696", "stroke": "none"});
ellipse.glow({width:10});
}
</script>
<style type="text/css">
#letters
{
background-color:yellow;
width:25px;
float:left;
}
#letters2
{
letter-spacing:0px;
display:block;
-moz-transform: rotate(80deg);
margin-left:90px;
margin-top:80px;
width:25px;
color:#DEDEDE;
}
</style>
</head>
<body>
Text: <input type="text" id="words" value="" />
<input type="button" value="Animate" onclick="animate()" />
<div id='msg'></div>
<div id='num'></div>
<div id='letters'></div>
<div id="letters2"></div>
<div id="draw-here-raphael" style="height: 200px; width: 400px; margin-top:0px;">
</div>
<div id="elps" style="margin-left:100px;"/>
<script type="text/javascript"> //all your javascript goes here
var r = new Raphael("draw-here-raphael");
</script>
</body>
</html>
Live Long and Prosper.
Do you really need raphael? What I did was simply print out your words onto an element and get the shadow with css's text-shadow. To get the vertical text I added a </br> after each letter.
Take a look at the fiddle: http://jsfiddle.net/joplomacedo/wVGbF/
Here's the code in case you can't see the fiddle:
HTML
Text: <input type="text" id="words" value="" />
<input id="animateBtn" type="button" value="Animate" />
<div class="print"></div>
CSS
.print {
font: 44px/0.8em "Lobster", cursive;
color: gold;
text-shadow: 2px 2px 3px rgba(0, 0, 0, 0.6);
}​
JS
var join = Array.prototype.join;
$('#animateBtn').on('click', function() {
var txt = $('#words').val(),
spaced_txt = join.call(txt, "</br>");
$('.print').html(spaced_txt);
});​
Here is also the text output function with Raphael:
function draw_text() {
var txt = document.getElementById("words").value;
var posy = txt.length*10;
r.clear();
var attr = {font: "50px Helvetica", opacity: 0.5};
var text = r.text(40, 40+posy, txt).attr(attr).attr({fill: "#0f0"}); // underlayer or "shadow"
text.attr({transform: "r270"}); // rotate 270 degrees
var text2 = r.text(43, 43+posy, txt).attr(attr).attr({fill: "#aa0"}); // text above
text2.attr({transform: "r270"}); // rotate 270 degrees
r.safari();
}
var r = new Raphael("draw-here-raphael");
The full script, based on this example, is here.

Categories

Resources