Can I change javascript draw function to an image? - javascript

I found a gamecode on github [https://github.com/maryrosecook/retro-games] today. I want to edit it and use png images instead of the draw function, is there anyway I can do it?
Thank you.
BodyBlock.prototype = {
draw: function(screen) {
drawRect(screen, this, "black");
}

drawRect() was custom, from scratch function.
var drawRect = function(screen, body, color) {
screen.fillStyle = color;
screen.fillRect();
};
What you are looking for is standard javascript canvas Method.
http://www.w3schools.com/tags/canvas_fillrect.asp
Tutorial : http://www.html5canvastutorials.com/tutorials/html5-canvas-lines/

Related

svg color inside fabricjs canvas not changing

i'm trying to change svg path's fill which is inside fabricjs canvas.
using this function
function changeColor(material) {
console.log(svgGroup[0].fill)
console.log(material);
if (material == 'base') {
svgGroup[0].fill = '#000000';
console.log(svgGroup[0].fill)
}
texture.needsUpdate = true;
object.children[0].material = textureMaterial;
canvas.renderAll();
}
but it doesn't updated automatically
anyone have any idea why? any thought would be helpful
i found the solution, the problem iwas i didn't set the color correctly. instead of doing this
svgGroup[0].fill = '#000000';
it should've use this
svgGroup._objects.forEach(obj => {
if (obj.id == material) {
obj.set('fill', color);
}
});
that way it is rendered when renderAll() is called

How to change raphael element picture

I have an element with a picture.
el = r.image("images/pic1.png", x, y, w, h);
How to change it's picture later when I need it?
Updating src like that wont't help:
el.attr({src: "images/pic2.png"})
I found an answer in this thread: How to update the source of an Image
Answer by sosuke worked best for me:
function setImgSrc(targetImg, newSrc) {
if (targetImg.node.src) {
targetImg.node.src = newSrc;
} else {
targetImg.node.href.baseVal = newSrc;
}
}

how to build a 3d donut chart

I wonder if it's possible to build a 3d donut chart in html.
I have found a interesting link here but infortunatly i need to add links (or javascript event) when clicking to launch a ajax request.
Have you ever done such a thing ?
Thanks for your answers
See the following example I've just made:
http://jsfiddle.net/baQCD/3/embedded/result/
The key point (pun intended) is to add a url key for each row (object) in the data array, and use it in the 'click' event handler:
point: {
events: {
click: function(e) {
location.href = e.point.url;
e.preventDefault();
}
}
},
In your case instead of opening a new url, you could do your ajax request or do anything else. In my example I've shown how to manipulate the data and title.
click: function(e) {
if (this.name == "Randomize!") {
sliceK = getRandomInt(0,chart.series[0].data.length-1);
chart.options.series[0].data[sliceK].y = getRandomInt(1,30);
chart = new Highcharts.Chart(chart.options);
} else if (this.name == "Link") {
location.href = this.url;
e.preventDefault();
} else {
chart.setTitle(null,{text:this.name + " clicked"});
}
}
You can immediately see, 2 features I very like in Highcharts, the ability to print or download the chart, and the ability to disable part of the data (removing it from the chart) by clicking on the legend.
This is based on the code shown in:
http://birdchan.com/home/2012/09/07/highcharts-pie-charts-can-have-url-links/
http://www.highcharts.com/demo/3d-pie-donut/
this is a simple 3d Axonometric class i wrote for testing, its very simple it puts the canvas transformation into a plane of zy or zx or yx... it uses canvas setTransform
you first have to call the axionometric class with phi and theta the angles of view
get_bd is a function where you can enter x,y,z coordinates and the method returns an object with b and d value... b is the x of the screen and d is the y of the screen.
i have appended and example, you just have to put a canvas tag in the html with id canvasView
//3d Maths - Axonometric -- Artner Thorsten -- Austria -- Wiener Neustadt
var context=document.getElementById("canvasView").getContext("2d");
function Axonometric (phi,theta)
{
var cosPHI=Math.cos(phi);
var sinPHI=Math.sin(phi);
var cosTHETA=Math.cos(theta);
var sinTHETA=Math.sin(theta);
this.cosPHI=cosPHI;
this.sinPHI=sinPHI;
this.cosTHETA=cosTHETA;
this.sinTHETA=sinTHETA;
this.phi=phi;
this.theta=theta;
}
Axonometric.prototype.get_bd=function (x,y,z)
{
var b=y*this.cosPHI-x*this.sinPHI-500;
var d=x*this.cosPHI*this.cosTHETA+y*this.sinPHI*this.cosTHETA-z*this.sinTHETA+500;
return {b:b,d:d};
}
Axonometric.prototype.plane_zy=function (x)
{
context.setTransform (0,this.sinTHETA,-this.cosPHI,this.sinPHI*this.cosTHETA,500+x*this.sinPHI,500+x*this.cosPHI*this.cosTHETA);
}
Axonometric.prototype.plane_zx=function (y)
{
context.setTransform (this.sinPHI,this.cosPHI*this.cosTHETA,0,this.sinTHETA,500+y*-this.cosPHI,500+y*this.sinPHI*this.cosTHETA);
}
Axonometric.prototype.plane_yx=function (z)
{
context.setTransform (this.sinPHI,this.cosPHI*this.cosTHETA,-this.cosPHI,this.sinPHI*this.cosTHETA,500,500-z*this.sinTHETA);
}
Axonometric.prototype.draw_axis=function (length)
{
var O=this.get_bd (0,0,0);
var X=this.get_bd (length,0,0);
var Y=this.get_bd (0,length,0);
var Z=this.get_bd (0,0,length);
context.save;
context.beginPath ();
context.textAlign="top";
context.fillText ("X",-X.b,X.d);
context.moveTo (-O.b,O.d);
context.lineTo (-X.b,X.d);
context.strokeStyle="red";
context.stroke ();
context.beginPath ();
context.fillText ("Y",-Y.b,Y.d);
context.moveTo (-O.b,O.d);
context.lineTo (-Y.b,Y.d);
context.strokeStyle="green";
context.stroke ();
context.beginPath ();
context.fillText ("Z",-Z.b,Z.d);
context.moveTo (-O.b,O.d);
context.lineTo (-Z.b,Z.d);
context.strokeStyle="blue";
context.stroke ();
context.restore ();
}
// example
var Viewer=new Axonometric (Math.PI/4, Math.PI/8);
Viewer.draw_axis (400);
Viewer.plane_yx (0);
context.beginPath ();
context.fillStyle="red";
context.fillRect (0,0,200,200);
Viewer.plane_zx (0);
context.beginPath ();
context.fillStyle="lightgrey";
context.fillRect (0,0,200,-200);
Viewer.plane_zy (0);
context.beginPath ();
context.arc (-100,100,100,0,2*Math.PI);
context.fillStyle="black";
context.fill();
Using an existing library is an easy solution. If I'm understanding your question properly, you would like users to be able to click on a slice to open a new URL.
This can be achieved in ZingChart by setting up a "pie3d" type, and then including "url" and "target" in the series.
Here's how I did it:
{
"graphset":[
{
"type":"pie3d",
"plot":{
"slice":45
},
"plotarea":{
"margin-top":"35px"
},
"series":[
{
"text":"Apples",
"values":[5],
"url":"http://www.google.com",
"target":"_blank"
},
{
"text":"Oranges",
"values":[8]
},
{
"text":"Bananas",
"values":[22]
},
{
"text":"Grapes",
"values":[16]
},
{
"text":"Cherries",
"values":[12]
}
]
}
]
}
Expanding on Merrily's answer, you can also use ZingChart's API to track chart interaction and call any functions you like.
var ZCwindow;
function openWindow() {
ZCwindow = window.open("http://zingchart.com/docs/chart-types/pie/", "ZingChart Pie Charts");
}
zingchart.node_click = function(e){
if(e.value == 5) openWindow();
};
You can view a live demo here.
I am part of the ZingChart team. You can reach out to us for assistance via support#zingchart.com
For the past few months I have been working with Google Visualization charts, and I think it may be exactly what you're looking for. Here is the link to the documentation.
This will give you a donut chart (though I am not sure if you can make it 3-D or not, I believe you can) and you can add event handlers for when the user clicks on a slice. Here's what it looks like:
I highly recommend trying the charts, I have found them to be extraordinarily useful. Good luck!
EDIT: My apologies, after re-reading the section on donut charts it appears the new API does not yet support 3-D donut charts. Does it absolutely have to be three-dimensional? If not this is still an excellent choice.
It's not 3D, but you should have a look at chart.js

Drag and drop SVGs with Raphael JS

Looking for some advice (example would be great) on dragging and dropping SVGs using RaphaelJS.
I have found how to drag an object created withint Raphael
window.onload = function() {
var R = Raphael("canvas", 500, 500);
var c = R.circle(100, 100, 50).attr({
fill: "hsb(.8, 1, 1)",
stroke: "none",
opacity: .5
});
var start = function () {
...
},
move = function (dx, dy) {
...
},
up = function () {
...
};
c.drag(move, start, up);
};​
But I need to be able to adapt this to work with a seperate SVG file(s) so for example
myPage.html has myImage.svg, I need to be able to drag myImage.svg around the 'canvas'.
I'm thinking something like
var c = R.SOMEMETHOD('myImage.svg');
...
c.drag(move, start, up);
For example.
Is there a way to do this and if so, an example would be brilliant!
This magic method doesn't exist in RaphaelJS. But there is a way to accomplish this. You can have a look at the raphael-svg-import project on GitHub which works well for basic svgs
Then, you'll want to use a grouping facility as you cannot use the Set functionnality of RaphaelJS
1 - import your SVG
2 - As you import, mark the elements so they belong to the same group
Enjoy !!

How to implement drag and drop for HTML5 Canvas painting application?

Based on Creating an HTML 5 canvas painting application I created a HTML5 canvas painting application. It works fine, but after creating each object I just need to drag the objects.
Working demo
How to implement drag and drop of the figures?
When the user clicks on the canvas, you have to check the coordinates (compare it to the coordinates for the objects), and see if it's on an object. E.g. You can test if a point (e.g. the coordinates for the mousedown even) is within a circle with this method:
function (pt) {
return Math.pow(pt.x - point.x,2) + Math.pow(pt.y - point.y,2) <
Math.pow(radius,2);
};
If the mousedown is on the object, you have to change the objects coordinates according to how the mouse is moved.
Here is an example, where you can drag a circle:
<!DOCTYPE html>
<html>
<head>
<script>
window.onload = function() {
drawCircle(circle);
element = document.getElementById('canvas');
element.addEventListener('mousedown', startDragging, false);
element.addEventListener('mousemove', drag, false);
element.addEventListener('mouseup', stopDragging, false);
element.addEventListener('mouseout', stopDragging, false);
}
function mouseX(e) {
return e.clientX - element.offsetLeft;
}
function mouseY(e) {
return e.clientY - element.offsetTop;
}
var Point = function (x, y) {
this.x = x;
this.y = y;
return this;
}
var Circle = function (point, radius) {
this.point = point;
this.radius = radius;
this.isInside = function (pt) {
return Math.pow(pt.x - point.x, 2) + Math.pow(pt.y - point.y, 2) <
Math.pow(radius, 2);
};
return this;
}
function startDragging(e) {
var p = new Point(e.offsetX, e.offsetY);
if(circle.isInside(p)) {
deltaCenter = new Point(p.x - circle.point.x, p.y - circle.point.y);
}
}
function drag(e) {
if(deltaCenter != null) {
circle.point.x = (mouseX(e) - deltaCenter.x);
circle.point.y = (mouseY(e) - deltaCenter.y);
drawCircle(circle);
}
}
function stopDragging(e) {
deltaCenter = null;
}
function drawCircle(circle) {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.arc(circle.point.x, circle.point.y, circle.radius, 0, Math.PI*2, true);
ctx.fill();
}
var circle = new Circle(new Point(30, 40), 25);
var deltaCenter = null;
var element;
</script>
</head>
<body>
<canvas id="canvas" width="400" height="300"></canvas>
</body>
</html>
Try it on jsFiddle
The same effect can be accomplished using Raphael.js (http://raphaeljs.com/) with Joint.jS (http://www.jointjs.com/).
Shapes created with Raphael can be accessed like any DOM element and can be manipulated via attributes. It is an awesome framework.
Joint.js helps in connecting the shapes. They also have a diagramming library and can help create ERD, Statemachine and several common diagrams. The best part is that you can extend their diagram element and create your own custom elements. Its jaw-dropingly cool.
Checkout their demos with source code at http://www.jointjs.com/demos
If you are using the raphael as "raw" lib you must handle the undo/redo by yourself.
The graphiti lib did have Undo/Redo Stack inside and supports the export for SVG, PNG, JSON,...
Additional you have some kind of Viso like connectors and ports.
http://www.draw2d.org/graphiti/jsdoc/#!/example
Greetings
I don't think there's an easy way to do this.
If you're just dealing with lines, my approach would be to keep track of all lines created, with starting coordinates, ending coordinates and some kind of z-index. When the user starts a dragging action (onmousedown), you have to check if the point is near the line, and then update the object and redraw the canvas when the mouse is moved.
How can I tell if a point belongs to a certain line?
This gets a lot more complicated if you're dealing with complex objects though. You'll probably have to find a solution to check if a point is inside a path.
Objects drawn into HTML5 Canvas are turned into pixels and then forgotten. You can't adjust properties on them and have the canvas update to see the effects. You can remember them yourself, but the canvas will still have those pixels set, so you'd have to basically redraw the whole canvas (or at least some of it) when you adjust a property.
You might want to consider SVG for this application instead, SVG elements are remembered in the DOM and when their properties are updated the browser will update the graphic to reflect the changes.
If you must use canvas, then you're going to need to write quite a bit of code to handle mouse-hits, object properties, and repaints.

Categories

Resources