Raphael playground effect and fill opacity - image

I've written the following code:
var w = 800;
var h = 600;
var paper = Raphael(0, 0, w, h);
paper.image("http://static.pourfemme.it/pfmoda/fotogallery/625X0/63617/borsa-alviero-martini-rodeo-drive.jpg", 0, 0, w, h);
var c = paper.circle(400, 300, 1);
c.attr({stroke: "#999", "stroke-width": w*2});
anim = Raphael.animation({r: w*2}, 6000);
c.animate(anim.delay(100));
( http://jsfiddle.net/qAgy7/ )
I need to visualize background image when the circle enlarges its radius, however I have the following problems:
I don't understand why the animation run slowly
Chrome render the effect in different way (I see a polygon not a circle like in
Firefox and IE)
Someone can help me?

Related

Best way to paint rectangles in three.js

EDIT: I solved my problem and this is what is was for. It now uses raw webgl and two triangles for each rectangle.
I'm a seasoned developer, but know next to nothing about 3d development.
I need to animate a million small rectangles where I set the coordinates in Javascript (rather than through a shader). (EDIT: It's a 2D job and I'm looking at webgl for performance reasons only.) I tweaked an existing threejs sample that uses "Points" to modify the coordinates in a BufferGeometry via Javascript and that performs really well, even with a million points.
The three.js concept of "Points", however, is a bit weird in that it appears they have to be squares - my rectangles can't be quite squares though, and they are of slightly different dimensions each.
I can think of a couple of workarounds, such as having foreground-colored squares partially overlap with squares of a background-color, thereby molding them into the correct rectangle. That's quite hacky though.
Another possibility would be to not do it with points but rather with proper triangles; but then I need to set 12 values from Javascript (2 triangles, 3 edges, 2 dimensions) rather than just the needed 4 (x, y, width, height). I suppose that could be improved with a vertex shader somehow, but that will be tricky for a noob like me.
I'm looking for some suggestions or, alternatively, a sample on how to set a large number of vertex coordinates from Javascript in threejs (the existing samples all appear to assume that manipulation is done in shaders, but that doesn't work so well for my use case).
EDIT - Here's a picture of how the rectangles could be laid out:
The rectangle's top and bottom edges are arbitrary, but they are organized into columns of arbitrary widths.
The rectangles of each column all have the same, uniform color.
Just an option with canvas and .map:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 0, 10);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
var gh = new THREE.GridHelper(10, 10, "black", "black");
gh.rotation.x = Math.PI * 0.5;
gh.position.z = 0.01;
scene.add(gh);
var canvas = document.createElement("canvas");
var map = new THREE.CanvasTexture(canvas);
canvas.width = 512;
canvas.height = 512;
var ctx = canvas.getContext("2d");
ctx.fillStyle = "gray";
ctx.fillRect(0, 0, canvas.width, canvas.height);
function drawRectangle(x, y, width, height, color) {
let xUnit = canvas.width / 10;
let yUnit = canvas.height / 10;
let x_ = x * xUnit;
let y_ = y * yUnit;
let w_ = width * xUnit;
let h_ = height * yUnit;
ctx.fillStyle = color;
ctx.fillRect(x_, y_, w_, h_);
map.needsUpdate = true;
}
drawRectangle(1, 1, 4, 3, "aqua");
drawRectangle(0, 6, 6, 3, "magenta");
drawRectangle(3, 2, 6, 6, "yellow");
var plane = new THREE.Mesh(new THREE.PlaneBufferGeometry(10, 10), new THREE.MeshBasicMaterial({
color: "white",
map: map
}));
scene.add(plane);
renderer.setAnimationLoop(() => {
renderer.render(scene, camera);
});
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
Read the source for these samples:
https://threejs.org/examples/?q=buffer#webgl_buffergeometry_custom_attributes_particles
https://threejs.org/examples/?q=buffer#webgl_buffergeometry_instancing
https://threejs.org/examples/?q=buffer#webgl_buffergeometry_instancing_billboards
https://threejs.org/examples/?q=buffer#webgl_buffergeometry_points

jCanvas method drawRect() position issue

