Skip to content

Commit a5dd552

Browse files
committed
adding support for SVG, refactoring and adding the example of using Introjs with SVG elements
1 parent 315762a commit a5dd552

File tree

6 files changed

+162
-152
lines changed

6 files changed

+162
-152
lines changed

example/index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ <h3 class="muted">Examples</h3>
3232
<li><a href="html-tooltip/index.html" title='HTML in tooltip'>HTML in tooltip</a></li>
3333
<li><a href="custom-class/index.html" title='Custom CSS Class'>Custom CSS Class</a></li>
3434
<li><a href="withoutElement/index.html" title='Introduction without focusing on elements'>Introduction without focusing on elements</a></li>
35+
<li><a href="bootstrap/v3/index.html" title='Using with Bootstrap v3.0'>Using with Bootstrap v3.0</a></li>
36+
<li><a href="svg/d3.htm" title='Using Introjs with SVG Element'>Using with SVG Elements (D3)</a></li>
3537
<li><a href="hint/index.html" title='Basic hints usage'>Basic hints usage</a></li>
3638
<li><a href="programmatic/hint.html" title='Programmatic defining hints using JSON'>Programmatic defining hints using JSON</a></li>
3739
</ul>

example/multi-page/second.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<div class="container-narrow">
2323

2424
<div class="masthead">
25-
<ul class="nav nav-pills pull-right" data-step="5" data-intro="Get it, use it.">
25+
<ul class="nav nav-pills pull-right" data-intro="Get it, use it.">
2626
<li><a href="https://github.com/usablica/intro.js/tags"><i class='icon-black icon-download-alt'></i> Download</a></li>
2727
<li><a href="https://github.com/usablica/intro.js">Github</a></li>
2828
<li><a href="https://twitter.com/usablica">@usablica</a></li>
@@ -34,7 +34,7 @@ <h3 class="muted">Intro.js</h3>
3434

3535
<div class="jumbotron">
3636
<h1>Second Page</span></h1>
37-
<p class="lead" data-step="4" data-intro="Another step.">Next page of introduction!</p>
37+
<p class="lead" data-intro="Another step.">Next page of introduction!</p>
3838
</div>
3939

4040
<hr>

example/svg/d3.htm

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,54 @@
11
<!DOCTYPE html>
2-
<!-- saved from url=(0106)http://bl.ocks.org/mbostock/raw/22994cc97fefaeede0d861e6815a847e/7796e0942d11162d512503cec3351f689125eb7f/ -->
3-
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4-
<style>
5-
6-
.active {
7-
stroke: #000;
8-
stroke-width: 2px;
9-
}
10-
11-
</style>
12-
13-
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Multi-page introduction, Page 1</title>
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<meta name="description" content="Intro.js - Better introductions for websites and features with a step-by-step guide for your projects.">
8+
<meta name="author" content="Afshin Mehrabani (@afshinmeh) in usabli.ca group">
149

1510
<!-- styles -->
1611
<link href="../assets/css/bootstrap.min.css" rel="stylesheet">
1712
<link href="../assets/css/demo.css" rel="stylesheet">
1813

