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.
Related
I'm trying to place an HTML div element over a three.js object. Most stackoverflow solutions offer a pattern similar to this:
// var camera = ...
function toScreenXY(pos, canvas) {
var width = canvas.width, height = canvas.height;
var p = new THREE.Vector3(pos.x, pos.y, pos.z);
var vector = p.project(camera);
vector.x = (vector.x + 1) / 2 * width;
vector.y = -(vector.y - 1) / 2 * height;
return vector;
}
I've tried many variations on this idea, and all of them agree on giving me this result:
console.log(routeStart.position); // target mesh
console.log(toScreenXY(routeStart.position));
// output:
//
// mesh pos: T…E.Vector3 {x: -200, y: 200, z: -100}
// screen pos: T…E.Vector3 {x: -985.2267639636993, y: -1444.7267503738403, z: 0.9801980328559876}
The actual screen coordinates for this camera position and this mesh position are somewhere around x: 470, y: 80 - I determined them by hardcoding my div position.
-985, -1444 are not even close to the actual screen coords :)
Please don't offer links to existing solutions if they follow the same logic as the snippet I provided. I would be especially thankful if someone could explain why I get these negative values, even though this approach seems to work for everyone else.
Here's a couple of examples using the same principle:
Three.js: converting 3d position to 2d screen position
Converting World coordinates to Screen coordinates in Three.js using Projection
Now, I've figured out the problem myself! Turns out, you can't project things before calling renderer.render(). It's very confusing that it gives you back weird negative coords.
Hope other people will find this answer useful.
I'm trying to rotate an image added to my canvas using KineticJS.
I got it almost working.
I know I need to set the offset to 'move' the rotation point, that part is working.
But it is also moving to that location of the offset.
After doing some rotating I can drag my image to another location in the canvas and continue rotating around its own center.
I don't want to rotate the whole canvas, because I have multiple images on a layer.
The relevant code:
function rotateLayer() {
// Rotate bird image
var rotation = 15;
// Set rotation point:
imageDict[1].setOffsetX(imageDict[1].width() / 2);
imageDict[1].setOffsetY(imageDict[1].height() / 2);
// rotation in degrees
imageDict[1].rotate(rotation);
imageDict[1].getLayer().draw();
}
A working demo is on jsfiddle: http://jsfiddle.net/kp61vcfg/1/
So in short I want the rotation but not the movement.
How you want to rotate without movement?
KineticJS rotate objects relative it's "start point" . For example for Kinetic.Rect start points is {0, 0} - top left corner. You may move such "start point" to any position with offset params.
After a lot of trail and error I found the solution.
The trick is to set the offset during load to the half width and height to set the rotation point to the middle of the image AND don't call image.cache:
function initAddImage(imgId, imgwidth, imgheight) {
var imageObj = new Image();
imageObj.src = document.getElementById(imgId).src;
imageObj.onload = function () {
var image = new Kinetic.Image({
image: imageObj,
draggable: true,
shadowColor: '#787878',
shadowOffsetX: 2,
shadowOffsetY: 2,
width: imgwidth,
height: imgheight,
x: 150, // half width of container
y: 150, // half height of container
offset : {x : imgwidth / 2, y : imgheight / 2}, // Rotation point
imgId: imgId
});
layer.add(image);
//image.cache();
layer.draw();
imageDict[currentLayerHandle] = image;
currentLayerHandle++;
};
}
I've updated my demo to a working version:
http://jsfiddle.net/kp61vcfg/2/
I have to set a limit for the movement of a circle when the coordinate 'y' is on the pixel 'y-15', on a specific coordinate (x,y). I've tried to use 'draggable=true' with the event 'mouseup' and 'mousedown', but I can't get the results that I need. Can someone help me, please?
My code is:
circle.on('mouseover',function(){
this.setAttr('draggable',true);
});
circle.on('dragmove',function(e){
var mousePos = stage.getMousePosition();
var x = mousePos.x;
var y = mousePos.y;
if(y < y2- 15){
//do anything
}
else{
this.setAttr('draggable',false);
}
});
If I understand correctly, what you want is dragBoundFunc.
See this tutorial:
http://www.html5canvastutorials.com/kineticjs/html5-canvas-drag-and-drop-bounds-tutorial-with-kineticjs/
// bound below y=50
var blueGroup = new Kinetic.Group({
x: 100,
y: 70,
draggable: true,
dragBoundFunc: function(pos) {
var newY = pos.y < 50 ? 50 : pos.y;
return {
x: pos.x,
y: newY
};
}
});
You'll just have to modify your code to look for y-15 when you grab your mouse coordinates, and set the dragBoundFunc to reflect the coordinates you clicked on.
If you're trying to limit the y-axis on a known fixed y value, then this becomes even easier, exactly like how the tutorial shows you, except you just have to change the coordinate that you want to limit Y to.
Check this one as a quick reference too:
http://www.html5canvastutorials.com/kineticjs/html5-canvas-drag-and-drop-shapes-horizontally-or-vertically-tutorial/
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?
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