C# Google Earth Error - c#

A friend of mine has embedded a google earth plugin into a C# user control. All works fine but when you close the window we recieve and "Unspecified Error" with the option to continue running the scripts or not. From our tracking it down it appears this is being cause by a script that google is dropping onto the page. Any ideas?

Here is an example, by me, of c#/Google Earth API integration that covers the problem you are having (see the comments)
http://fraserchapman.blogspot.com/2008/08/google-earth-plug-in-and-c.html
Also, here is another of my projects that uses COM Google Earth Plugin Type Library (plugin_ax.dll) converted into the equivalent definitions in a common language run time assembly. It may be of some use. http://fraserchapman.blogspot.com/2008/12/google-earth-plugin-control-library.html

We have now tried this in both IE and FF. Works fine. Any ideas why the error only comes up on close? can we somehow disable it? here is our code.
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<html>
<head>
<script src="http://www.google.com/jsapi?key=ABQIAAAAzghEPRV_D0MDzTELJ4nkXBT2AlVLQD8Rz4_aVbiXesLoyhRIMBRo399nnxv9aY-fqnkVGgTgR-pTsg">
</script>
<script>
google.load("earth", "1");
var ge = null;
var placemark;
function init(){
google.earth.createInstance("map3d", initCallback, failureCallback);
}
function initCallback(object){
ge = object;
ge.getWindow().setVisibility(true);
ge.getNavigationControl().setVisibility(ge.VISIBILITY_SHOW);
ge.getLayerRoot().enableLayerById(ge.LAYER_TERRAIN, false);
placemark = ge.createPlacemark('');
placemark.setName("Current Position");
// Create style map for placemark
var normal = ge.createIcon('');
normal.setHref('http://maps.google.com/mapfiles/kml/paddle/red-circle.png');
var iconNormal = ge.createStyle('');
iconNormal.getIconStyle().setIcon(normal);
var highlight = ge.createIcon('');
highlight.setHref('http://maps.google.com/mapfiles/kml/paddle/red-circle.png');
var iconHighlight = ge.createStyle('');
iconHighlight.getIconStyle().setIcon(highlight);
var styleMap = ge.createStyleMap('');
styleMap.setNormalStyle(iconNormal);
styleMap.setHighlightStyle(iconHighlight);
placemark.setStyleSelector(styleMap);
var options = ge.getOptions();
options.setStatusBarVisibility(true);
options.setScaleLegendVisibility(true);
}
function failureCallback(object){
// Gracefully handle failure.
alert("Error");
}
function changeViewAngle(angle){
var lookAt = ge.getView().copyAsLookAt(ge.ALTITUDE_ABSOLUTE);
lookAt.setTilt(angle);
ge.getView().setAbstractView(lookAt);
}
function ShowMarker(){
ge.getFeatures().appendChild(placemark);
}
function MoveMarker(lon, lat){
// Create point
var la = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND);
var point = ge.createPoint('');
point.setLatitude(lat);
point.setLongitude(lon);
placemark.setGeometry(point);
}
function HideMarker(){
ge.getFeatures().removeChild(placemark);
}
function SetPosition(lon, lat, heading){
var lookAt = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND);
lookAt.setLatitude(lat);
lookAt.setLongitude(lon);
lookAt.setHeading(heading);
ge.getView().setAbstractView(lookAt);
}
function SetAltitude(alt){
var lookAt = ge.getView().copyAsLookAt(ge.ALTITUDE_RELATIVE_TO_GROUND);
lookAt.set(lookAt.getLatitude(), lookAt.getLongitude(), 0, ge.ALTITUDE_RELATIVE_TO_GROUND, 0, lookAt.getTilt(), alt);
ge.getView().setAbstractView(lookAt);
}
function ResizeMap(w, h){
var map = document.getElementById('map3d_container');
map.style.height = h;
map.style.width = w;
}
function AddKML(kml){
var parseKML = ge.parseKml(kml);
ge.getFeatures().appendChild(parseKML);
return ge.getFeatures().getLastChild().getName();
}
function RemoveKML(kmlName){
if (ge.getFeatures().hasChildNodes()) {
var nodes = ge.getFeatures().getChildNodes();
for (var i = 0; i < nodes.getLength(); i++) {
var child = nodes.item(i);
if (child.getName() == kmlName) {
ge.getFeatures().removeChild(child);
}
}
}
}
function OptionsChanged(nav, status, scale, grid, map, terrain, road, border, building){
var options = ge.getOptions();
var form = document.options;
if (nav) {
ge.getNavigationControl().setVisibility(ge.VISIBILITY_SHOW);
}
else {
ge.getNavigationControl().setVisibility(ge.VISIBILITY_HIDE);
}
options.setStatusBarVisibility(status);
options.setScaleLegendVisibility(scale);
options.setGridVisibility(grid);
options.setOverviewMapVisibility(map);
ge.getLayerRoot().enableLayerById(ge.LAYER_TERRAIN, terrain);
ge.getLayerRoot().enableLayerById(ge.LAYER_ROADS, road);
ge.getLayerRoot().enableLayerById(ge.LAYER_BORDERS, border);
ge.getLayerRoot().enableLayerById(ge.LAYER_BUILDINGS, building);
}
</script>
</head>
<body onload='init()'>
<center>
<div id='map3d_container' style='border: 1px solid silver; height: 510px; width: 767px;'>
<DIV id=map3d style="HEIGHT: 100%">
</DIV>
</div>
</center>
</body>
</html>

