I have an SVG loading like this:
<object id="svg-object" type="image/svg+xml" width="1400px" height="900px" data="media/1.svg?"></object>
I then have a function that works calling out one element in this svg and apply a style to it just fine. Here is the onload event that is working for getting me the element properly:
window.onload=function() {
var svgObject = document.getElementById('svg-object').contentDocument;
var element = svgObject.getElementById('sprite1');
};
But how do I set a .hover even in for this same element? I've tried:
$('#${element}').hover(function(e) { }
But no luck.
Also, how can I apply the svgObject variable to a whole class like path or polygon? I use this on a local inline SVG and it works fine:
$("polygon, path").hover(function(e) { }
I would like this to work on the object embedded in the svg also.
Sorry, I am not able to put an external svg in snippet (or at least I don't know how) as external URL will not load in an object. And it needs to load as an object for you to see the issue.
Any help?
Also, here is code that works defining element color from script but mouseover not working either. (tried instead of hover)
window.onload=function() {
var svgObject = document.getElementById('svgEmb').contentDocument;
var element = svgObject.getElementById('left');
element.style.fill = "blue";
element.style.stroke ="blue";
};
element.addEventListener("mouseover", function() {
element.style.fill = "red";
element.style.stroke ="red";
});
Related
I'm working with RaphaelJS.
I've noticed that you can add dynamic data to the elements, for example:
to assign a value:
el.data("key",value);
to get a value:
el.data("key")
How can I copy this behaviour using JQuery or Javascript?
Hi I'm trying a wild guess here: as I understand correctly you'd like to communicate from Rapahel to jQuery.
The best I've come up so far is to keep references of both and use them accordingly as Raphael seems not to insert data into dom directly (apart from ID attribute):
$(document).ready(function () {
var paper = Raphael("div", 400, 150);
var circle = paper.circle(80, 80, 30).data('title', 'Red dot').attr({
fill: '#f00'
});
circle.node.id = 'my_circle';
$el_circle = $(circle[0]); // get DOM element out of Rapahel's object
$el_circle.on('click', function () {
// use Raphael reference:
alert("My is title: " + circle.data('title'));
});
});
http://jsfiddle.net/saxxi/Z35NV/
References.
the possibilities: raphael.js - custom attributes
the explanation: Where does Raphael.js store an element's data that is set with the element.data() method?
Combining Raphael and jQuery to achieve browser compatibility
I Googled this issue for about 30 minutes and was surprised nobody has asked so maybe it's not possible.
I'm using this line to embed the SVG file that I made in AI (note that when I saved the SVG, I had no fill OR stroke on the paths):
<object type="image/svg+xml" data="example.svg" height=600px width=600px>Your browser does not support SVG</object>
This obviously comes up with no image because the SVG file has no fill or stroke.
I tried adding in
...fill=yellow>
or
...style="fill:yellow;">
but I'm not having any luck. Thanks!
Have a nice trick: Embed it as <img> and use javascript to convert it into inline <svg> with this code (that came from SO I think). Now you can manipulate this SVG object
CODE::
/*
* Replace all SVG images with inline SVG
*/
jQuery('img.svg').each(function(){
var $img = jQuery(this);
var imgID = $img.attr('id');
var imgClass = $img.attr('class');
var imgURL = $img.attr('src');
jQuery.get(imgURL, function(data) {
// Get the SVG tag, ignore the rest
var $svg = jQuery(data).find('svg');
// Add replaced image's ID to the new SVG
if(typeof imgID !== 'undefined') {
$svg = $svg.attr('id', imgID);
}
// Add replaced image's classes to the new SVG
if(typeof imgClass !== 'undefined') {
$svg = $svg.attr('class', imgClass+' replaced-svg');
}
// Remove any invalid XML tags as per http://validator.w3.org
$svg = $svg.removeAttr('xmlns:a');
// Replace image with new SVG
$img.replaceWith($svg);
});
});
Are you trying to add the fill or style on the object element? If so, that's not going to work. Those properties are not supported on the object element. You're going to have to add it into the SVG in the SVG file.
I have no problem using SVGweb when page is simply loaded (opened).
How is it possible to reinitialize SVGweb in order to redraw all SVG on the page?
Anotherwords I need SVGweb to rescan and rerender everything on the page.
source (from this):
<script type="image/svg+xml">
<svg>
...
</svg>
</script>
to this (like SVGweb si doing that when simply open the page):
<svg>
...
</svg>
I need this because I change the SVG graphics using ajax and need to rerender it on the page.
I needed the same capability and figured out how to do this properly without modifying the svgweb source or calling the _onDOMContentLoaded() handler manually. In fact, it is supported natively.
The trick is to (re)attach your SVG elements to the DOM using window.svgweb.appendChild() which causes the node to be processed by svgweb, as is documented within the svgweb manual.
Example, using jQuery:
// Iterate over all script elements whose type attribute has a value of "image/svg+xml".
jQuery('body').find('script[type="image/svg+xml"]').each(function () {
// Wrap "this" (script DOM node) in a jQuery object.
var $this = jQuery(this);
// Now we use svgweb's appendChild method. The first argument is our new SVG element
// we create with jQuery from the inner text of the script element. The second
// argument is the parent node we are attaching to -- in this case we want to attach
// to the script element's parent, making it a sibling.
window.svgweb.appendChild(jQuery($this.text())[0], $this.parent()[0]);
// Now we can remove the script element from the DOM and destroy it.
$this.remove();
});
For this to work properly I suggest wrapping all SVG script tags with a dedicated div, so that when attaching the SVG element it is attached to a parent element containing no other nodes. This removes the possibility of inadvertently reordering nodes during the process.
After the DOM is changed with a new SVGweb code (through Ajax)
<script type="image/svg+xml">
<svg>
...
</svg>
</script>
need to execute this:
svgweb._onDOMContentLoaded();
But before need to comment a line in the core source of SVGweb svg-uncompressed.js or svg.js
svg-uncompressed.js
from
if (arguments.callee.done) {
return;
}
to
if (arguments.callee.done) {
//return;
}
svg.js: find and delete this:
arguments.callee.done=true;
or replace with
arguments.callee.done=false;
EDIT:
One more fix to work for IE9:
for svg.js
from
var a=document.getElementById("__ie__svg__onload");if(a){a.parentNode.removeChild(a);a.onreadystatechange=null}
to
var IEv=parseFloat(navigator.appVersion.split("MSIE")[1]);if(IEv<9){var a=document.getElementById("__ie__svg__onload");if(a){a.parentNode.removeChild(a);a.onreadystatechange=null;a=null;}}
for svg-uncompressed.js
from
// cleanup onDOMContentLoaded handler to prevent memory leaks on IE
var listener = document.getElementById('__ie__svg__onload');
if (listener) {
listener.parentNode.removeChild(listener);
listener.onreadystatechange = null;
listener = null;
}
to
// cleanup onDOMContentLoaded handler to prevent memory leaks on IE
var IEv=parseFloat(navigator.appVersion.split("MSIE")[1]);
if (IEv<9) {
var listener = document.getElementById('__ie__svg__onload');
if (listener) {
listener.parentNode.removeChild(listener);
listener.onreadystatechange = null;
listener = null;
}
}
Good day.
I use script Imagecropper
Script:
<img src="http://test.com/img/1362244329.jpg" id="yui_img" height="768" width="1024">
<script>
(function() {
var Dom = YAHOO.util.Dom,
Event = YAHOO.util.Event;
var crop = new YAHOO.widget.ImageCropper('yui_img');
})();
</script>
result:
But if i do not specify the image size, then i get next(see image):
<img src="http://test.com/img/1362244329.jpg" id="yui_img">
result:
And if i specify the wrong picture size, the window will increase the portion of the image:
<img src="http://test.com/img/1362244329.jpg" id="yui_img" height="333" width="500">
result:
How to make in tag image does not necessarily will been to specify its size?
First of all I'd like to point you to YUI 3 since YUI 2 is no longer supported. You shouldn't write new code using YUI 2. There's an ImageCropper component I wrote for YUI 3 that works just like the YUI 2 version in the YUI Gallery: http://yuilibrary.com/gallery/show/imagecropper. Since it copies what the YUI 2 ImageCropper did, it shares these issues with the older version.
What to do when the size of the image isn't specified
The reason why you're getting a small ImageCropper is that you're creating the widget before the image has been fetched and so the browser doesn't know its size yet. What you can do is wait for the image's onload event. You can listen to that event and create the ImageCropper after it fires:
(function() {
var Dom = YAHOO.util.Dom,
Event = YAHOO.util.Event;
var yui_img = Dom.get('yui_img');
Event.addListener(yui_img, 'load', function () {
var crop = new YAHOO.widget.ImageCropper(yui_img);
});
})();
Why the ImageCropper doesn't work with images with the wrong size
Neither the YUI 2 ImageCropper nor my YUI 3 version work with images when they don't have the right size. The reason is that both use the background: url() CSS style for showing the image inside the crop area (the non-darkened part of the widget). CSS backgrounds don't let you use a resized/zoomed image.
I plan on using another strategy at some point for the YUI 3 version that will fix the issue. However, you need to keep in mind that the ImageCropper component is designed so that you send the crop coordinates to the server for it to actually crop the image. That means that if you have the wrong size set to the image, the coordinates that the image cropper returns with its getCropCoords method wouldn't be the coordinates that match with the full sized image. Instead you'd also have to send the server the size of the image you've been using and do extra math to crop the image correctly.
In conclusion, you shouldn't use the image with the wrong size. You can fix the size of the image in two ways:
Use the HTML5 naturalWidth and naturalHeight attributes of the image. Those return the real size of the image even if it's resized. Unfortunately these attributes are not yet supported by all browsers.
Create a new image with JS, set it the same src as the image you're using, listen to its load event and get that image's size.
Something like this:
(function () {
var Dom = YAHOO.util.Dom;
var yui_img = Dom.get('yui_img'),
new_img = new Image();
new_img.onload = function () {
yui_img.width = new_img.width;
yui_img.height = new_img.height;
// create the ImageCropper
};
new_img.src = yui_img.src;
}());
A YUI3 version
You can easily do all this with YUI3:
YUI().use('gallery-imagecropper', function (Y) {
var img = Y.one('#yui_img');
img.on('load', function () {
var cropper = new Y.ImageCroper({
srcNode: img,
width: img.get('width'),
height: img.get('height')
});
cropper.render();
});
});
Typo in code. Should be
var cropper = new Y.ImageCropper({
You missed a letter "p".
I determined using the core api that the method "svgCanvas.importImage(url) can import base64 encoded images.
But the embedded API does not expose this method which is private. It also seems i can not use any of the methods that method uses (svgFromgJson, etc).
Does anyone have advice on how I can load a base 64 string representing an image when the embedded svg-edit starts up? I am thinking to just wrap that string inside an < image> tag in a mock svg file and import that way..
Does SVG support embedding of bitmap images?
Modifying the existing code, based on the answer in my original question I modified their sample import, and it works just wonderfully.
Include the embedapi.js in your page
Define an Iframe to show svg-edit
Call the following code function in the iframe's onload event
// call onLoad for the iframe
var frame = document.getElementById('svgedit');
svgCanvas = new embedded_svg_edit(frame);
// Hide main button, as we will be controlling new/load/save etc from the host document
var doc;
doc = frame.contentDocument;
if (!doc)
{
doc = frame.contentWindow.document;
}
var mainButton = doc.getElementById('main_button');
mainButton.style.display = 'none';
var embeddedImage='<image xlink:href="data:image/png;base64,..OMITTED FOR BREVITY.." id="svg_2" height="128" width="128" y="0" x="0"/>';
var svgDef = '<svg width="128" height="128" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"><g><title>Layer 1</title>' + embeddedImage + '</g></svg>';
svgCanvas.setSvgString(svgDef);
}