1914
<!-- Add IntroJs styles -->
2015
<link href="../../introjs.css" rel="stylesheet">
21-
2216
<link href="../assets/css/bootstrap-responsive.min.css" rel="stylesheet">
23-
24-
25-
</head>
26-
27-
<body>
28-
<h1 data-intro="Headline">SVG Example</h1>
29-
<svg width="960" height="500">
30-
<circle data-intro="hello" cx="429" cy="260" r="32" style="fill: rgb(31, 119, 180); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle>
31-
<circle data-intro="second step intro" cx="171" cy="112" r="32" style="fill: rgb(174, 199, 232); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle>
32-
<circle cx="414" cy="51" r="32" style="fill: rgb(255, 127, 14); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="177" cy="464" r="32" style="fill: rgb(255, 187, 120); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="680" cy="378" r="32" style="fill: rgb(44, 160, 44); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="477" cy="68" r="32" style="fill: rgb(152, 223, 138); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="867" cy="395" r="32" style="fill: rgb(214, 39, 40); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="572" cy="327" r="32" style="fill: rgb(255, 152, 150); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="87" cy="427" r="32" style="fill: rgb(148, 103, 189); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="41" cy="273" r="32" style="fill: rgb(197, 176, 213); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="382" cy="443" r="32" style="fill: rgb(140, 86, 75); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="135" cy="57" r="32" style="fill: rgb(196, 156, 148); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="821" cy="144" r="32" style="fill: rgb(227, 119, 194); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="539" cy="272" r="32" style="fill: rgb(247, 182, 210); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="886" cy="93" r="32" style="fill: rgb(127, 127, 127); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="74" cy="181" r="32" style="fill: rgb(199, 199, 199); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="526" cy="299" r="32" style="fill: rgb(188, 189, 34); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="434" cy="57" r="32" style="fill: rgb(219, 219, 141); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="722" cy="394" r="32" style="fill: rgb(23, 190, 207); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="809" cy="139" r="32" style="fill: rgb(158, 218, 229); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle>
33-
</svg>
34-
35-
36-
<script src="./d3_files/d3.v4.min.js"></script>
37-
17+
</head>
18+
19+
<body>
20+
<div class="container-narrow">
21+
<div class="masthead">
22+
<ul class="nav nav-pills pull-right">
23+
<li><a href="https://github.com/usablica/intro.js/tags"><i class='icon-black icon-download-alt'></i> Download</a></li>
24+
<li><a href="https://github.com/usablica/intro.js">Github</a></li>
25+
<li><a href="https://twitter.com/usablica">@usablica</a></li>
26+
</ul>
27+
<h3 class="muted">Intro.js</h3>
28+
</div>
29+
30+
<hr>
31+
32+
<div class="jumbotron">
33+
<h1 data-intro="This is a tooltip!">SVG</h1>
34+
<p class="lead">Using Introjs for SVG Element</p>
35+
<a id="startButton" class="btn btn-large btn-success" href="javascript:void(0);">Show me how</a>
36+
</div>
37+
38+
<hr>
39+
40+
<svg width="960" height="500">
41+
<circle data-intro="hello" cx="429" cy="260" r="32" style="fill: rgb(31, 119, 180); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle>
42+
<circle data-intro="second step intro" cx="171" cy="112" r="32" style="fill: rgb(174, 199, 232); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle>
43+
<circle cx="414" cy="51" r="32" style="fill: rgb(255, 127, 14); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="177" cy="464" r="32" style="fill: rgb(255, 187, 120); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="680" cy="378" r="32" style="fill: rgb(44, 160, 44); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="477" cy="68" r="32" style="fill: rgb(152, 223, 138); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="867" cy="395" r="32" style="fill: rgb(214, 39, 40); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="572" cy="327" r="32" style="fill: rgb(255, 152, 150); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="87" cy="427" r="32" style="fill: rgb(148, 103, 189); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="41" cy="273" r="32" style="fill: rgb(197, 176, 213); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="382" cy="443" r="32" style="fill: rgb(140, 86, 75); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="135" cy="57" r="32" style="fill: rgb(196, 156, 148); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="821" cy="144" r="32" style="fill: rgb(227, 119, 194); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="539" cy="272" r="32" style="fill: rgb(247, 182, 210); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="886" cy="93" r="32" style="fill: rgb(127, 127, 127); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="74" cy="181" r="32" style="fill: rgb(199, 199, 199); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="526" cy="299" r="32" style="fill: rgb(188, 189, 34); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="434" cy="57" r="32" style="fill: rgb(219, 219, 141); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="722" cy="394" r="32" style="fill: rgb(23, 190, 207); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle><circle cx="809" cy="139" r="32" style="fill: rgb(158, 218, 229); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></circle>
44+
</svg>
45+
46+
</div>
3847
<script type="text/javascript" src="../../intro.js"></script>
39-
</body></html>
48+
<script type="text/javascript">
49+
document.getElementById('startButton').onclick = function() {
50+
introJs().start();
51+
};
52+
</script>
53+
</body>
54+
</html>

example/svg/d3_files/d3.v4.min.js

Lines changed: 0 additions & 8 deletions
This file was deleted.

intro.js