I ran the sample and didn't get any errors when closing the tab.

try this
yourWebBrowser1.Document.Write(String.Empty);
when you close the app.
my question:
can you show me how to use AddKML(kml) in C# app? by string or file path, I tried both.
I am looking for a way to parse kml files...

Related

How to extract svg tag from svg image [duplicate]

This is a self Q&A of a handy piece of code I came up with.
Currently, there isn't an easy way to embed an SVG image and then have access to the SVG elements via CSS. There are various methods of using JS SVG frameworks, but they are overly complicated if all you are doing is making a simple icon with a rollover state.
So here is what I came up with, which I think is by far the easiest way to use SVG files on a website. It takes its concept from the early text-to-image replacement methods, but as far as I am aware has never been done for SVGs.
This is the question:
How do I embed an SVG and change its color in CSS without using a JS-SVG framework?
Firstly, use an IMG tag in your HTML to embed an SVG graphic. I used Adobe Illustrator to make the graphic.
<img id="facebook-logo" class="svg social-link" src="/images/logo-facebook.svg"/>
This is just like how you'd embed a normal image. Note that you need to set the IMG to have a class of svg. The 'social-link' class is just for examples sake. The ID is not required, but is useful.
Then use this jQuery code (in a separate file or inline in the HEAD).
/**
* 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);
}, 'xml');
});
What the above code does is look for all IMG's with the class 'svg' and replace it with the inline SVG from the linked file. The massive advantage is that it allows you to use CSS to change the color of the SVG now, like so:
svg:hover path {
fill: red;
}
The jQuery code I wrote also ports across the original images ID and classes. So this CSS works too:
#facebook-logo:hover path {
fill: red;
}
Or:
.social-link:hover path {
fill: red;
}
You can see an example of it working here:
http://labs.funkhausdesign.com/examples/img-svg/img-to-svg.html
We have a more complicated version that includes caching here:
https://github.com/funkhaus/style-guide/blob/master/template/js/site.js#L32-L90
Style
svg path {
fill: #000;
}
Script
$(document).ready(function() {
$('img[src$=".svg"]').each(function() {
var $img = jQuery(this);
var imgURL = $img.attr('src');
var attributes = $img.prop("attributes");
$.get(imgURL, function(data) {
// Get the SVG tag, ignore the rest
var $svg = jQuery(data).find('svg');
// Remove any invalid XML tags
$svg = $svg.removeAttr('xmlns:a');
// Loop through IMG attributes and apply on SVG
$.each(attributes, function() {
$svg.attr(this.name, this.value);
});
// Replace IMG with SVG
$img.replaceWith($svg);
}, 'xml');
});
});
You can now use the CSS filter property in most modern browsers (including Edge, but not IE11). It works on SVG images as well as other elements. You can use hue-rotate or invert to modify colors, although they don't let you modify different colors independently. I use the following CSS class to show a "disabled" version of an icon (where the original is an SVG picture with saturated color):
.disabled {
opacity: 0.4;
filter: grayscale(100%);
-webkit-filter: grayscale(100%);
}
This makes it light grey in most browsers. In IE (and probably Opera Mini, which I haven't tested) it is noticeably faded by the opacity property, which still looks pretty good, although it's not grey.
Here's an example with four different CSS classes for the Twemoji bell icon: original (yellow), the above "disabled" class, hue-rotate (green), and invert (blue).
.twa-bell {
background-image: url("https://twemoji.maxcdn.com/svg/1f514.svg");
display: inline-block;
background-repeat: no-repeat;
background-position: center center;
height: 3em;
width: 3em;
margin: 0 0.15em 0 0.3em;
vertical-align: -0.3em;
background-size: 3em 3em;
}
.grey-out {
opacity: 0.4;
filter: grayscale(100%);
-webkit-filter: grayscale(100%);
}
.hue-rotate {
filter: hue-rotate(90deg);
-webkit-filter: hue-rotate(90deg);
}
.invert {
filter: invert(100%);
-webkit-filter: invert(100%);
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<span class="twa-bell"></span>
<span class="twa-bell grey-out"></span>
<span class="twa-bell hue-rotate"></span>
<span class="twa-bell invert"></span>
</body>
</html>
Alternatively you could use CSS mask, granted browser support isn't good but you could use a fallback
.frame {
background: blue;
-webkit-mask: url(image.svg) center / contain no-repeat;
}
If you can include files (PHP include or include via your CMS of choice) in your page, you can add the SVG code and include it into your page. This works the same as pasting the SVG source into the page, but makes the page markup cleaner.
The benefit is that you can target parts of your SVG via CSS for hover -- no javascript required.
http://codepen.io/chriscoyier/pen/evcBu
You just have to use a CSS rule like this:
#pathidorclass:hover { fill: #303 !important; }
Note that the !important bit is necessary to override the fill color.
TL/DR: GO here-> https://codepen.io/sosuke/pen/Pjoqqp
Explanation:
I'm assuming you have html something like this:
<img src="/img/source.svg" class="myClass">
Definitely go the filter route, ie. your svg is most likely black or white. You can apply a filter to get it to be whatever color you want, for example, I have a black svg that I want mint green. I first invert it to be white (which is technically all RGB colors on full) then play with the hue saturation etc. To get it right:
filter: invert(86%) sepia(21%) saturate(761%) hue-rotate(92deg) brightness(99%) contrast(107%);
Even better is that you could just use a tool to convert the hex you want into a filter for you: https://codepen.io/sosuke/pen/Pjoqqp
#Drew Baker gave a great solution to solve the problem. The code works properly. However, those who uses AngularJs may find lots of dependency on jQuery. Consequently, I thought it is a good idea to paste for AngularJS users, a code following #Drew Baker's solution.
AngularJs way of the same code
1. Html: use the bellow tag in you html file:
<svg-image src="/icons/my.svg" class="any-class-you-wish"></svg-image>
2. Directive: this will be the directive that you will need to recognise the tag:
'use strict';
angular.module('myApp')
.directive('svgImage', ['$http', function($http) {
return {
restrict: 'E',
link: function(scope, element) {
var imgURL = element.attr('src');
// if you want to use ng-include, then
// instead of the above line write the bellow:
// var imgURL = element.attr('ng-include');
var request = $http.get(
imgURL,
{'Content-Type': 'application/xml'}
);
scope.manipulateImgNode = function(data, elem){
var $svg = angular.element(data)[4];
var imgClass = elem.attr('class');
if(typeof(imgClass) !== 'undefined') {
var classes = imgClass.split(' ');
for(var i = 0; i < classes.length; ++i){
$svg.classList.add(classes[i]);
}
}
$svg.removeAttribute('xmlns:a');
return $svg;
};
request.success(function(data){
element.replaceWith(scope.manipulateImgNode(data, element));
});
}
};
}]);
3. CSS:
.any-class-you-wish{
border: 1px solid red;
height: 300px;
width: 120px
}
4. Unit-test with karma-jasmine:
'use strict';
describe('Directive: svgImage', function() {
var $rootScope, $compile, element, scope, $httpBackend, apiUrl, data;
beforeEach(function() {
module('myApp');
inject(function($injector) {
$rootScope = $injector.get('$rootScope');
$compile = $injector.get('$compile');
$httpBackend = $injector.get('$httpBackend');
apiUrl = $injector.get('apiUrl');
});
scope = $rootScope.$new();
element = angular.element('<svg-image src="/icons/icon-man.svg" class="svg"></svg-image>');
element = $compile(element)(scope);
spyOn(scope, 'manipulateImgNode').andCallThrough();
$httpBackend.whenGET(apiUrl + 'me').respond(200, {});
data = '<?xml version="1.0" encoding="utf-8"?>' +
'<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->' +
'<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' +
'<!-- Obj -->' +
'<!-- Obj -->' +
'<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"' +
'width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">' +
'<g>' +
'<path fill="#F4A902" d=""/>' +
'<path fill="#F4A902" d=""/>' +
'</g>' +
'</svg>';
$httpBackend.expectGET('/icons/icon-man.svg').respond(200, data);
});
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should call manipulateImgNode atleast once', function () {
$httpBackend.flush();
expect(scope.manipulateImgNode.callCount).toBe(1);
});
it('should return correct result', function () {
$httpBackend.flush();
var result = scope.manipulateImgNode(data, element);
expect(result).toBeDefined();
});
it('should define classes', function () {
$httpBackend.flush();
var result = scope.manipulateImgNode(data, element);
var classList = ["svg"];
expect(result.classList[0]).toBe(classList[0]);
});
});
I realize you're wanting to accomplish this with CSS, but just a reminder in case it's a small, simple image - you can always pop it open in Notepad++ and change the path/whateverelement's fill:
<path style="fill:#010002;" d="M394.854,205.444c9.218-15.461,19.102-30.181,14.258-49.527
...
C412.843,226.163,402.511,211.451,394.854,205.444z"/>
It could save a ton of ugly script. Sorry if it's off-base, but sometimes the simple solutions can be overlooked.
...even swapping multiple svg images might be smaller in size than some of the code snippets for this question.
I wrote a directive to solve this issue with AngularJS. It is available here - ngReusableSvg.
It replaces the SVG element after it's been rendered, and places it inside a div element, making its CSS easily changeable. This helps using the same SVG file in different places using different sizes/colors.
The usage is simple:
<object oa-reusable-svg
data="my_icon.svg"
type="image/svg+xml"
class="svg-class"
height="30" // given to prevent UI glitches at switch time
width="30">
</object>
After that, you can easily have:
.svg-class svg {
fill: red; // whichever color you want
}
Here's a version for knockout.js based on the accepted answer:
Important: It does actually require jQuery too for the replacing, but I thought it may be useful to some.
ko.bindingHandlers.svgConvert =
{
'init': function ()
{
return { 'controlsDescendantBindings': true };
},
'update': function (element, valueAccessor, allBindings, viewModel, bindingContext)
{
var $img = $(element);
var imgID = $img.attr('id');
var imgClass = $img.attr('class');
var imgURL = $img.attr('src');
$.get(imgURL, function (data)
{
// Get the SVG tag, ignore the rest
var $svg = $(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);
}, 'xml');
}
};
Then just apply data-bind="svgConvert: true" to your img tag.
This solution completely replaces the img tag with a SVG and any additional bindings would not be respected.
There is an open source library called SVGInject that uses the onload attribute to trigger the injection. You can find the GitHub project at https://github.com/iconfu/svg-inject
Here is a minimal example using SVGInject:
<html>
<head>
<script src="svg-inject.min.js"></script>
</head>
<body>
<img src="image.svg" onload="SVGInject(this)" />
</body>
</html>
After the image is loaded the onload="SVGInject(this) will trigger the injection and the <img> element will be replaced by the contents of the SVG file provided in the src attribute.
It solves several issues with SVG injection:
SVGs can be hidden until injection has finished. This is important if a style is already applied during load time, which would otherwise cause a brief "unstyled content flash".
The <img> elements inject themselved automatically. If you add SVGs dynamically, you don't have to worry about calling the injection function again.
A random string is added to each ID in the SVG to avoid having the same ID multiple times in the document if an SVG is injected more than once.
SVGInject is plain Javascript and works with all browsers that support SVG.
Disclaimer: I am the co-author of SVGInject
Here's a no framework code, only pure js :
document.querySelectorAll('img.svg').forEach(function(element) {
var imgID = element.getAttribute('id')
var imgClass = element.getAttribute('class')
var imgURL = element.getAttribute('src')
xhr = new XMLHttpRequest()
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
var svg = xhr.responseXML.getElementsByTagName('svg')[0];
if(imgID != null) {
svg.setAttribute('id', imgID);
}
if(imgClass != null) {
svg.setAttribute('class', imgClass + ' replaced-svg');
}
svg.removeAttribute('xmlns:a')
if(!svg.hasAttribute('viewBox') && svg.hasAttribute('height') && svg.hasAttribute('width')) {
svg.setAttribute('viewBox', '0 0 ' + svg.getAttribute('height') + ' ' + svg.getAttribute('width'))
}
element.parentElement.replaceChild(svg, element)
}
}
xhr.open('GET', imgURL, true)
xhr.send(null)
})
If we have a greater number of such svg images we can also take the help of font-files.
Sites like https://glyphter.com/ can get us a font file from our svgs.
E.g.
#font-face {
font-family: 'iconFont';
src: url('iconFont.eot');
}
#target{
color: white;
font-size:96px;
font-family:iconFont;
}
You can use data-image for that. using data-image(data-URI) you can access SVG like inline.
Here is rollover effect using pure CSS and SVG.
I know it messy but you can do this way.
.action-btn {
background-size: 20px 20px;
background-position: center center;
background-repeat: no-repeat;
border-width: 1px;
border-style: solid;
border-radius: 30px;
height: 40px;
width: 60px;
display: inline-block;
}
.delete {
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg version='1.1' id='Capa_1' fill='#FB404B' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='482.428px' height='482.429px' viewBox='0 0 482.428 482.429' style='enable-background:new 0 0 482.428 482.429;' xml:space='preserve'%3e%3cg%3e%3cg%3e%3cpath d='M381.163,57.799h-75.094C302.323,25.316,274.686,0,241.214,0c-33.471,0-61.104,25.315-64.85,57.799h-75.098 c-30.39,0-55.111,24.728-55.111,55.117v2.828c0,23.223,14.46,43.1,34.83,51.199v260.369c0,30.39,24.724,55.117,55.112,55.117 h210.236c30.389,0,55.111-24.729,55.111-55.117V166.944c20.369-8.1,34.83-27.977,34.83-51.199v-2.828 C436.274,82.527,411.551,57.799,381.163,57.799z M241.214,26.139c19.037,0,34.927,13.645,38.443,31.66h-76.879 C206.293,39.783,222.184,26.139,241.214,26.139z M375.305,427.312c0,15.978-13,28.979-28.973,28.979H136.096 c-15.973,0-28.973-13.002-28.973-28.979V170.861h268.182V427.312z M410.135,115.744c0,15.978-13,28.979-28.973,28.979H101.266 c-15.973,0-28.973-13.001-28.973-28.979v-2.828c0-15.978,13-28.979,28.973-28.979h279.897c15.973,0,28.973,13.001,28.973,28.979 V115.744z'/%3e%3cpath d='M171.144,422.863c7.218,0,13.069-5.853,13.069-13.068V262.641c0-7.216-5.852-13.07-13.069-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C158.074,417.012,163.926,422.863,171.144,422.863z'/%3e%3cpath d='M241.214,422.863c7.218,0,13.07-5.853,13.07-13.068V262.641c0-7.216-5.854-13.07-13.07-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C228.145,417.012,233.996,422.863,241.214,422.863z'/%3e%3cpath d='M311.284,422.863c7.217,0,13.068-5.853,13.068-13.068V262.641c0-7.216-5.852-13.07-13.068-13.07 c-7.219,0-13.07,5.854-13.07,13.07v147.154C298.213,417.012,304.067,422.863,311.284,422.863z'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e ");
border-color:#FB404B;
}
.delete:hover {
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg version='1.1' id='Capa_1' fill='#fff' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='482.428px' height='482.429px' viewBox='0 0 482.428 482.429' style='enable-background:new 0 0 482.428 482.429;' xml:space='preserve'%3e%3cg%3e%3cg%3e%3cpath d='M381.163,57.799h-75.094C302.323,25.316,274.686,0,241.214,0c-33.471,0-61.104,25.315-64.85,57.799h-75.098 c-30.39,0-55.111,24.728-55.111,55.117v2.828c0,23.223,14.46,43.1,34.83,51.199v260.369c0,30.39,24.724,55.117,55.112,55.117 h210.236c30.389,0,55.111-24.729,55.111-55.117V166.944c20.369-8.1,34.83-27.977,34.83-51.199v-2.828 C436.274,82.527,411.551,57.799,381.163,57.799z M241.214,26.139c19.037,0,34.927,13.645,38.443,31.66h-76.879 C206.293,39.783,222.184,26.139,241.214,26.139z M375.305,427.312c0,15.978-13,28.979-28.973,28.979H136.096 c-15.973,0-28.973-13.002-28.973-28.979V170.861h268.182V427.312z M410.135,115.744c0,15.978-13,28.979-28.973,28.979H101.266 c-15.973,0-28.973-13.001-28.973-28.979v-2.828c0-15.978,13-28.979,28.973-28.979h279.897c15.973,0,28.973,13.001,28.973,28.979 V115.744z'/%3e%3cpath d='M171.144,422.863c7.218,0,13.069-5.853,13.069-13.068V262.641c0-7.216-5.852-13.07-13.069-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C158.074,417.012,163.926,422.863,171.144,422.863z'/%3e%3cpath d='M241.214,422.863c7.218,0,13.07-5.853,13.07-13.068V262.641c0-7.216-5.854-13.07-13.07-13.07 c-7.217,0-13.069,5.854-13.069,13.07v147.154C228.145,417.012,233.996,422.863,241.214,422.863z'/%3e%3cpath d='M311.284,422.863c7.217,0,13.068-5.853,13.068-13.068V262.641c0-7.216-5.852-13.07-13.068-13.07 c-7.219,0-13.07,5.854-13.07,13.07v147.154C298.213,417.012,304.067,422.863,311.284,422.863z'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e ");
background-color: #FB404B;
}
<a class="action-btn delete"> </a>
You can convert your svg to data url here
https://codepen.io/elliz/full/ygvgay
https://websemantics.uk/tools/svg-to-background-image-conversion/
Since SVG is basically code, you need just contents. I used PHP to obtain content, but you can use whatever you want.
<?php
$content = file_get_contents($pathToSVG);
?>
Then, I've printed content "as is" inside a div container
<div class="fill-class"><?php echo $content;?></div>
To finnaly set rule to container's SVG childs on CSS
.fill-class > svg {
fill: orange;
}
I got this results with a material icon SVG:
Mozilla Firefox 59.0.2 (64-bit) Linux
Google Chrome66.0.3359.181 (Build oficial) (64 bits) Linux
Opera 53.0.2907.37 Linux
The selected solution is fine if you want jQuery to process all svg elements in your DOM and your DOM is of reasonable size. But if your DOM is large and you decide to load parts of your DOM dynamically, it really makes no sense to have to rescan the entire DOM just to update svg elements. Instead, use a jQuery plugin to do this:
/**
* A jQuery plugin that loads an svg file and replaces the jQuery object with its contents.
*
* The path to the svg file is specified in the src attribute (which normally does not exist for an svg element).
*
* The width, height and class attributes in the loaded svg will be replaced by those that exist in the jQuery object's
* underlying html. Note: All other attributes in the original element are lost including the style attribute. Place
* any styles in a style class instead.
*/
(function ($) {
$.fn.svgLoader = function () {
var src = $(this).attr("src");
var width = this.attr("width");
var height = this.attr("height");
var cls = this.attr("class");
var ctx = $(this);
// Get the svg file and replace the <svg> element.
$.ajax({
url: src,
cache: false
}).done(function (html) {
let svg = $(html);
svg.attr("width", width);
svg.attr("height", height);
svg.attr("class", cls);
var newHtml = $('<a></a>').append(svg.clone()).html();
ctx.replaceWith(newHtml);
});
return this;
};
}(jQuery));
In your html, specify an svg element as follows:
<svg src="images/someSvgFile.svg" height="45" width="45" class="mySVGClass"/>
And apply the plugin:
$(".mySVGClass").svgLoader();
for :hover event animations we can left the styles inside svg file,
like a
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
rect {
fill:rgb(165,225,75);
stroke:none;
transition: 550ms ease-in-out;
transform-origin:125px 125px;
}
rect:hover {
fill:rgb(75,165,225);
transform:rotate(360deg);
}
</style>
</defs>
<rect x='50' y='50' width='150' height='150'/>
</svg>
check this on svgshare
.carousel-control-prev-icon {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='rgb(3,122,247)' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e");
}
chnage color : fill='rgb(3,122,247)'

