i am trying out raphael with javascript and trying to get the hang of it. At the moment i am trying to get it so that when the user hovers over a circle in raphael which i have drawn it will create a simmple hover messge like hi. However i am stuck to an end on this part, i cant seem to do anything about, any help on this would be great.
Javascript:
window.onload= function (){
var paper = new Raphael( 0, 0, 400, 400);
var backGround = paper.rect(0, 0, 400, 400);
backGround.attr({ fill: "orange"});
var face = paper.circle(200,200,100);
face.attr({ fill: "Red"});
};
HTML
<div class= "bot">
<p>Hi there</p>
</div>
Just use the Element.hover() function, as documented on the Raphael website.
Update: The code snippet posted below works if you copy it onto your own computer and run it locally. However, to actually run this snippet on Stack Overflow, it only works on some browsers (e.g. it works on Firefox, but not on Chrome), probably due to the different browsers allowing or not allowing the code snippets to load external libraries, like Raphael.js, as required in this code snippet.
window.onload = function() {
var paper = new Raphael(0, 0, 400, 400);
var backGround = paper.rect(0, 0, 400, 400);
backGround.attr({
fill: "orange"
});
var face = paper.circle(200, 200, 100);
face.attr({
fill: "Red"
});
face.hover(hoverHandler);
};
function hoverHandler() {
alert("hi");
}
<script src="http://github.com/DmitryBaranovskiy/raphael/raw/master/raphael-min.js"></script>
<div class="bot">
<p>Hi there</p>
</div>
Related
I am building an app in Rails, and I am using a gem called easy_as_pie which enables me to use this Jquery plugin called 'Easy Pie Chart' (http://rendro.github.io/easy-pie-chart/)
I have the pie chart working no problem, using the following code:
$(document).ready(function() {
$('.chart').easyPieChart({
size: 300,
animate: 1400,
lineWidth: 150,
lineCap: "butt",
scaleColor: false,
trackColor: "black",
barColor: "white"
});
});
The question I have, is whether not it would be possible to have the chart load a background image instead of a solid colour. In the documentation it allows you to use a gradient with a function, using the following code:
new EasyPieChart(element, {
barColor: function(percent) {
var ctx = this.renderer.ctx();
var canvas = this.renderer.canvas();
var gradient = ctx.createLinearGradient(0,0,canvas.width,0);
gradient.addColorStop(0, "#ffe57e");
gradient.addColorStop(1, "#de5900");
return gradient;
}
});
I was hoping to get the gradient working, then work on trying to manipulate the function to load in an image. But I have been unsuccessful in even getting the gradient to work.
Provided your gradient example works like it looks, you should be able to draw just about anything you want into the canvas object they've provided. With that in mind, you might be able to draw images like so:
new EasyPieChart(element, {
barColor: function(percent) {
var ctx = this.renderer.ctx();
var canvas = this.renderer.canvas();
var yourImage = new Image();
yourImage.src = "path-to-your-img.jpg";
return ctx.drawImage(yourImage);
}
});
However, Image objects, like <img> tags, require a further GET request to the server to actually load them, so the above probably won't actually work (sorry for the tease). Instead, you'll have to wait for that image to load before calling it, for example:
// Instantiate the image, it's blank here.
var yourImage = new Image();
// Add a callback that uses the fully-loaded img
yourImage.onload = function() {
new EasyPieChart(element, {
barColor: function(percent) {
var ctx = this.renderer.ctx();
var canvas = this.renderer.canvas();
return ctx.drawImage(yourImage);
}
});
};
// Set the src, that queues it for the actual GET request.
yourImage.src = "path-to-your-img.jpg";
It seems to happen only when I try to animate an image on Chrome. All I want to do is make an image to move back an forth in Raphaƫl.js. I created a jsfiddle that illustrates the problem. I'm very sure that it used to work in Chrome since I use it to develop and it seems to be broken in later versions of Chrome. When I change the image to a rect for example it seems to render fine. When you resize the screen that contains the animation it repaints.
http://jsfiddle.net/k69yzz0o/1/
var moveForth = function () {
useControl.animate({x : 38, y: 0}, 900, moveBack);
};
var moveBack = function () {
useControl.animate({x : 0, y: 0}, 600, moveForth);
};
var R = Raphael("holder", 500, 500);
useControl = R.image("http://i.imgur.com/ta8zlD2.png", 0, 0, 189, 18);
moveForth();
It only happens in Chrome and I use latest Raphael.js 2.1.2.
How can I resolve this issue?
Yes, there appears to be an issue with Chrome recognizing the rect as dirty, and refusing to repaint it. You can see that it's working by mousing over the area.
I tried the same animation using a Transform rather than using the actual position. Transforming an object evidently correctly tells modern Chrome to redraw that area.
Here it is working:
var moveForth = function () {
useControl.animate({"transform":"T38,0"}, 900, ">", moveBack);
};
var moveBack = function () {
useControl.animate({"transform":""}, 600, "<", moveForth);
};
var R = Raphael("holder", 500, 500);
useControl = R.image("http://i.imgur.com/ta8zlD2.png", 0, 0, 189, 18);
moveForth();
I also added some easing (">") to give it a more natural bounce.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I have tried searching similar problems but have not been able to find the reason why my code works in jfiddle but not in a browser. I have also tried making a copy of my code from jfiddle to another fiddle project and the code doesn't work in the new project. You can find my project here. I am making a interactive food game where someone picks a food item, example acorn squash and then the user can drag that image around.
My first attempt was pasting the code within the head.
<script language="JavaScript">
code
</script>
Do I need an onpage load event? Does the javascript need to be put in a function? Am I using something from the jfiddle framework thats not being used on my local host that I need to call?
Below is the code I am using without the extra food options
var stage, layer;
var sources = {
plate: 'http://www.healncure.com/wp-content/uploads/2014/03/plate1.jpg',
acornsquash: 'http://www.healncure.com/wp-content/uploads/2014/03/acorn-squash.png',
};
loadImages(sources, initStage);
function loadImages(sources, callback) {
var images = {};
var loadedImages = 0;
var numImages = 0;
// get num of sources
for (var src in sources) {
numImages++;
}
for (var src in sources) {
images[src] = new Image();
images[src].onload = function () {
if (++loadedImages >= numImages) {
callback(images);
}
};
images[src].src = sources[src];
}
}
function initStage(images) {
stage = new Kinetic.Stage({
container: 'container',
width: 936,
height: 550
});
layer = new Kinetic.Layer();
stage.add(layer);
// plate
var plateImg = new Kinetic.Image({
image: images.plate,
x: 218,
y: 20,
width: 503,
hei4ht: 502,
draggable: false,
visible: true
});
layer.add(plateImg);
// acornsquash
var acornsquashImg = new Kinetic.Image({
id: "acornsquash",
image: images.acornsquash,
x: 50,
y: 20,
width: 134,
height: 114,
draggable: true,
stroke: 'orange',
strokeWidth: 5,
strokeEnabled: false,
visible: false
});
layer.add(acornsquashImg);
layer.draw();
$(".food").click(function () {
var node = stage.find("#" + $(this).attr("id"));
node.show();
layer.draw();
console.log($(this).attr("id"));
});
document.getElementById('hide').addEventListener('click', function () {
acornsquashImg.hide();
layer.draw();
}, false);
}
The usual reason for this is that you're putting your code above the elements that it operates on, and not delaying the code using onload or "ready" events. jsFiddle's default is to put your JavaScript in an onload handler, which delays it until very late in the page load process.
Fundamentally, before your code can do something with an element on the page, the element has to exist. For it to exist, the browser must have processed the HTML for it. So this fails:
<html>
<head>
<script>
// FAILS
document.getElementById("foo").style.color = "green";
</script>
</head>
<body>
<div id="foo">This is foo</div>
</body>
</html>
but this works:
<html>
<head>
</head>
<body>
<div id="foo">This is foo</div>
<script>
// Works
document.getElementById("foo").style.color = "green";
</script>
</body>
</html>
Do I need an onpage load event?
Almost certainly not.
Does the javascript need to be put in a function?
Not necessarily. What you do is put the script tag at the very end of the HTML, just before the closing </body> tag.
Include jQuery library in the head section of your document
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
</head>
then wrap your custom scripts between script tags and document ready function
<script>
$(function() {
...your custom scripts...
});
</script>
just before the </body> tag.
My problem started with the version 5 of KineticJS, before that it was not a problem. Native KineticJS shapes such as squares and circles can be saved to an image file using the stage.toDataURL function. But it doesn't work for non-Kinetic shapes drawn with normal canvas methods such as beginPath(); and canvas.fill(); (version 4 did this fine). The following code draws two rectangles, one red and one blue. The red is custom, the blue is a native kinetic rectangle.
<body>
<div id="container"></div>
<button id="save">
Save as image
</button>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.0.2.min.js"> </script>
<script>
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var box = new Kinetic.Rect({
x: 400,
y: 80,
width: 100,
height: 50,
fill: '#00D2FF',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
layer.add(box);
stage.add(layer);
var canvas = layer.getCanvas().getContext('2d');
canvas.beginPath();
canvas.setAttr('strokeStyle', 'black');
canvas.setAttr('fillStyle', '#FF2222');
canvas.setAttr('lineWidth', 8);
canvas.rect(50,80,100,50);
canvas.stroke();
canvas.fill();
document.getElementById('save').addEventListener('click', function() {
stage.toDataURL({
callback: function(dataUrl) {
window.location.href = dataUrl;
}
});
}, false);
</script>
</body>
Both shapes appear, but only the blue rectangle appears in the image generated by the toDataURL function. The way they are drawn has changed in KineticJS 5, where you set attributes for fillStyle etc. so I'm thinking that may have something to do with it, or maybe the fact that the custom shape is added after the layer is added to the stage...
You are correct, between recent versions much has changed, and this has probably broken something in your drawing function.
You should consult the official docs on each item, but basically a custom shape has slightly updated properties... first of all "StrokeStyle" is no longer a valid property. Just use 'stroke'. Same thing with FillStyle.
Also -- 'dashArray' is no longer valid, now it's just 'dash' -- so I'm sure there are more things that changed that I'm not recalling... right, such as 'lineWidth' is now 'strokeWidth'...
Also -- the way you show or don't show strokes and fills has changed... yep, pretty much most of the way you used to do it has been changed slightly. 'drawFunc' is now 'sceneFunc' also...
var ctx = layer.getContext();
var customShape01 = new Kinetic.Shape({
sceneFunc: function(ctx) {
ctx.beginPath();
ctx.moveTo(162.1, 213.8);
ctx.bezierCurveTo(162.1, 213.8, 180.7, 215.3, 193.5, 214.5);
ctx.bezierCurveTo(205.8, 213.7, 221.8, 212.3, 222.8, 221.4);
ctx.bezierCurveTo(222.9, 221.7, 222.9, 222.0, 222.9, 222.3);
ctx.bezierCurveTo(222.9, 232.4, 204.6, 232.7, 192.0, 227.1);
ctx.bezierCurveTo(179.4, 221.5, 163.1, 213.8, 162.1, 213.8);
ctx.closePath();
ctx.fillStrokeShape(this);
},
id: 'customShape01',
fill: 'rgb(255, 0, 255)',
stroke: 'black',
strokeWidth: 2,
lineJoin: 'round',
dash: [5,5],
dashEnabled: 'true',
strokeEnabled: 'true'
});
check out a full working sample (you'll have to allow popups).
http://jsfiddle.net/axVXN/1/
I'm trying to put an image inside a circle but no success. This is my code:
//Elms.raphael() is my stage.
var circle = Elms.raphael().circle( 730, 200, 0 );
circle.attr( { fill : 'url(myImg.jpg)' } );
setTimeout( function()
{
circle.animate( { 'stroke' : '#000', r : 90, 'stroke-width' : '5' }, 300 );
}, 250 );
Instead of put the image in the circle It get colored with black ("#333"). I also tried to make an image-object but still doesn't work.
A little help please?
Another way to do, if you have separate image and want to bring it over you circle object.
This makes the whole image appear with smaller size that fits you circle. DEMO
var r = new Raphael(10,10, 500, 500);
var c = r.circle(200, 200, 80).attr({stroke: 'red', "stroke-width" : 3});
var img = r.image("http://www.eatyourcareer.com/wp-content/uploads/2012/06/ok-256x2561.png", 100, 105, 200, 200);
Here's a link to how I created a circle with an image in it:
jsfiddle
var paper = Raphael(document.getElementById("test"), 320, 200);
var circle = paper.circle(100, 100, 50);
circle.attr({
fill: 'url(http://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/SIPI_Jelly_Beans_4.1.07.tiff/lossy-page1-220px-SIPI_Jelly_Beans_4.1.07.tiff.jpg)'
});
I left the animate out entirely to keep it as basic as I could. It seems to work fine and is very similar to your code. If you cannot see it in the example it may be a browser issue.