I have been exploring using SVG's for the latest website I've been building - bit behind the times so trying to catch up. I initially setup my file similar to the way I would do a normal sprite. Although this worked, it does seem a little clumsy when you want to take advantage of resizing the vector and then trying to find the new background position in the document!
After doing some research I came across the idea of stacking it via layers - which makes a heap of sense. After getting all excited and successfully doing this I then came across a few posts saying this isn't support in all browsers - typical.
https://code.google.com/p/chromium/issues/detail?id=128055#c6
Here is a great tutorial for stacking SVG images in a single file as well as some work arounds for browsers that don't support it: http://hofmannsven.com/2013/laboratory/svg-stacking/
Although this works fine, is there an alternative to save writing all this extra code and fallbacks?
After thinking about this a little I decided I could take advantage of the Apache server and see if I could simply inject what I needed into the document. The end result? Works perfect in all browsers :)
To start with I added some code in my .htaccess file to capture all .svg requests
RewriteRule ^(.*)\.svg$ /{path-to-file}/svg.php [L]
Then I wrote a few lines to deal with the target layer and inject that into the file
(UPDATE) Added new variable called target-fill to allow for dynamically changing the fill colour of a shape if required
<?php
// Set the SVG header
header('Content-Type: image/svg+xml');
$queryString = Array();
if(isset($_SERVER['QUERY_STRING'])) $queryString = explode('&', $_SERVER['QUERY_STRING']);
// Get target from the query string
$target = $queryString[0];
// Get a fill alternative if available and valid
if(isset($queryString[1]) && hexdec($queryString[1]) !== false) {
$targetFill = '#' . $queryString[1];
} else {
$targetFill = '';
}
// Validate the target - this is your ID in the SVG file
$validTargets = Array('Camera', 'Layer_1');
if(!in_array($target, $validTargets)) $target = false;
// Get contents of the file - tweak this depending on where you have saved this file to relative to the root of your website
$filename = '../..' . $_SERVER['REDIRECT_URL'];
// Get the contents of the file
$contents = file_get_contents($filename);
// Replace the target with the valid target above
// - doing it this way rather than echoing the target in the SVG file as it seemed like a security risk
if($target) $contents = str_replace('g:target', 'g#' . $target, $contents);
// Replace the fill colour if available
$contents = str_replace('target-fill', $targetFill, $contents);
// Output the amended SVG file
echo $contents;
Included near the top of the SVG is the stacking code to hide we don't want displayed and to turn on what we do
<defs>
<style>
svg g { display: none }
svg g:target, svg g:target g { display: inline }
svg g:target * { fill: target-fill; }
</style>
</defs>
And that is it. So now instead of calling your SVG file like (also works as a background image):
<img src="images/svg-file.svg#Camera">
You would do it like this
<img src="images/svg-file.svg?Camera">
The advantage of doing it this way is you can now also do some further checks based on the user agent to return an alternative file altogether if SVG isn't supported.
(UPDATE) You can now also express a second parameter to change the fill colour if required. Use it like this:
<img src="images/svg-file.svg?Camera&cc0000">
Hope this helps someone else out there.
Related
I'm trying to make a custom cursor setter. You can customize cursors in CSS, so I went there first.
html {
cursor: url(MY URL GOES HERE), auto !important;
}
It works at this point. However, I want the average user to be able to enter an image URL and see the cursor change to that. I decided to use JavaScript to do that.
function customCursor() {
var v1 = prompt("Enter the image URL you want to be your mouse cursor.");
var style = document.createElement('style');
style.innerHTML = `html {cursor:url(` + v1 + `); } `;
document.head.appendChild(style);
}
However, it doesn't work. I checked the current page HTML with Firebug, and the tag is added. And when I use JavaScript to add it manually, it works. So why would it not work?
I also made sure to keep the images I chose below 128x128.
After massive changes to the code, it still is not working. However, I now understand a reason why (by using devtools to read what was actually being added):
Instead of dynamically using my variable, it was treating the variable name as the URL itself. This makes this question mostly irrelevant.
I have Matlab 2019b, GUI Layout Toolbox 2.3.4 and t all runs on MacOs 14 Mojave.
I want to create button in in a UI that have icons/images instead of text. I have seen here:
https://undocumentedmatlab.com/blog/html-support-in-matlab-uicomponents/
that it is supposed to be possible to use HTML to render the button contents.
So - I try this sample code:
figure('MenuBar','none','Name','GUI-TEST','NumberTitle','off','Position',[200,200,140,90]);
push_btn = uicontrol('Style','PushButton','String','Push','Position',[30,60,80,20],...
'CallBack','disp(''You are pressed a push button'')');
close_btn = uicontrol('Style','PushButton','String','Close','Position',[30,5,80,50],...
'CallBack','close');
icon_file = fullfile(pwd, 'close.png')
str = ['<html><img src="file://' icon_file '"></html>']
set(close_btn,'String',str);
but it leaves me with an empty button.
If I deliberately use a filename that does not correspond to an existing file, I see a broken image icon:
So I am reasonably sure that the basic syntax and file path stuff is correct but the image does not get rendered in the button.
Is there something else I need to do to make this work or is it all just part of Matlab's overwhelming strangeness?
The easiest way to put an image on a uicontrol (and specifically a button), is to use the CData property,
im_orig = imread(icon_file); % Needs to be true color, i.e. MxNx3
im_sized = imresize(im_orig,[80,50]); % size of the button
% str = ['<html><img src="file://' icon_file '"></html>'];
% set(close_btn,'String',str);
set(close_btn,'CData',im_sized);
I'm rendering image and I'm passing svg file as source attribute to image. It works perfect on all browsers, except Edge. I cant find an reason why it renders this weird black box with cross:
Html code of is like: <img width="3029" height="3920" id="id_of_image" src="data:image/svg+xml;charset=utf-8,<svg xmlns=....................CONTENT OF SVG............></svg>"/>
How can I show this kind of image also on edge? I'm filling src attribute from JS where I have element as string. I need to put it into image attribute, but question is how is that possible?
Problem solved. Issue was that in Edge it had problem with rendering svg when you are using tags directly in attributes. So solution was to replace and convert string in JS. I created function to generate SVG attribute for image from ajax request, when you have your SVG string:
function fixSVGDiagram(svgString) {
svgString = svgString.replace("<![CDATA[", "").replace("]]>", ""); //If styles occured, Edge crashes on that
svgString = svgString.replace(/#/g,"temporaryhash") //Because of hasthag issues (in styles)
svgString = encodeURI(svgString) //Magic happens
svgString = svgString.replace(/temporaryhash/g, "%23") //Get back hashtag
return "data:image/svg+xml;charset=utf-8," + svgString
}
If you are loading SVG as attribute in ajax request then you can store it as string:
svgData = (new XMLSerializer).serializeToString(responseData);
and then
var img = new Image
img.src = fixSVGDiagram(svgData)
and you can put image where you want.
svg code doesn't work like this for svg image.
Without the use of image tag you can directly use the svg tag in the html code.
OR.
You can create an svg file with *.svg extension and set the filename as the src in the image attribute.
I have a class name 'MonthReport.class.php' and its structure like the following:
class MonthReport{
.....
//some member variables
public function pieChart(){
........
//the image data comes from mysql and data belongs to a specified user
$myPicture->Stroke();
}
public function lineChart(){
........
//the image data comes from mysql and data belongs to a specified user
$myPicture->Stroke();
}
public function render html(){
$html.=str1<<<
.....
//some html code
str1;
$html.=<<<str2
<img src="$this->pieChart()" /> //can not work
str2;
}
}
when I call the pieChart() function with this in the place src it will overwrites my entire page and just shows the image.how can I do this?
I try to render the image in a separate page but the image need some specified user data eg.'userId'.in others words when i new a object, it specify the userId,so I can not render the image in a separate page.
sorry for my bad english!but I need your help!thanks in advancd!
Your question is a little unclear but if your problem is what I am assuming it to be, then I used to have similar issues (Graphic created that is just an image with all of the rest of my page content not displaying). My solution was to generate a temporary image using pchart then embed that file in the html
$myfilename = "temp_image.png"; // temp file name
$myPicture = new pImage(700,500,$myData);
// other image creation code....
$myPicture->Render($myfilename); // generate image "temp_image.png"
$image_html = '<img src="' . $myfilename . '">'; //generate the link
print("$htmlline");
Again there is some guesswork going on here as your question is unclear. The above works for me though and enables me to embed an image created on the fly by pChart into my php pages.
i am trying to put context path for an image in HTML.<img src="/MyWeb/images/pageSetup.gif">
Here /MyWeb is the ContextPath which is hardcoded. How can i get dynamically.
i am using as <img src=contextPath+"/images/pageSetup.gif">but image is not displaying. Is there any option.
First of all, "Context path" is a term which is typically used in JSP/Servlet web applications, but you didn't mention anything about it. Your question history however confirms that you're using JSP/Servlet. In the future, you should be telling and tagging what server side language you're using, because "plain HTML" doesn't have a concept of "variables" and "dynamic generation" at all. It are server side languages like JSP which have the capability of maintaining and accessing variables and dyamically generating HTML. JavaScript can be used, but it has its limitations as it runs in webbrowser, not in webserver.
The question as you initially have will only confuse answerers and yield completly unexpected answers. With question tags you reach a specific target group. If you use alone the [html] tag, you will get answers which assume that you're using pure/plain HTML without any server side language.
Back to your question: you can use ${pageContext.request.contextPath} for this.
<img src="${pageContext.request.contextPath}/images/pageSetup.gif">
See also:
How to use relative paths without including the context root name?
Browser can't access/find relative resources like CSS, images and links when calling a Servlet which forwards to a JSP
You can't write JavaScript in the src attribute. To do what you want, try some code like this:
var img = new Image();
img.src = contextPath + "/images/pageSetup.gif";
document.getElementById('display').appendChild(img);
Here the target; the place where you want to display the image, is a div or span, with the id display.
Demo
With HTML, you'll have to take some extra traffic of producing an error, so you can replace the image, or you can send some traffic Google's way. Please do not use this:
<img src='notAnImage' onerror='this.src= contextPath + "/images/pageSetup.gif" '>
Demo
Do not use this.
You must use JavaScript for this.
First, have all images point to some dummy empty image on your domain while putting the real path as custom attribute:
<img src="empty.gif" real_src="/images/pageSetup.gif" />
Now have such JavaScript code in place to iterate over all the images and change their source to use the context path:
var contextPath = "/MyRealWeb";
window.onload = function() {
var images = document.getElementByTagName("img");
for (var i = 0; i < images.length; i++) {
var image = images[i];
var realSource = image.getAttribute("real_src") || "";
if (realSource.length > 0)
image.src = contextPath + realSource;
}
};