In three.js does not work material selection through span - javascript

At first, span worked for me, then I set up materialsLib and initMaterialSelectionMenus from documentation and examples, but now or the span does not work, then the model does not appear.
Help, please!
UPD
The problem was in the functions. Apparently they were looped or something like that.
Some of code
main.html:
<canvas id="c" width="100" height="100" allowtransparency frameborder="no" scrolling="yes"</canvas>
<div id="menu">
<div></div>
<span>Kar color: <select id="kar-mat"></select></span><br/><br/>
<span>Prof color: <select id="pro-mat"></select></span>
</div>
<style>
#c {width: 100px; height: 100px; display: block;}
#menu {position: absolute; left: 1em; top: 1em; padding: 1em; background: rgba(0, 0, 0, 0.8); color: white; font-family: monospace;}
</style>
<script type="module" src="./main.js"></script>
main.js:
var karMatSelect = document.getElementById( 'kar-mat' );
var proMatSelect = document.getElementById( 'pro-mat' );
var objParts = {
karkass: [],
proff: [],
};
...
function loadModel() {
var LOADER = new GLTFLoader();
LOADER.crossOrigin = true;
LOADER.load('1.glb',
(gltf) => {
console.log('loading complete')
const objbox = gltf.scene;
SCENE.add(objbox);
console.log(objbox);
objParts.karkass.push(objbox.getObjectByName('karkasidver')); //all objects are [Mesh]es
objParts.proff.push(objbox.getObjectByName( 'profl' ),);
...
function initMaterials() {
materialsLib = {
karkaslib: [
new THREE.MeshStandardMaterial( {
color: 0x154889, metalness: 1, roughness: 0.2, name: '5005'
} ),
.....
proflib: [
......
} ),
],
};
}
function initMaterialSelectionMenus() {
function addOption(name, menu) {
var option = document.createElement( 'option' );
option.text = name;
option.value = name;
menu.add(option);
}
materialsLib.karkaslib.forEach( function ( material ) {
addOption(material.name, karMatSelect);
} );
materialsLib.proflib.forEach( function ( material ) {
addOption(material.name, proMatSelect);
} );
karMatSelect.selectedIndex = 2;
proMatSelect.selectedIndex = 5;
karMatSelect.addEventListener( 'change', updateMaterials );
proMatSelect.addEventListener( 'change', updateMaterials );
}
function updateMaterials() {
initMaterials()
var karkasMat = materialsLib.karkaslib[karMatSelect.selectedIndex];
var proflMat = materialsLib.karkaslib[proMatSelect.selectedIndex];
objParts.karkass.forEach(part => part.material = karkasMat);
objParts.proff.forEach(part => part.material = proflMat);
}

When I started the project, I had errors in the console. I made a few changes to fix it:
In loadModel I have add rows with initMaterials(); and initMaterialSelectionMenus();
objParts.karkass.push(objbox.getObjectByName('karkasidver'));
objParts.proff.push(objbox.getObjectByName('profl'));
console.log(dumpObject(objbox).join('\n')); //-список объектов в сцене
/* Add function call for initialization*/
initMaterials();
updateMaterials();
/* Add function call for UI initialization*/
initMaterialSelectionMenus();
I have add checks for undefined for karkasMat and proflMat in the function updateMaterials. Also I have removed call initMaterials().
function updateMaterials() {
/* Remove call for initMaterials() */
var karkasMat = materialsLib.karkaslib[karMatSelect.selectedIndex];
var proflMat = materialsLib.karkaslib[proMatSelect.selectedIndex];
/* added check for empty element */
if (karkasMat) {
objParts.karkass.forEach(part => part.material = karkasMat);
}
/* added check for empty element */
if (proflMat) {
objParts.proff.forEach(part => part.material = proflMat);
}
}
3.
function updateCamera() {
CAMERA.updateProjectionMatrix();
/* Remove next rows, because animation function already started, and will update controls and render scene*/
// CONTROLS.update();
// RENDERER.render(SCENE, CAMERA);
// animate()
}
Result

Alex has an error:
in function updateMaterials()
var proflMat = materialsLib.karkaslib[proMatSelect.selectedIndex];
instead of
var proflMat = materialsLib.proflib[proMatSelect.selectedIndex];

Related

How do I get the code in jsfiddle to work in my Visual Studio Code?

const canvasEle = document.getElementById('drawing-container');
const canvasPad = document.getElementById('pad');
const toolbar = document.getElementById('toolbar');
const context = canvasEle.getContext('2d');
const padContext = canvasPad.getContext('2d');
const canvasOffsetX = canvas.offsetLeft;
const canvasOffsetY = canvas.offsetTop;
canvas.width = window.innerWidth - canvasOffsetX;
canvas.height = window.innerHeight - canvasOffsetY;
let startPosition = {
x: 0,
y: 0
};
let lineCoordinates = {
x: 0,
y: 0
};
let isDrawStart = false;
const getClientOffset = (event) => {
const {
pageX,
pageY
} = event.touches ? event.touches[0] : event;
const x = pageX - canvasPad.offsetLeft;
const y = pageY - canvasPad.offsetTop;
return {
x,
y
}
}
toolbar.addEventListener('click', e => {
if (e.target.id === 'clear') {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
});
toolbar.addEventListener('change', e => {
if(e.target.id === 'stroke') {
ctx.strokeStyle = e.target.value;
}
if(e.target.id === 'lineWidth') {
lineWidth = e.target.value;
}
});
const drawLine = (ctx) => {
if (!isDrawStart) {
return;
}
ctx.beginPath();
ctx.moveTo(startPosition.x, startPosition.y);
ctx.lineTo(lineCoordinates.x, lineCoordinates.y);
ctx.stroke();
}
const mouseDownListener = (event) => {
startPosition = getClientOffset(event);
isDrawStart = true;
}
const mouseMoveListener = (event) => {
if (!isDrawStart) return;
lineCoordinates = getClientOffset(event);
clearCanvas(padContext);
drawLine(padContext);
}
const mouseupListener = (event) => {
clearCanvas(padContext);
drawLine(context);
isDrawStart = false;
}
const clearCanvas = (ctx) => {
ctx.clearRect(0, 0, canvasEle.width, canvasEle.height);
}
canvasPad.addEventListener('mousedown', mouseDownListener);
canvasPad.addEventListener('mousemove', mouseMoveListener);
canvasPad.addEventListener('mouseup', mouseupListener);
body {
margin: 0;
padding: 0;
height: 100%;
overflow: hidden;
color: white;
}
h1 {
background: #7F7FD5;
background: -webkit-linear-gradient(to right, #91EAE4, #86A8E7, #7F7FD5);
background: linear-gradient(to right, #91EAE4, #86A8E7, #7F7FD5);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.cnv-wrapper {
height: 100%;
display: flex;
}
.pad {
height: 100%;
display: flex;
border: 4px solid #333;
}
.container {
height: 100%;
display: flex;
}
#toolbar {
display: flex;
flex-direction: column;
padding: 5px;
width: 70px;
background-color: #202020;
}
#toolbar * {
margin-bottom: 6px;
}
#toolbar label {
font-size: 12px;
}
#toolbar input {
width: 100%;
}
#toolbar button {
background-color: #1565c0;
border: none;
border-radius: 4px;
color:white;
padding: 2px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content = "IE = edge">
<meta name = "viewport" content = "width = device - width, initial - scale = 0.1">
<link rel = "stylesheet" href = "styles.css">
<title> Pipe Illustrator </title>
</head>
<body>
<section class = "container">
<div id = "toolbar">
<h1>Draw.</h1>
<label for="stroke">Stroke</label>
<input id="stroke" name='stroke' type="color">
<label for="lineWidth">Line Width</label>
<input id="lineWidth" name='lineWidth' type="number" value="5">
<button id="clear">Clear</button>
</div>
<div class = "drawing-container">
<canvas id = "drawing-container"></canvas>
</div>
<div class = "cnv-wrapper">
<canvas id = "cnv-wrapper"></canvas>
</div>
</section>
<script src = "./index.js"></script>
</body>
</html>
The project is to make a simple line drawer which makes allows me to draw fixed straight lines without the previous line being removed. The code written below is exactly what I need and was provided by another user from a question I asked previously about making it as my code wouldn't allow for the previous line to remain when drawing a new one.
This is the code below which is in jsfiddle, when I copy and paste it into my Visual studio code, I don't get the same output as I would in jsfiddle, the canvas doesn't appear nor does it allow anything to be drawn. Am I missing something ?
Right so this is the code i have written in VSC. It isn't entirely what was in the jsfiddle, i tried to integrate some other functions from another paint project i did. I was trying to add a toolbar for line colour and width. I think the way i have written it is contradicting it all got quite messy and was quite a fail. These are projects im doing to learn code as i am still a beginner to coding. Thank you for your help and input.
const canvasEle = document.querySelector('.draw-container');
const canvasPad = document.querySelector('.pad');
const context = canvasEle.getContext('2d');
const padContext = canvasPad.getContext('2d');
let startPosition = {
x: 0,
y: 0
};
let lineCoordinates = {
x: 0,
y: 0
};
let isDrawStart = false;
const getClientOffset = (event) => {
const {
pageX,
pageY
} = event.touches ? event.touches[0] : event;
const x = pageX - canvasPad.offsetLeft;
const y = pageY - canvasPad.offsetTop;
return {
x,
y
}
}
const drawLine = (ctx) => {
if (!isDrawStart) {
return;
}
ctx.beginPath();
ctx.moveTo(startPosition.x, startPosition.y);
ctx.lineTo(lineCoordinates.x, lineCoordinates.y);
ctx.stroke();
}
const mouseDownListener = (event) => {
startPosition = getClientOffset(event);
isDrawStart = true;
}
const mouseMoveListener = (event) => {
if (!isDrawStart) return;
lineCoordinates = getClientOffset(event);
clearCanvas(padContext);
drawLine(padContext);
}
const mouseupListener = (event) => {
clearCanvas(padContext);
drawLine(context);
isDrawStart = false;
}
const clearCanvas = (ctx) => {
ctx.clearRect(0, 0, canvasEle.width, canvasEle.height);
}
canvasPad.addEventListener('mousedown', mouseDownListener);
canvasPad.addEventListener('mousemove', mouseMoveListener);
canvasPad.addEventListener('mouseup', mouseupListener);
body {
background-color: #ccc;
}
.cnv-wrapper {
position: relative;
}
.pad {
position: absolute;
top: 0px;
left: 0px;
border: 1px solid #333;
}
.draw-container {
border: 1px solid #333;
}
<div class="cnv-wrapper">
<canvas class="draw-container" width="500" height="500"></canvas>
<canvas class="pad" width="500" height="500"></canvas>
</div>
From comments where I advise:
You can't just copy and paste code [from fiddle] without also using the appropriate html tags. Your CSS needs to go in style tags. Your scripts need to go in script tags. The dom elements, e.g. the "canvas" needs to go in the body tag. Etc. ... You may also need to affix the appropriate "doctype" and you may need to trigger the scripts to run on document load.
As an example, I tried the pasted code using the above advice on my own computer and it worked.
I'll show the complete source and then followup with a runnable version here on SO. Note that the runnable version uses SO's utility for such and as such you won't see all the various tags I mentioned, but the functionality remains the same just as with the "fiddle".
Corrected "pasted" source showing all the relevant tags you need to create:
<!doctype html> <!-- Add appropriate doctype -->
<html>
<head>
<style>
/* Paste the CSS in a style tag */
body {
background-color: #ccc;
}
.cnv-wrapper {
position: relative;
}
.pad {
position: absolute;
top: 0px;
left: 0px;
border: 1px solid #333;
}
.draw-container {
border: 1px solid #333;
}
</style>
</head>
<body>
<div class="cnv-wrapper">
<canvas class="draw-container" width="500" height="500"></canvas>
<canvas class="pad" width="500" height="500"></canvas>
</div>
<script>
// Paste your init scripts into the onload event to ensure they get ran after the canvas is created
window.onload = function() {
const canvasEle = document.querySelector('.draw-container');
const canvasPad = document.querySelector('.pad');
const context = canvasEle.getContext('2d');
const padContext = canvasPad.getContext('2d');
let startPosition = {
x: 0,
y: 0
};
let lineCoordinates = {
x: 0,
y: 0
};
let isDrawStart = false;
const getClientOffset = (event) => {
const {
pageX,
pageY
} = event.touches ? event.touches[0] : event;
const x = pageX - canvasPad.offsetLeft;
const y = pageY - canvasPad.offsetTop;
return {
x,
y
}
}
const drawLine = (ctx) => {
if (!isDrawStart) {
return;
}
ctx.beginPath();
ctx.moveTo(startPosition.x, startPosition.y);
ctx.lineTo(lineCoordinates.x, lineCoordinates.y);
ctx.stroke();
}
const mouseDownListener = (event) => {
startPosition = getClientOffset(event);
isDrawStart = true;
}
const mouseMoveListener = (event) => {
if (!isDrawStart) return;
lineCoordinates = getClientOffset(event);
clearCanvas(padContext);
drawLine(padContext);
}
const mouseupListener = (event) => {
clearCanvas(padContext);
drawLine(context);
isDrawStart = false;
}
const clearCanvas = (ctx) => {
ctx.clearRect(0, 0, canvasEle.width, canvasEle.height);
}
canvasPad.addEventListener('mousedown', mouseDownListener);
canvasPad.addEventListener('mousemove', mouseMoveListener);
canvasPad.addEventListener('mouseup', mouseupListener);
}
</script>
</body>
</html>
Now on to demonstrating this code works now here on SO.
Note that SO's intepreter of code also (like "fiddle") doesn't need the tags mentioned that would be needed when you copy and paste into your own editor. Therefore I re-mention where the pasted code goes in code comments.
// Your scripts will go in a <script> tag
// Use an onload event handler to ensure they get ran after the canvas is created
window.onload = function() {
const canvasEle = document.querySelector('.draw-container');
const canvasPad = document.querySelector('.pad');
const context = canvasEle.getContext('2d');
const padContext = canvasPad.getContext('2d');
let startPosition = {
x: 0,
y: 0
};
let lineCoordinates = {
x: 0,
y: 0
};
let isDrawStart = false;
const getClientOffset = (event) => {
const {
pageX,
pageY
} = event.touches ? event.touches[0] : event;
const x = pageX - canvasPad.offsetLeft;
const y = pageY - canvasPad.offsetTop;
return {
x,
y
}
}
const drawLine = (ctx) => {
if (!isDrawStart) {
return;
}
ctx.beginPath();
ctx.moveTo(startPosition.x, startPosition.y);
ctx.lineTo(lineCoordinates.x, lineCoordinates.y);
ctx.stroke();
}
const mouseDownListener = (event) => {
startPosition = getClientOffset(event);
isDrawStart = true;
}
const mouseMoveListener = (event) => {
if (!isDrawStart) return;
lineCoordinates = getClientOffset(event);
clearCanvas(padContext);
drawLine(padContext);
}
const mouseupListener = (event) => {
clearCanvas(padContext);
drawLine(context);
isDrawStart = false;
}
const clearCanvas = (ctx) => {
ctx.clearRect(0, 0, canvasEle.width, canvasEle.height);
}
canvasPad.addEventListener('mousedown', mouseDownListener);
canvasPad.addEventListener('mousemove', mouseMoveListener);
canvasPad.addEventListener('mouseup', mouseupListener);
}
/* Your CSS would go in a <style> tag */
body {
background-color: #ccc;
}
.cnv-wrapper {
position: relative;
}
.pad {
position: absolute;
top: 0px;
left: 0px;
border: 1px solid #333;
}
.draw-container {
border: 1px solid #333;
}
<!-- Your HTML would go in the <body> tag -->
<div class="cnv-wrapper">
<canvas class="draw-container" width="500" height="500"></canvas>
<canvas class="pad" width="500" height="500"></canvas>
</div>

Adding Text on the selected canvas in Fabric js

I have fabric js multiple canvases and I would like to add Text on the selected canvas, instead of the last item of the array.
If a user creates multiple canvases then I need an option to add the text on the selected canvas.
Please run the code snippet or see the codepen demo of the current approach...
Thank you!
//================== Create Canvas start =================
var createCanvas = document.getElementById("createCanvas");
var canvasInstances = [];
createCanvas.addEventListener('click',function(){
var canvasContainer = document.getElementById("canvasContainer");
var newcanvas = document.createElement("canvas");
//newcanvas.classList.add("active");
canvasContainer.append(newcanvas);
var fabricCanvasObj = new fabric.Canvas(newcanvas, {
height: 400,
width: 400,
backgroundColor: '#ffffff',
});
canvasInstances.push(fabricCanvasObj);
console.log(canvasInstances);
})
//================== Create Canvas End =================
//================== Add Text ================
var addText = document.getElementById("addText");
addText.addEventListener('click',function(){
canvasInstances.forEach(function(current,id,array){
if(id === array.length - 1){
const converText = new fabric.IText(`Type Text`,{
type: 'text',
width: 200,
fontSize: 20,
left: 20,
top: 20,
fill: '#444'
});
current.add(converText);
current.renderAll();
return false;
}
})
})
//================== Add End =================
*{
box-sizing: border-box;
}
body{
background:#ccc;
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 200px;
}
.canvas-container{
margin-bottom:10px;
}
.add-text{
margin: 20px;
width: 400px;
text-align: center;
border:1px dashed red;
padding: 15px;
cursor:pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.5.0/fabric.min.js"></script>
<div class="add-text" id="addText">Add Text</div>
<div id="canvasContainer">
</div>
<button id="createCanvas">Create Canvas</button>
Declare canvasobject globally, you can try below code
<script type="text/javascript">
var canvasobject;
window.onload = function () {
canvasobject = new fabric.Canvas('myCanvas');
canvasobject.backgroundColor = '#0056d6';
canvasobject.renderAll();
//
function addtext() {
var textvalue = "Type here";
var fontcolor = "#333";
var fontFamily = "Baloo 2";
var myfont = new FontFaceObserver(fontFamily);
myfont.load()
.then(function () {
// when font is loaded, use it.
var text = new fabric.Text(textvalue, {
left: 100,
top: 100,
fontFamily: fontFamily,
fill: fontcolor,
});
canvasobject.add(text);
canvasobject.renderAll();
}).catch(function (e) {
//console.log(e);
console.log('font loading failed ' + fontFamily);
});
}
}

What may be the cause of the error "ReferenceError: Velocity is not defined"?

help please help, I do not understand the reason. Throws an error ReferenceError: Velocity is not defined. If I use $ (function () {}; then the error disappears, but then simply do not work. Use hammer 2.0.4 and velocity 1.2.3
// Constants
const THRESH = 0.75;
const TIMING = 250;
// When the dom is loaded, set up hammer events.
document.addEventListener('DOMContentLoaded', f => {
var lis = document.querySelectorAll('.swipe');
for (let i = 0; i < lis.length; i++) {
let hammertime = new Hammer(lis[i]);
hammertime.on('panright', e => handlePan(e));
hammertime.on('panend', e => reset(e));
}
});
// pane{right} handler
function handlePan(e, model) {
var {target: el, deltaX: dx} = e;
if (doAction(dx, el)) {
el.classList.add('action');
} else {
el.classList.remove('action');
}
Velocity(el, {
translateX: dx
}, 0);
}
// panend handler
function reset(e) {
var {target: el, deltaX: dx} = e;
// Should we remove the element?
if (doAction(dx, el)) {
Velocity(el, {
translateX: dx * 2
}, TIMING).then(() => {
return Velocity(el, {
height: 0
}, TIMING);
}).then(() => {
el.parentNode.removeChild(el);
});
} else {
Velocity(el, {
translateX: 0
}, TIMING);
}
}
// Determines if an element will be dismissed
function doAction(dx, el) {
return Math.abs(dx) >= THRESH * el.clientWidth;
}
.swipe {
position: relative;
list-style: none;
text-align: center;
background: #9e9e9e;
height: 150px;
line-height: 150px;
width: 40vw;
}
<div class="swipe">Swipe me!</div>
<!--Scripts-->
<script src="http://code.jquery.com/jquery-2.2.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.4/hammer.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
The velocity library reference should have been BEFORE the
jQuery reference. The way you know this is that when you run the code, with the developers tools open (F12) and you get the error, the error comes up from within the jQuery code - - so that means that jQuery can't find velocity. Then looking at the script references, you can see why...the jQuery library is running before the velocity library has been loaded.
This works:
// Constants
const THRESH = 0.75;
const TIMING = 250;
// When the dom is loaded, set up hammer events.
document.addEventListener('DOMContentLoaded', f => {
var lis = document.querySelectorAll('.swipe');
for (let i = 0; i < lis.length; i++) {
let hammertime = new Hammer(lis[i]);
hammertime.on('panright', e => handlePan(e));
hammertime.on('panend', e => reset(e));
}
});
// pane{right} handler
function handlePan(e, model) {
var {target: el, deltaX: dx} = e;
if (doAction(dx, el)) {
el.classList.add('action');
} else {
el.classList.remove('action');
}
Velocity(el, {
translateX: dx
}, 0);
}
// panend handler
function reset(e) {
var {target: el, deltaX: dx} = e;
// Should we remove the element?
if (doAction(dx, el)) {
Velocity(el, {
translateX: dx * 2
}, TIMING).then(() => {
return Velocity(el, {
height: 0
}, TIMING);
}).then(() => {
el.parentNode.removeChild(el);
});
} else {
Velocity(el, {
translateX: 0
}, TIMING);
}
}
// Determines if an element will be dismissed
function doAction(dx, el) {
return Math.abs(dx) >= THRESH * el.clientWidth;
}
.swipe {
position: relative;
list-style: none;
text-align: center;
background: #9e9e9e;
height: 150px;
line-height: 150px;
width: 40vw;
}
<!--Scripts-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<script src="http://code.jquery.com/jquery-2.2.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.4/hammer.min.js"></script>
<div class="swipe">Swipe me!</div>

Check if my server is responding [Javascript]

I want to check if server at URL is responding, then set the text of my < p > tag to 'server is online' or 'server is offline'.
I can make a page on my server that returns for ex. 'success' as a plain text. And if my javascript can catch this message it should write 'server is online', else it should try to connect for maximum 5 or more seconds, then write a message 'server is offline'.
I tried the code from this answer, but it turns offline after 1500 ms.
<body onload="Pinger_ping('google.com')">
...
<p id = "status">Checking server status...</p>
...
<script type="text/javascript">
function Pinger_ping(ip, callback) {
if(!this.inUse) {
this.inUse = true;
this.callback = callback
this.ip = ip;
var _that = this;
this.img = new Image();
var status=document.getElementById('status');
this.img.onload = function() {status.innerHTML="online";};
this.img.onerror = function() {status.innerHTML="online";};
this.start = new Date().getTime();
this.img.src = "http://" + ip;
this.timer = setTimeout(function() {status.innerHTML="offline";}, 1500);
}
}
</script>
You may try this solution, here I am using image load event to track the connection status.
(function(win) {
var _ = {};
_.win = win;
_.doc = _.win.document;
_.status = _.doc.createElement('div');
_.status.className = "hide";
_.status.innerHTML = "You are now offline !";
_.doc.getElementsByTagName('body')[0].appendChild(_.status);
_.img = new Image();
_.loop = function() {
_.win.setTimeout(_.nextSrc, 5000);
};
_.onLine = function() {
_.status.className = "hide"; // hide
_.loop();
};
_.offLine = function() {
_.status.className = "net-err"; // show
_.loop();
};
_.img.onload = _.onLine;
_.img.onerror = _.offLine;
_.nextSrc = function() {
_.img.src = "https://raw.githubusercontent.com/arvind-web-corner/offline-status/gh-pages/blank.png?" + _.win.Math.random();
};
_.loop();
})(window);
* {
font-family: Calibri, Arial !important;
}
.net-err {
width: 100%;
display: block;
z-index: 999;
padding: 15px 10px;
background: rgb(255, 9, 9);
color: #fff;
font-weight: bold !important;
text-align: center;
position: fixed;
top: -1px;
left: -1px;
border: 1px solid #ddd;
font-size: 30px;
opacity: 0.9;
filter: alpha(opacity=90);
/* IE */
}
.hide {
display: none;
}
<!DOCTYPE html>
<html>
<head>
<title>Status</title>
</head>
<body>
<h1>This page will be tracking your internet connection</h1>
<h2>You will be notified when you loose connection</h2>
<h3>e.g. Go to File > Work Offline</h3>
</body>
</html>
script, demo

Raphael path.animate recursive function syntax

Does anyone know the syntax to call a function recursively to chain path.animate events using the Raphael library?
I have posted a JS Fiddle for reference at http://jsfiddle.net/Quarkist/c4TzV/
The function animString() (result on left) chains events properly and is animated.
The recursive function animRecursion() (result on right) does not animate.
Any insight is appreciated. Thank you!
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Recursive animatePath w/Raphael</title>
<style type="text/css">
<!--
#displayA { position: absolute; top: 0px; left: 0px; }
#displayB { position: absolute; top: 0px; left: 112px; }
// -->
</style>
<script type="text/javascript" src="raphael-min.js"></script>
<script type="text/javascript">
// Paths to animate
var path1 = "M200,50c-27.5,0,50,78,50,50 c0-27.5-77.5,50-50,50c28,0-50-77.5-50-50C150,127.5,228,50,200,50z";
var path2 = "M200,150c-27.5,0-50-22.5-50-50 s22.5-50,50-50s50,22.5,50,50S227.5,150,200,150z";
var path3 = "M200,171 130,100 200,30 271,100 200,171z";
var path4 = "M250,150 150,150 150,50 250,50 250,150z";
var path5 = "M200,50 200,83.5 200,116.5 200,150";
// animString works by stringing code along
function animString()
{ var tempCanvas = Raphael(document.getElementById('displayA'), 0, 0, 320, 240);
var path = tempCanvas.path( path1 );
var speed = 1000;
path.animate(
{ path: path1 }, 1000, // twist
function(){ path.animate( { path: path1 }, speed, 2000,
function(){ path.animate( { path: path2 }, speed, 2000,
function(){ path.animate( { path: path3}, speed, 2000,
function(){ path.animate( { path: path4}, speed, 2000,
function(){ path.animate( { path: path5}, speed, 2000
) } ) } ) } ) } ) } );
}
// animRecursion fails
function animRecursion(pathArray, speedArray, initialization)
{ var newPath=pathArray.shift(pathArray);
var newSpeed=speedArray.shift(speedArray);
if ( !initialization )
{ initialization=1;
var tempCanvas = Raphael(document.getElementById('displayB'), 0, 0, 320, 240);
var path = tempCanvas.path( newPath );
path.animate({path:newPath},newSpeed,animRecursion(pathArray, speedArray, initialization));
} else
{ if ( pathArray.length !=1 )
{ path.animate({path:newPath},newSpeed,animRecursion(pathArray, speedArray, initialization));
} else
{ if ( pathArray.length ==1 )
{ path.animate({path:newPath},newSpeed);
}
}
}
}
var sendArray = new Array();
var sendSpeed = new Array();
sendArray = [path1, path2, path3, path4, path5];
sendSpeed= [100,200,300,400,500];
</script>
</head>
<body onLoad="animString(); animRecursion(sendArray,sendSpeed);">
<div id="displayA"></div>
<div id="displayB"></div>
</body>
</html>
Notice that the working code does this:
path.animate(x,y,z,function(){path.animate()});
instead of this:
path.animate(x,y,z,path.animate());
But the failing code does this:
path.animate(x,y,z,animRecursion());
What you should have done is to do it the way the working code does it:
path.animate(x,y,z,function(){animRecursion()});
That is, pass a function to be called, not call a function.

Categories