Handle Youtube Embed restriction

I'm actually developping a JARVIS assistant
It will have a lot of module But i start with what was supposed an easy one.
the Youtube One. So my mainwindow who are fullscreen or hidden has a WebBrowser
private static string GetYouTubeVideoPlayerHTML(string videoCode)
{
var sb = new StringBuilder();
const string YOUTUBE_URL = #"http://www.youtube.com/embed/";
sb.Append("<html>");
sb.Append(" <head>");
sb.Append(" <meta name=\"viewport\" content=\"width=device-width; height=device-height;\">");
sb.Append(" </head>");
sb.Append(" <body marginheight=\"0\" marginwidth=\"0\" leftmargin=\"0\" topmargin=\"0\" style=\"overflow-y: hidden\">");
sb.Append($" <iframe width=\"100%\" height=\"100%\" src =\"{YOUTUBE_URL}{videoCode}?autoplay=1&showinfo=0&controls=0\" frameborder = \"0\" allowfullscreen>");
sb.Append(" </body>");
sb.Append("</html>");
return sb.ToString();
}
This return the string i use with WebBrowser.Navigate()
It work well but if the video has embeded restriction like VEVO i can't see it
https://www.youtube.com/embed/wfN4PVaOU5Q
Exemple here
One thing tell me its possible because in this site
http://codepen.io/Jebik/pen/ZLZQwX
The embeded work like a charm....
So it's probably something that i don't get about this restriction.
Any idéa and solution is welcomming.
But i would rather have a legit solution like "man you must register your domain and ask the page in https" than "you can hack this security by this method"
I found a way i don't know why its works
I use a server i have to upload a webpage
<!DOCTYPE html>
<html>
<body>
<div id="player"></div>
<script>
var player;
var body = document.body;
var html = document.documentElement;
var height = Math.max( body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight, html.offsetHeight );
var width = Math.max( body.scrollWidth, body.offsetWidth,
html.clientWidth, html.scrollWidth, html.offsetWidth );
window.onresize = resize;
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
function onYouTubeIframeAPIReady()
{
player = new YT.Player('player', {
height: height,
width: width,
playerVars: { 'autoplay': 1, 'controls': 0, 'showinfo': 0, 'enablejsapi':1, 'iv_load_policy':3, 'modestbranding':1, 'showinfo':0},
videoId: '<?php echo $_GET["v"]; ?>',
events: {
'onReady': onPlayerReady
}
});
}
function resize()
{
height = Math.max( body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight, html.offsetHeight );
width = Math.max( body.scrollWidth, body.offsetWidth,
html.clientWidth, html.scrollWidth, html.offsetWidth );
if(player != null)
{
player.setSize(width, height);
}
}
function onPlayerReady(event) {
event.target.playVideo();
}
function playVideo()
{
player.playVideo();
}
function pauseVideo()
{
player.pauseVideo();
}
</script>
</body>
</html>
The web page Must Be acces from https
I don't exactly know why
Maybe youtube use the certificat to know the real location of web site (checking where it is registred instead of the ip)
And after taht i change my WebBrowser.NavigateToString by a WebBrowser.Navigate($"https://domain.fr/youtube.php?v={VideoCode}");
In this way i have a youtube player in full screen in my WPF window and i can read most of the youtube video like VEVO limited one.
This is resolved but if anyone know why i'm curious to know

