Triggering a script after loading from an internal link - svg

I am using an SVG element on page A with a href link to page B-- page B has a script that calls the Trianglify api to generate the background.
However, if you navigate to page B by clicking this link, the script doesn't trigger. If you refresh the page on page B, the script triggers and the background works.
Can someone help me figure out how to trigger this script just on the click to the href element?
(application is written w/ express/node and handlebars)
This is how I am triggering it:
<div id="something"></div>
<script>
var f = function(e) {
console.log("ready");
var something = document.getElementById('something');
var dimensions = something.getClientRects()[0];
var pattern = Trianglify({
width: dimensions.width,
height: dimensions.height
});
something.appendChild(pattern.canvas());
}
$("document").ready(f);
</script>
and then here's the button on page A--
<a href="/contact" class="under animated fadeInRight">
<rect x="100" y="15" width="10" height="10"/>
<text x="117" y="25" style="opacity:.5;font-size:15px">CONTACT</text>
</a>

Related

Material Design Icon (MDI) inside SVG graphic?

In my application I need to use the same icon in different places.
in v-card-action's button
in a SVG graphic
For the button it is as explained in vuetify documentation:
<v-card-actions>
<v-btn value="previous" color="red" >
<span class="hidden-sm-and-down">Previous</span>
<v-icon right>mdi-arrow-left-circle</v-icon>
</v-btn>
</v-card-actions>
But now, how to use the exact same icon (using it's name) in a custom SVG
<svg viewBox="0 0 100 100">
<rec x="0" y="0" width="100" height="100" stroke="grey" />
<???> mdi-arrow-left-circle </???>
</svg>
First, do i need to use SVG <img>, <text> or <path> primitive ?
Second, how do i get the proper icon from it's name mdi-arrow-left-circle ?
I had the exact same question. This link came in handy when putting this together:
How do I include a font awesome icon in my svg?
Disclaimer: I'm using TS components in Vue and have added Vuetify.
in the template I have a SVG:
<svg>
<text
x="100"
y="100"
class="licon"
fill="red">
{{ content('mdi-close') }}
</text>
</svg>
The content method does this:
content(cls: string): string {
// this copies the content from the pseudo element :before as it's needed to show the icon from material design
const ele = document.querySelector('.' + cls);
if(ele) {
const styles = window.getComputedStyle(ele, ':before');
return styles.content.replaceAll('"', "");
}
return '';
}
The last piece needed was to make sure to use the correct font (include in your stylesheet/etc):
.licon {
font: bold 300px 'Material Design Icons';
}
Hopefully this helps someone else.

How to click on svg element using xpath with document.evaluate

I need to click on an add button, when i am inspecting it, i am getting a xpath
//li[text()='Alabama']//ancestor::ul//li[2]//*[local-name()='svg']
the HTML code is given below
<div class="available-state-list scroll-bar">
<ul>
<li>Alabama</li>
<li><svg width="16" height="15" viewBox="0 0 16 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3.00774 2.16391C0.246501 4.93321 0.246501 9.43934 3.00774 12.2087C5.76898 14.978 10.262 14.978 13.0232 12.2087C15.7845 9.43934 15.7845 4.93322 13.0232 2.16391C10.262 -0.605398 5.76898 -0.605398 3.00774 2.16391ZM11.0972 6.6401C11.1699 6.63823 11.2422 6.65098 11.3099 6.67759C11.3776 6.70419 11.4393 6.74413 11.4914 6.79503C11.5434 6.84593 11.5848 6.90677 11.6131 6.97397C11.6413 7.04116 11.6559 7.11335 11.6559 7.18628C11.6559 7.25921 11.6413 7.33139 11.6131 7.39859C11.5848 7.46579 11.5434 7.52663 11.4914 7.57753C11.4393 7.62843 11.3776 7.66836 11.3099 7.69497C11.2422 7.72158 11.1699 7.73433 11.0972 7.73246L8.56031 7.7327L8.56007 10.277C8.55643 10.4194 8.49746 10.5548 8.39573 10.6542C8.29399 10.7537 8.15755 10.8093 8.01548 10.8093C7.87341 10.8093 7.73697 10.7537 7.63523 10.6542C7.5335 10.5548 7.47452 10.4194 7.47089 10.277L7.47065 7.7327L4.93379 7.73246C4.79177 7.72881 4.65679 7.66967 4.55763 7.56764C4.45847 7.46561 4.40297 7.32876 4.40297 7.18628C4.40297 7.0438 4.45847 6.90695 4.55763 6.80492C4.65679 6.70289 4.79177 6.64374 4.93379 6.6401L7.47065 6.63985L7.47089 4.09559C7.47452 3.95315 7.5335 3.81778 7.63523 3.71833C7.73697 3.61888 7.87341 3.56322 8.01548 3.56322C8.15755 3.56322 8.29399 3.61888 8.39573 3.71833C8.49746 3.81778 8.55643 3.95315 8.56007 4.09559L8.56031 6.63985L11.0972 6.6401Z" fill="#1D54B4">
</path>
</svg>
</li>
</ul>
<ul>......</ul>
<ul>......</ul>
</div>
so i tried to click on that svg element using below code
function getElementByXpath(path) {
return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
}
getElementByXpath("//li[text()='Alabama']//ancestor::ul//li[2]//*[local-name()='svg']").click();
i have seen one solution in Extract <svg> element by using document.evaluate()? .So tried it in my code as given below
document.evaluate("//li[text()='Alabama']//ancestor::ul//li[2]//svg:*[local-name()='svg']", document,
function(prefix) {
if (prefix === 'svg')
{
return 'http://www.w3.org/2000/svg';
}
else
{
return null;
}
}, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.click();
but it shows an error as document.evaluate(...).singleNodeValue.click is not function. Am i going wrong? Can any one help to click on this element using xpath expression? Thanks in advance.

SVG <use xlink:href> from a CDN

I am using the <use xlink:href> to reference my svg file.
It works fine on my local but throws an error (CORS) when I reference it from a CDN. It looks as though the xlink:href doesn't allow the CORS request but I am wondering if there is any solution?
On the other hand, I have heard that this sprite technique is deprecated on SVG2. So what is the best solution to use sprite SVG file for now that works on all different browsers including mobile browsers.
The simplest cross-browser solution I've found is to fetch the SVG sprite via ajax and embed it in your page:
<div id="svg-container" style="display: none"></div>
<script>
!function() {
var xhr = new XMLHttpRequest();
xhr.open("GET", '/path/to/cdn/sprite.svg');
xhr.onload = function() {
document.getElementById('svg-container').innerHTML = xhr.responseText;
}
xhr.send();
}();
</script>
This also saves you from specifying the SVG sprite's URL in xlink:href
<svg>
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#heart"></use>
</svg>

include Facebook Pixel Code js in orchard

I need to add Facebook Pixel Code script in head section of every page.
<!-- Facebook Pixel Code -->
<script>
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
document,'script','//connect.facebook.net/en_US/fbevents.js');
fbq('init', 'xxx');
fbq('track', "PageView");</script>
<noscript><img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id=xxx&ev=PageView&noscript=1"
/></noscript>
<!-- End Facebook Pixel Code -->
How can get this?
I recently started working on orchard. I read about edit cshtml or edit the theme...
Thanks
There should be a Layout.cshtml file in your themes directory, where you can add the script like this:
#using ( Script.Head() )
{
<!-- Facebook Pixel Code -->
<script>
!function (f, b, e, v, n, t, s) {
if (f.fbq) return; n = f.fbq = function () {
n.callMethod ?
n.callMethod.apply(n, arguments) : n.queue.push(arguments)
}; if (!f._fbq) f._fbq = n;
n.push = n; n.loaded = !0; n.version = '2.0'; n.queue = []; t = b.createElement(e); t.async = !0;
t.src = v; s = b.getElementsByTagName(e)[0]; s.parentNode.insertBefore(t, s)
}(window,
document, 'script', '//connect.facebook.net/en_US/fbevents.js');
fbq('init', 'xxx');
fbq('track', "PageView");</script>
<noscript>
<img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id=xxx&ev=PageView&noscript=1" />
</noscript>
<!-- End Facebook Pixel Code -->
}
Alternatively, you could copy the Document.cshtml located in *Orchard.Web\Core\Shapes\Views* into your theme and insert the script directly in the head section.

Using Meteor to create SVG in template works, but not in #each loop

Update: as of February 2014, Meteor supports reactive SVG, so no workaround is necessary.
Meteor 0.5.9
I would like to create a group of shapes, one for each document in the collection. I can create shapes one at a time in a template, but not inside of an {{#each loop}}.
This works:
<Template name="map">
<svg viewBox="0 0 500 600" version="1.1">
<rect x="0" y="0" width="100" height="100" fill={{color}}/>
</svg>
</Template>
Template.map.color = function() {
return "green";
};
This does not:
<Template name="map">
<svg viewBox="0 0 500 600" version="1.1">
{{#each colors}}
<rect x="0" y="0" width="100" height="100" fill={{color}}/>
{{/each}}
</svg>
</Template>
Template.map.colors = function() {
return [{color: "red"}, {color: "blue"}];
}
Anything I try to create inside of using {{#each}} just doesn't show up, even though I can create them manually, even with attributes inserted by Meteor through the template.
I also tried just sending a single object {color: "red"} to the template and using {{#with colors}}, and that does not work either. In addition to the SVG, I've also put plain s into the templates to make sure information gets to the template correctly, and those are all working as expected, with {{#each}} and with {{#with}}.
Should I be able to do what I'm trying to do?
(Updated April 1, 2013)
Found a way that combines Handlebars with insertion by Javascript. Have to give credit to this blog entry for figuring this one out:
http://nocircleno.com/blog/svg-and-handlebars-js-templates/
I created the following two files, placed them inside the client folder of a new Meteor directory and I got the html successfully.
Testing.js:
<head>
<title>testing</title>
</head>
<body>
</body>
<template name="map">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
{{#each colors}}
<rect x="0" y="{{yPosition}}" width="100" height="100" fill="{{color}}"/>
{{/each}}
</svg>
</template>
Testing.html:
(function () {
var count = 0;
Template.map.yPosition = function() {
count++;
return (count-1) * 100;
};
Template.map.colors = function() {
return [{color: "red"}, {color: "blue"}];
};
Meteor.startup(function() {
var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svgElement.width = 500;
svgElement.height = 600;
document.getElementsByTagName("body")[0].appendChild(svgElement);
var svgFragment = new DOMParser().parseFromString(Template.map(), "text/xml");
svgElement.appendChild(svgFragment.documentElement);
});
})();
I came across the same problem experimenting with Meteor and SVG elements and discovered that you can add elements and get them to show up with the two methods below. One option is to just wrap the elements in the each loop in an <svg></svg>, like this:
<svg viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
{{#each pieces}}
<svg xmlns="http://www.w3.org/2000/svg"><circle cx="{{x}}" cy="{{y}}" r="1" fill="{{color}}"></circle></svg>
{{/each}}
</svg>
Another options is to (on template render) create an svg element with jQuery that contains the element you want to insert, then use jQuery to grab that inner element and insert it into the svg element already in the DOM, like so (in coffeescript):
for piece in Pieces.find().fetch()
$el = $("<svg><circle cx='#{piece.x}' cy='#{piece.y}' r='1' class='a'></circle></svg>")
$el.find('circle').appendTo #$('svg')
You could also use something like d3 or RaphaelJS to do the inserting. You can even make the individual elements reactive to your Collection and animate easily by using a library like d3 in the Collection observer callbacks like so (again, coffeescript):
Pieces.find().observe {
added: (piece)=>
# using jquery (could use d3 instead)
$el = $("<svg><circle cx='#{piece.x}' cy='#{piece.y}' r='1' fill='#{piece.color}' data-id='#{piece._id}'></circle></svg>")
$el.find('circle').appendTo #$('svg')
changed: (newPiece, oldPiece)=>
# using d3 to animate change
d3.select("[data-id=#{oldPiece._id}]").transition().duration(1000).attr {
cx: newPiece.x
cy: newPiece.y
fill: newPiece.color
}
removed: (piece)=>
#$("[data-id=#{piece._id}]").remove()
}
These methods seem to work in latest Chrome, Safari, Firefox browsers on Mac, but I haven't tested in others.
According to the Using Blaze page, Meteor will have first class support of SVG when Blaze is released.

Resources