I have a problem with jCanvas which is a framework drawing canvas and jquery.
When I set x = 0 , y = 0 The .drawRect output should be same as the pure javascript result.
I tried the document and google but I did not find anything to solve this.
Screen shoot:
Pure js result
jCanvas result
Please help me.
Many thanks.
// Pure javascript
var canvas = document.getElementsByTagName('canvas')[0];
var ctx = canvas.getContext("2d");
ctx.fillStyle = 'blue';
ctx.fillRect(0, 0, 100, 100);
// jCanvas
$('canvas').drawRect({
fillStyle: '#000',
x: 0, y: 0,
width: 100,
height: 100
});
To run this code, please copy and pass to this sanbox.
https://projects.calebevans.me/jcanvas/sandbox/
From jCanvas documentation:
The [.drawRect's] fromCenter property determines if a rectangle’s x and y properties lie at its center (as opposed to its top-left corner). This property is true by default.
So yeah. Your X and Y with jCanvas, refer to the center of the rectangle, unlike canvas' fillRect X and Y, which refer to the top left corner of the rectangle.

pulling images from different canvas and exporting to single pdf

I have a situation where i am generating several graphs in web page and showing them in canvas and my requirement is that on click of download button,i should be able to export all canvas images to pdf.
I have successfully done this for single canvas element using html2canvas and Jspdf but cannot figure out how to do the same for all.
I followed this JSFiddle code for generating pdf from Html2canvas and jspdf.
jsfiddle
$(document).ready(function() {
var d_canvas = document.getElementById('canvas');
var context = d_canvas.getContext('2d');
context.moveTo(20, 20);
context.lineTo(100, 20);
context.fillStyle = "#999";
context.beginPath();
context.arc(100, 100, 75, 0, 2 * Math.PI);
context.fill();
context.fillStyle = "orange";
context.fillRect(20, 20, 50, 50);
context.font = "24px Helvetica";
context.fillStyle = "#000";
context.fillText("Canvas", 50, 130);
$('#ballon').draggable();
$('#download').click(function() {
html2canvas($("#canvas"), {
onrendered: function(canvas) {
var imgData = canvas.toDataURL(
'image/png');
var doc = new jsPDF('p', 'mm');
doc.addImage(imgData, 'PNG', 10, 10);
doc.save('sample-file.pdf');
}
});
});
});
Kindly help,thanks in advance.
It was very simple ,I just changed the argument to this line
html2canvas($("#canvas"), {
Instead of passing seperate canvases and then trying to export them to single pdf rather i kept different canvases in on Div and passed the Div id to the above mentioned line and both canvases were exported to single pdf file
There should be no need to use html2canvas for this. It will only deliver you another canvas element at a cost. You can use the original canvas element and toDataURL() directly with jsPdf.
Example (partly pseudo)
This will collect all canvases in the page and put them in a PDF. The pseudo part is the missing variables for width, deltas, factor etc. But you should get the gist of it.
Note: The size for images must be given in the same unit you're using for the document, so you need to convert pixel positions and sizes into millimeter representation using a pre-calculated factor based on document DPI (not shown here, but this may help).
var x = someX,
y = someY,
dx = somDeltaForX,
dy = somDeltaForY,
i,
canvases = document.querySelectorAll("canvas"),
pdf = new jsPDF('p', 'mm'),
f = convertionFactorFromPixelstoMM;
for(i = 0; i < canvases.length; i++) {
var url = canvases[i].toDataURL("image/jpeg", 0.75);
doc.addImage(url, "JPEG", x * f, y * f, canvases[i].width * f, canvases[i].height * f);
x += dx; // tip: dx could also be based on previous canvas width in non-uniform sizes
if (x > widthOfPage) {
x = 0;
y += dy;
}
}

HTML5 Cropped Canvas Image Not Showing

I am learning HTML5 and JavaScript and am attempting to draw an animated image. I thought the easiest way to do this would be to create an image with the frames in a row, as below.
Image http://html5stuff.x10.mx/HTML5%20Test/alien_green_strip8.png
Then a only part of the image would be draw at a time. I followed this tutorial.
This is a link to what I have made:
html5stuff.x10.mx/HTML5%20Test/page.html
The problem is, the image isn't being drawn. It's something within the drawSprite function, because when I change it to a simple "ctx.drawImage(sprite.source, x, y)", it does draw the image (just as a whole without the animation, obviously). Please note that though there is an option for rotating the image, I have not yet added support for that. Also, keys.js is not being used yet though it is included.
The reason is because sprite.imagenum is not defined when drawSprite is called.
This is because in some places you use imagenum and others imgnum, so correct that typo and you're good to go!
TOTALLY OPTIONAL:
But now that thats answered lets take a look at your js to get a better idea of how to structure this. You have:
function Sprite(){
var imagenum = null; //The number of images
var width = null; //The width of each image
var height = null; //The height on each image
var xoffset = null; //The origin on each image
var yoffset = null;
var source = null; //The location of each image
}
function drawSprite(sprite, subimg, x, y, w, h, angle){
ctx.drawImage(sprite.source, Math.floor(subimg) * sprite.width, 0, w * sprite.imagenum, h, x - sprite.xoffset * (w/sprite.width), y - sprite.yoffset * (h/sprite.height), w, h);
}
All those var statements are actually doing nothing. It should be:
function Sprite(){
this.imagenum = null; //The number of images
this.width = null; //The width of each image
this.height = null; //The height on each image
this.xoffset = null; //The origin on each image
this.yoffset = null;
this.source = null; //The location of each image
}
in order to correctly set them as you were envisioning. Also, you can rewrite drawSprite so that the sprites are drawing themselves, so that you don't need to pass them as an argument:
// now we can use "this" instead of "sprite"
Spite.prototype.draw = function(subimg, x, y, w, h, angle){
// put this on several lines just so we can see it easier
ctx.drawImage(this.source,
Math.floor(subimg) * this.width,
0,
w * this.imagenum, h,
x - this.xoffset * (w/this.width),
y - this.yoffset * (h/this.height),
w, h);
}
Then instead of:
drawSprite(img, index, 128, 128, 32, 32, 0); // img is a sprite
We can write:
img.draw(index, 128, 128, 32, 32, 0); // img is a sprite

Chrome Canvas Linear Gradient != Firefox Canvas Linear Gradient

Well , the problem is the next :
canvas = GreenCanvas.get(0).getContext('2d');
grad = canvas.createLinearGradient(0,0,255,0);
grad.addColorStop(0, 'rgb('+r+','+0+','+b+')');
grad.addColorStop(1, 'rgb('+r+','+255+','+b+')');
canvas.fillStyle = grad;
canvas.fillRect(0,0,256,34);
256 pixels . from for example rgb(0,0,0) to rgb(0,255,0)
Chrome 6.0.472: gradient (0,0,0) (0,1,0) (0,2,0) (0,3,0) (0,4,0) ... (0,255,0)
Firefox 3.6.6: gradient (0,0,0) (0,0,0) (0,1,0) (0,2,0) ... (0,255,0)
i would like to see who programs that gradient function in firefox . But anyway , i would like to know if its a real problem , or is that in firefox the gradient is done that manner. Or if it exist another manner to do a well done gradient without using too much memory.
It's known that Chrome has problems with the Canvas gradients at the moment.
I submitted a bug to Chromium because of how many of hixie's (the specification writer) tests were failing on Chrome.
In short, you can't make your 'grad' variable. You have to set it directly.
This works:
var context = document.getElementsByTagName('canvas')[0].getContext('2d');
context.fillStyle = context.createLinearGradient(0, 0, 500, 300);
context.fillStyle.addColorStop(0, '#0000ff');
context.fillStyle.addColorStop(1, '#ff00ff');
context.fillRect(0, 0, 500, 300);
This does NOT work, even though they are SUPPOSED to do the same thing:
var context = document.getElementsByTagName('canvas')[0].getContext('2d');
var g = context.createLinearGradient(0, 0, 500, 300);
g.addColorStop(0, '#0000ff');
g.addColorStop(1, '#ff00ff');
context.fillStyle = g;
context.fillRect(0, 0, 500, 300);
For now, just do it the first way.
Here's the filed bug report from early September.
http://code.google.com/p/chromium/issues/detail?id=54070&can=4&colspec=ID%20Stars%20Pri%20Area%20Feature%20Type%20Status%20Summary%20Modified%20Owner%20Mstone%20OS

Resources