Lines changed: 67 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Intro.js v2.4.0
2+
* Intro.js v2.5.0
33
* https://github.com/usablica/intro.js
44
*
55
* Copyright (C) 2016 Afshin Mehrabani (@afshinmeh)
@@ -18,7 +18,7 @@
1818
}
1919
} (this, function (exports) {
2020
//Default config/variables
21-
var VERSION = '2.4.0';
21+
var VERSION = '2.5.0';
2222

2323
/**
2424
* IntroJs main class
@@ -401,12 +401,7 @@
401401
floatingElement.parentNode.removeChild(floatingElement);
402402
}
403403

404-
//remove `introjs-showElement` class from the element
405-
var showElement = document.querySelector('.introjs-showElement');
406-
if (showElement) {
407-
_removeClass(showElement, /introjs-[a-zA-Z]+/g);
408-
//showElement.className = showElement.className.replace(/introjs-[a-zA-Z]+/g, '').replace(/^\s+|\s+$/g, ''); // This is a manual trim.
409-
}
404+
_removeShowElement();
410405

411406
//remove `introjs-fixParent` class from the elements
412407
var fixParents = document.querySelectorAll('.introjs-fixParent');
@@ -491,10 +486,6 @@
491486
tooltipOffset = _getOffset(tooltipLayer);
492487
windowSize = _getWinSize();
493488

494-
console.log(targetElement)
495-
console.log(targetOffset)
496-
console.log(tooltipOffset)
497-
498489
switch (currentTooltipPosition) {
499490
case 'top':
500491
arrowLayer.className = 'introjs-arrow bottom';
@@ -712,28 +703,6 @@
712703
elementPosition = _getOffset(currentElement.element),
713704
widthHeightPadding = 10;
714705

715-
716-
console.log('go', currentElement)
717-
718-
//add target element position style
719-
if (currentElement instanceof SVGElement) {
720-
console.log('boo')
721-
var parentElm = currentElement.parentNode;
722-
723-
while (currentElement.parentNode != null) {
724-
if (!parentElm.tagName || parentElm.tagName.toLowerCase() === 'body') break;
725-
726-
if (parentElm.tagName.toLowerCase() === 'svg') {
727-
conosle.log(
728-
'found parent'
729-
)
730-
currentElement = parentElm;
731-
}
732-
733-
parentElm = parentElm.parentNode;
734-
}
735-
}
736-
737706
// If the target element is fixed, the tooltip should be fixed as well.
738707
// Otherwise, remove a fixed class that may be left over from the previous
739708
// step.
@@ -847,10 +816,7 @@
847816
}
848817

849818
//remove old classes if the element still exist
850-
var oldShowElement = document.querySelector('.introjs-showElement');
851-
if (oldShowElement) {
852-
_removeClass(oldShowElement, /introjs-[a-zA-Z]+/g);
853-
}
819+
_removeShowElement();
854820

855821
//we should wait until the CSS3 transition is competed (it's 0.3 sec) to prevent incorrect `height` and `width` calculation
856822
if (self._lastShowElementTimer) {
@@ -888,6 +854,7 @@
888854
}
889855
}, 350);
890856

857+
// end of old element if-else condition
891858
} else {
892859
var helperLayer = document.createElement('div'),
893860
referenceLayer = document.createElement('div'),
@@ -1024,6 +991,8 @@
1024991

1025992
//set proper position
1026993
_placeTooltip.call(self, targetElement.element, tooltipLayer, arrowLayer, helperNumberLayer);
994+
995+
//end of new element if-else condition
1027996
}
1028997

1029998
//disable interaction
@@ -1067,25 +1036,70 @@
10671036
//Set focus on "next" button, so that hitting Enter always moves you onto the next step
10681037
nextTooltipButton.focus();
10691038

1070-
//add target element position style
1039+
_setShowElement(targetElement);
1040+
1041+
if (!_elementInViewport(targetElement.element) && this._options.scrollToElement === true) {
1042+
var rect = targetElement.element.getBoundingClientRect(),
1043+
winHeight = _getWinSize().height,
1044+
top = rect.bottom - (rect.bottom - rect.top),
1045+
bottom = rect.bottom - winHeight;
1046+
1047+
//Scroll up
1048+
if (top < 0 || targetElement.element.clientHeight > winHeight) {
1049+
window.scrollBy(0, top - this._options.scrollPadding); // 30px padding from edge to look nice
1050+
1051+
//Scroll down
1052+
} else {
1053+
window.scrollBy(0, bottom + 70 + this._options.scrollPadding); // 70px + 30px padding from edge to look nice
1054+
}
1055+
}
1056+
1057+
if (typeof (this._introAfterChangeCallback) !== 'undefined') {
1058+
this._introAfterChangeCallback.call(this, targetElement.element);
1059+
}
1060+
}
1061+
1062+
/**
1063+
* To remove all show element(s)
1064+
*
1065+
* @api private
1066+
* @method _removeShowElement
1067+
*/
1068+
function _removeShowElement() {
1069+
var elms = document.querySelectorAll('.introjs-showElement');
1070+
1071+
for (var i = 0, l = elms.length; i < l; i++) {
1072+
var elm = elms[i];
1073+
_removeClass(elm, /introjs-[a-zA-Z]+/g);
1074+
}
1075+
}
1076+
1077+
/**
1078+
* To set the show element
1079+
* This function set a relative (in most cases) position and changes the z-index
1080+
*
1081+
* @api private
1082+
* @method _setShowElement
1083+
* @param {Object} targetElement
1084+
*/
1085+
function _setShowElement(targetElement) {
1086+
// we need to add this show element class to the parent of SVG elements
1087+
// because the SVG elements can't have independent z-index
10711088
if (targetElement.element instanceof SVGElement) {
10721089
var parentElm = targetElement.element.parentNode;
10731090

10741091
while (targetElement.element.parentNode != null) {
10751092
if (!parentElm.tagName || parentElm.tagName.toLowerCase() === 'body') break;
10761093

10771094
if (parentElm.tagName.toLowerCase() === 'svg') {
1078-
_setClass(parentElm, 'introjs-showElement introjs-relativePosition')
1095+
_setClass(parentElm, 'introjs-showElement introjs-relativePosition');
10791096
}
10801097

10811098
parentElm = parentElm.parentNode;
10821099
}
1083-
} else {
1084-
//targetElement.element.node.className += ' introjs-showElement';
1085-
_setClass(targetElement.element, 'introjs-showElement')
10861100
}
10871101

1088-
console.log(parentElm)
1102+
_setClass(targetElement.element, 'introjs-showElement');
10891103

10901104
var currentElementPosition = _getPropValue(targetElement.element, 'position');
10911105
if (currentElementPosition !== 'absolute' &&
@@ -1111,26 +1125,6 @@
11111125

11121126
parentElm = parentElm.parentNode;
11131127
}
1114-
1115-
if (!_elementInViewport(targetElement.element) && this._options.scrollToElement === true) {
1116-
var rect = targetElement.element.getBoundingClientRect(),
1117-
winHeight = _getWinSize().height,
1118-
top = rect.bottom - (rect.bottom - rect.top),
1119-
bottom = rect.bottom - winHeight;
1120-
1121-
//Scroll up
1122-
if (top < 0 || targetElement.element.clientHeight > winHeight) {
1123-
window.scrollBy(0, top - this._options.scrollPadding); // 30px padding from edge to look nice
1124-
1125-
//Scroll down
1126-
} else {
1127-
window.scrollBy(0, bottom + 70 + this._options.scrollPadding); // 70px + 30px padding from edge to look nice
1128-
}
1129-
}
1130-
1131-
if (typeof (this._introAfterChangeCallback) !== 'undefined') {
1132-
this._introAfterChangeCallback.call(this, targetElement.element);
1133-
}
11341128
}
11351129

11361130
function _setClass(element, className) {
@@ -1141,7 +1135,7 @@
11411135
} else {
11421136
element.className += ' ' + className;
11431137
}
1144-
};
1138+
}
11451139

11461140
function _removeClass(element, classNameRegex) {
11471141
if (element instanceof SVGElement) {
@@ -1660,12 +1654,18 @@
16601654
function _getOffset(element) {
16611655
var elementPosition = {};
16621656

1657+
var body = document.body;
1658+
var docEl = document.documentElement;
1659+
1660+
var scrollTop = window.pageYOffset || docEl.scrollTop || body.scrollTop;
1661+
var scrollLeft = window.pageXOffset || docEl.scrollLeft || body.scrollLeft;
1662+
16631663
if (element instanceof SVGElement) {
16641664
var x = element.getBoundingClientRect()
1665-
elementPosition.top = x.top;
1665+
elementPosition.top = x.top + scrollTop;
16661666
elementPosition.width = x.width;
16671667
elementPosition.height = x.height;
1668-
elementPosition.left = x.left;
1668+
elementPosition.left = x.left + scrollLeft;
16691669
} else {
16701670
//set width
16711671
elementPosition.width = element.offsetWidth;

0 commit comments

Comments
 (0)