I am using the FreeTransform plugin for moving and scaling objects.
I want to limit this moving and scaling to the size of another rect which contains this object. How can I achieve this?
I have provided an example of problem on JSFiddle. (I want the red rect to stay inside the other rect.)
Thank you.
The FreeTransform plugin provides the option to set a boundary:
boundary: { x: x-pos, y: y-post, width: i, height: i},
see the documentation
https://github.com/ElbertF/Raphael.FreeTransform/
Related
I wanted to enhance the drawing application I built with JS by allowing the user to draw various shapes. I want to make it convenient for the users by allowing them to drag these shapes around. So I used jCanvas, since it offers a simple way of dragging a shape:
$("#can").drawRect({
draggable: true,
fillStyle: "#000",
width: 100, height: 100,
x: 100,
y: 100,
});
The problem is, I need a function to erase it again. So I made this script:
<script>
$("#can").drawRect({
draggable: true,
fillStyle: "#000",
width: 100, height: 100,
x: 100,
y: 100,
});
$("#erase").click(function () {
$("#can").clearCanvas();
});
</script>
<canvas id="can" width="200px" height="150px"></canvas>
<button id="erase">Clear Canvas</button>
This doesn't work though. When I erase, it clears out everything at first, but when I try to draw on the Canvas, the shape appears again.
I checked the code of jCanvas, and it appears that it just draws tons of rectangles when dragged, and clears them away to create the illusion of the shape being dragged. But when this happens, the cleared Canvas retreats itself and the shape is visible again.
Is there a way to clear the shape away for eternity? Or do I have to reload the page for that to work?
Thanks in advance
You are not using Layer explicitly, but when you set drag property the Canvas create a layer:
Layers can be made draggable using the draggable property.
https://projects.calebevans.me/jcanvas/docs/draggableLayers/
So, clearCanvas is not suitable:
This method is not meant to be used if you are using the jCanvas Layer API, because the API handles redrawing for you in many cases, and so if you try to clear the canvas. you layers will eventually be redrawn by jCanvas when it deems necessary.
You need remove the layer:
$('canvas').removeLayer(0);
or
$('canvas').removeLayers();
Look more options in Doc: https://projects.calebevans.me/jcanvas/docs/manipulateLayers/
If this help you, check my answer as correct or voteup!
I'm having an issue animating text using snap.svg. I'm moving text around an arc, from the bottom left of the arc to its apex. I'm using the standard Snap.animate functionality with its built-in setter function.
When I animate a random element (such as the circle I've included in the examples below), the animation behaves as expected. When I animate plain text it also behaves as expected. When I add a textpath attribute to that text, however, the animation functions differently in ways I don't understand.
This text animates as expected:
svg.text(0,200,'Regular Text').attr({'text-anchor': 'middle'});
Example (hover for animation): http://codepen.io/anon/pen/pJbmYW
Whereas this text stops short of its desired destination (also the top of the arc:
var path = 'M0 200 A 200 200, 0, 1, 1, 400 200';
svg.text(0,200,'Arced Text').attr({'text-anchor': 'middle',
'textpath':path});
Example (hover for animation): http://codepen.io/anon/pen/GJqaVp
I suppose I don't understand what adding the textpath is doing to the text object, as it seems I should be able to animate/transform its x and y coordinates as I could before I added the path.
Any insight or suggestions are welcome. Thanks.
It doesn't really make sense to animate x,y for a textPath in this case I think (I may be wrong), as what does that mean in respect to a fluctuating line.
I think what you want is to animate the startOffset. Eg...
Snap.animate(0, arc.getTotalLength()/2,
function(val){
var point = arc.getPointAtLength(val);
circ.attr({cx: point.x,
cy: point.y});
arcText.textPath.attr({ startOffset: val})
},1000,mina.easeinout);
with this bit being the main change ...
arcText.textPath.attr({ startOffset: val})
codepen (hover over)
I am looking for a way to achieve only an inner glow or shadow on a raphael path. Unfortunately, you can only do radial gradients on an ellipse or a circle.
One idea may be to create a series of paths which are slightly smaller and fit inside the original path and then to give them different stroke colors, but I have no idea how I would approach that. Some function that takes the path and subtracts or adds values to the numbers depending on where they are... Anyway, if anyone has any ideas, or maybe another javascript library that does this, that would be great.
Ok here is how you can achieve that. It is pretty straightforward I think. I know it is hard to manually create a shadow path from your original. But there is a trick called scale() function. Steps to how you can get inner shadow or inner glow effect:
Create your path
Clone it into another path
Set the scale() of cloned path to be 0.9*original
Then hide the cloned path, but apply glow() function on it
The code:
var paper = Raphael("notepad", 500, 500);
var path = paper.path("M 50 200 L 120 100 200 190 80 250z");
var shadow = path.clone().scale(0.9).hide();
shadow.glow();
path.attr({stroke: "darkred"});
Look at the DEMO, this is not perfect but with minor changes, yo can get what you want.
Also as a side note:
glow() function has attributes like offsetx, offsety, opacity... Changing those attributes will give you your preferred shadow/glow.
UPDATED CODE http://jsfiddle.net/jUTFm/41/
Look here. You could try animating the width of the path and darkening the color gradually to give some kinda glowing effect.
check out the bottom part
brain = paper.add(brain);
brain.attr('stroke', '#ff0');
brain.transform('s 0.5, 0.5 0 0');
glow = brain.glow({
color: '#ff0',
width: 5
});
anim = Raphael.animation({
"stroke-width": 15,
opacity: 1
}, 500);
anim = anim.repeat(Infinity);
glow.animate(anim);
I'm trying to change one of the Y-coordinates of an SVG line, I'm using jQuery and the SVG plugin + animation plugin. I have been animating the lines previously, but here the function needs to simply change the position,
this works;
$(strings[i]).animate({
svgY1 : 150
}, 0);
this does not;
$(strings[i]).attr(
'svgY1', '150'
);
I can see I shouldn't be using animate here, but I don't know why attr or css don't work in this context? I figure the problem is that svgY1 isn't the correct way to identify that coordinate maybe but I'm stuck.
At this point all concerned elements are static, I'm pretty sure it's not interference from another function.
First, give the lines unique identifiers:
svg.line(g, 450, 120, 550, 20, {strokeWidth: 5, id: '123'});
Now use the change function of the svg manager:
svg.change(svg.getElementById('123'), { y1: 150 });
I just started with fabric.js and I have a (probably beginner) error:
I am using fabric with jquery with the following code:
$(document).ready(function () {
canvas = new fabric.StaticCanvas('scroller');
canvas.add(
new fabric.Rect({ top: 0, left: 0, width: 140, height: 100, fill: '#f55' })
);
});
This code should draw a 140x100 Rectangle on the canvas.
Sadly, only a quarter of the Rectangle appears.
If I change the top and left values to higher numbers, more of the Rectangle appears on the canvas.
So it seems, that the canvas origin is not at 0/0, but at sth. higher.
Does someone know how to fix this or what I am doing wrong?
Thanks in advance,
McFarlane
Here is a jsfiddle link with some examples http://jsfiddle.net/pukster/sdQ7U/2/
My guess is that fabric.js calculates everything from the origin (middle point) since it is drawing exactly one quarter of a rectangle even with a canvas 10 times the size of the rectangle. My guess is that top and left actually refer to the origin and not the top and left sides of the imaginary bounding box. Trouble is there is very little documentation on fabricjs. Is there any reason you are using fabricjs and not easeljs
EDIT Here's the same fiddle but with squares instead of rectangles (it is more clear) http://jsfiddle.net/pukster/sdQ7U/3/
EDIT OK I am now almost absolutely certain that fabric.js uses the center as the top/left. I ripped their example off of their site and overlayed it with the transparent couterpart to those shapes had they been coded in pure canvas http://jsfiddle.net/pukster/uathZ/2/ (blue border is the limit of the canvas element).
What you see is that the boxes are exactly offset by half but the circle (I only drew a semi circle otherwise it would not have been discernable) is perfectly overlapped. This is b/c in HTML Canvas, the circle coordinates (x,y) refer to the origin and not the top left. I did not bother with the triangle b/c my trigonometry is a bit rusty. I personally think it's misleading to use the terms top and left, when x and y would have been more representative and shorter.
Yes, this is highly unexpected and even more undocumented.
Workaround:
Set
originX: "left"
originY: "top"
for each created object.
edit: or use kangax simpler solution in the comment below.
I want to comment but lack the reputation to do so. So anyway, here is what happens when I do the following:
fabric.Object.prototype.originX = "left";
fabric.Object.prototype.originY = "top";
The shape gets rendered fine but when I select it for resizing or moving, it gets offset to a different location. The best approach seems to be to set the coordinates for every object separately using the set() method.