C# google maps api multiple markers

I want to create a simple windows form C# app that shows a google map with multiple markers from a list of Lat Long.
My app can include a web browser container in it.
Is there any google api for that?
I use a google dll to calculate routes automatically using in the Nugget Console the following code:
PM> Install-Package GoogleMapsApi
Not sure if it will serve you, but it has all the features of Google Maps on it, just know how to use. Use the google documentation to learn how to use it well: https://developers.google.com/maps/
Edit 1:
I use this query that return all possible routes in the veriable routes.
Namespaces:
using GoogleMapsApi;
using GoogleMapsApi.Entities.Directions.Request;
var request = new DirectionsRequest
{
Origin = employeeAdress,
Destination = companyAdress,
TravelMode = TravelMode.Transit,
Alternatives = true,
ApiKey = key,
DepartureTime = DateTime.Now
};
var routes = GoogleMaps.Directions.Query(request);
But using a free key that google gives to you, you have only 2500 requests per day.
Here is some code for an HTML page to be used inconjunction with WebBrowser:
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>GoogleMap</title>
<style type="text/css"> v\:* { behavior:url(#default#VML); } </style>
<script src="http://maps.google.com/maps/api/js?key=xxxxxxxxxxxxxx&sensor=false" type="text/javascript"></script>
<script type="text/javascript">
//======== Local Google API data ===========================================================
var map = null;
var overlayvew = null;
var geocoder = null;
// ======== Local controls ======================================================
var body_info_label = null ;
var body_map = null ;
//======== Local functions and Events ============================================
function load()
{
body_info_label = document.getElementById("body_info_label");
body_map = document.getElementById("body_map") ;
MapLoad(900,700,"H") ;
}
function MapLoad(Width,Height,MapType)
{
try
{
ToGM_SetMapSize(Width,Height) ;
var mapOptions =
{
center: new google.maps.LatLng(-25.363882, 131.044922),
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP,
// Add controls
mapTypeControl: false, scaleControl: true, streetViewControl:false,
overviewMapControl: false, overviewMapControlOptions: { opened: true }
};
map = new google.maps.Map(body_map,mapOptions);
}
catch (ex){ window.external.FromGM_Uninitialized() ; }
if (map != null)
{
geocoder = new google.maps.Geocoder();
ToGM_SetMapCenter(50.0,15.0,4); // Center and Zoom to Europe
ToGM_SetZoomControl (true ) ; // Create and Display zoom
ToGM_SetMapType (MapType) ; // Display according to map Type
ToGM_SetScaleControl(true ) ; // Create and Display scale
overlayview = new google.maps.OverlayView();
overlayview.draw = function() {};
overlayview.setMap(map);
// call to a C# procedure to indicate end of init
// window.external.FromGM_Initialized() ;
}
}
//======== Some functions that may be called from C# by .Net WebBrowser ================================
function ToGM_SetMapSize(Width,Height)
{
if (body_info_label!=null) Height=Height-15 ;
body_map.style.width =Width +"px" ;
body_map.style.height=Height+"px" ;
if (map!=null) google.maps.event.trigger(map, 'resize');
}
function ToGM_SetMapCenter(Lat,Lon,Zoom)
{ if (map!=null) {
if (Zoom==null) Zoom = map.getZoom() ;
var Center ;
if (Lat==null) Center = map.getCenter() ;
else Center = new google.maps.LatLng(Lat,Lon);
map.setCenter(Center) ;
map.setZoom(Zoom);
}}
function ToGM_SetZoomControl(On)
{
if (map!=null) map.setOptions({zoomControl:On}) ;
}
function ToGM_SetScaleControl(On)
{
if (map!=null) map.setOptions({scaleControl:On }) ;
}
function ToGM_SetMapType(MapType) // String MapType = "N"/"S"/"H"/"P"
{if (map!=null) {
if (MapType=="N") map.setMapTypeId(google.maps.MapTypeId.ROADMAP );
if (MapType=="S") map.setMapTypeId(google.maps.MapTypeId.SATELLITE );
if (MapType=="H") map.setMapTypeId(google.maps.MapTypeId.HYBRID );
if (MapType=="P") map.setMapTypeId(google.maps.MapTypeId.TERRAIN );
}}
</script>
</head>
<body
onload="load()" onunload="unload()">
<div id="body_map" style="width: 1000px; height: 600px"></div>
</body>
</html>

dynamic tooltips doesn't work

I am trying to create a dynamic tooltips to my application however this is not working, can I have some idea?
below is the my code that try to retrieve tools tip through java scripting.
<input type="text" tooltipid="testfamily" onclick="tooltipshow(this);" id="family"
value="family " />
<script type="text/javascript" src="Scripts/jquery-1.4.1.min.js"></script>
<script type="text/javascript">
var data = {
name: "enter your name",
family: "enter your family",
testfamily: "enter your family",
uc1_txtname: "enter your name for Control 1 (User Control1)",
uc2_txtname: "enter your name for Control 2 (User Control2)"
}
function tooltipshow(e) {
var Tip = $("<div class='dinamictip'></div>");
Tip.text('');
var ToolTip = $(e).attr('tooltipid');
if (ToolTip != null) {
var offset = $(e).offset();
var height = $(e).height() + 10;
Tip.text(data[ToolTip]);
Tip.css('position', 'absolute').css('left', offset.left).css('top', offset.top - height);
Tip.appendTo('body');
Tip.remove();
}
};
I didn't tested your code, but probably the culprit is Tip.remove();: you are deleting the tip as soon as you create it.
Try this change in your tooltipshow function: the first time this code executes, it won't find the tool tip's div, so it will create it and will add it to the body (hidden, for now). Then, the next time you call the code, it will find the old tool tip and will reuse it.
function tooltipshow(e) {
var Tip = $("#mydinamictip");
if(Tip.length==0){
Tip = $("<div id='mydinamictip' class='dinamictip'></div>");
Tip.hide().appendTo('body');
}
Tip.text('');
var ToolTip = $(e).attr('tooltipid');
if (ToolTip != null) {
var offset = $(e).offset();
var height = $(e).height() + 10;
Tip.text(data[ToolTip]);
Tip.css('position', 'absolute').css('left', offset.left).css('top', offset.top - height);
Tip.show();
}
};

Implementing javascript in c# code behind

Morning all.
I have the following javascript in my code in front
<script type="text/javascript" src="~/VDSReporting/jquery.js"></script> <script type="text/javascript">
function ShowImage() {
document.getElementById('tbxProdAC')
.style.backgroundImage = 'url(/images/vds/progress.gif)';
document.getElementById('tbxProdAC')
.style.backgroundRepeat = 'no-repeat';
document.getElementById('tbxProdAC')
.style.backgroundPosition = 'right';
}
function HideImage() {
document.getElementById('tbxProdAC')
.style.backgroundImage = 'none';
}
</script>
How do I go about 'converting' this and only having it present in c# code behind?
Please excuse my ignorance, I'm completely out of my depth here!
If this is a progress image you are showing (seems so from the image name), then why would you want to do that server side? That will kind of defeat the whole purpose of a progress image. This seem like it belong on the client side, so keep it there.
Update
You don't need to use the code behind to render the script just to get the client id's. You can do something like this:
function ShowImage() {
document.getElementById('<%=tbxProdAC.ClientID%>')
.style.backgroundImage = 'url(/images/vds/progress.gif)';
document.getElementById('<%=tbxProdAC.ClientID%>')
.style.backgroundRepeat = 'no-repeat';
document.getElementById('<%=tbxProdAC.ClientID%>')
.style.backgroundPosition = 'right';
}
function HideImage() {
document.getElementById('<%=tbxProdAC.ClientID%>')
.style.backgroundImage = 'none';
}
Here I use <%=tbxProdAC.ClientID%> to get the id of the control. This is a lot more readable then using the code behind to render the script.
I need some javascript to be run from the server side and this worked for me -
if (!this.ClientScript.IsStartupScriptRegistered("StartDown"))
{
string scriptString = #"alert(""some javascript"");location.href='MyPage.aspx';";
this.ClientScript.RegisterStartupScript(Page.GetType(), "StartDown", scriptString, true);
}
Hope this helps..

Categories