How to draw shadow only in right and bottom side of object in createjs. there is no shadow over the object or on top and left side.
the shadow contains only 4 parameters
1. color of shadow
2. x
3. y
4. blur effect
but it didn't tell anything about 4 different sides.
var box = createjs.Shape();
box.shadow = new createjs.shadow('#000',4,4,5);
the above code generates some blur portion over top and left part of object.
Your example is working for me, I've tested on fiddle.net using firefox and chrome.
http://jsfiddle.net/by1vf7oc/
var box = new createjs.Shape();
box.graphics.beginFill("red").drawRect(100, 100, 100, 100);
box.shadow = new createjs.Shadow('#000', 4, 4, 5);
Try to test on these browsers, using the last version of the createjs.
Try this:
var box = new createjs.Shape();
box.graphics.beginFill("red").drawRect(0, 0, 100, 100);
box.shadow = new createjs.Shadow("#000000", 10, 10, 0);
this is giving dark black color with outline of shadow box over object. i need blurred shadow on right and bottom with no effect on object.
Related
In SkiaSharp I can nicely fill the space between two curves by using SKPathFillType.EvenOdd. Below I show a simplified excerpt from the code.
My question is how can I give a certain pattern to this filled area between the curves ? Here I can only fill it with a color and give it a transparency. I'm interested in applying a pattern, such as hatch or dots.
Thank you for any support.
Greetings,
Sorin
SKPath path = new SKPath();
path.FillType = SKPathFillType.EvenOdd;
// start the first curve
path.MoveTo(....);
path.LineTo(....); // draw the curve and close it
....
path.AddCircle(....); // add a second curve as a circle
SKPaint paint = new SKPaint(new SKFont(SKTypeface.Default)) {
IsAntialias = true,
Style = SKPaintStyle.Fill,
Color = SKColors.Blue.WithAlpha((byte)(0xFF * (1 - 0.5))),
StrokeWidth = 1
};
canvas.DrawPath(path, paint);
I've managed to fix this with a trick.
First of all, I do all I wrote above, i.e.
canvas.DrawPath(path, paint)
.... will draw a filled area between the two curves, with a certain transparency.
On top of that (literally), I draw another pattern:
var hatch = new SKPath();
hatch.AddCircle(0, 0, 1);
var hatchPaint = new SKPaint {
PathEffect = SKPathEffect.Create2DPath(SKMatrix.MakeScale(7, 7), hatch),
Color = SKColors.RosyBrown,
Style = SKPaintStyle.Stroke,
StrokeWidth = 3
};
And again:
canvas.DrawPath(path, hatchPaint);
This draws a nice hatch pattern on top of the filled area between the curves.
Note: the size of the pattern is essential - here AddCircle(0, 0, 1), where the circle ray is 1 pixel. If you have a larger one, the hatch pattern will spill out the filled area, which is not what you want. To me this looks like a bug in SKIA.
Here's a demonstration:
var ctx = document.getElementById("test").getContext("2d");
ctx.shadowColor = "black";
ctx.fillStyle = "white";
ctx.shadowBlur = 10;
ctx.fillRect(10, 10, 10, 10);
ctx.shadowBlur = 50;
ctx.fillRect(70, 10, 10, 10);
ctx.fillRect(70, 70, 70, 70);
<canvas id="test" width="200" height="200"></canvas>
If I set shadowBlur=10 and then draw a small 10x10 square, I get a nice, strong shadow. The same if I set shadowBlur=50 and draw a big 70x70 square. But if I set shadowBlur=50 and then draw a small 10x10 square, I get a very faint, barely visible shadow.
Instead I would have expected a small center square and a large dark shadow all around it.
Obviously I misunderstand how the shadow blur works, so - how does it work, and how do I get a large dark shadow around a small object?
The shadowBlur uses Gaussian blur to produce the shadow internally. The object is drawn to a separate bitmap as stencil in the shadow-color and then blurred using the radius. It does not use the original shape after this step. The result is composited back (as a side-note: there was previously a disagreement on how to composite shadows so Firefox and Chrome/Opera rendered them differently - I think they have landed on source-over in both camps by now though).
If the object is very small and the blur radius very big, the averaging will be thinned by the empty remaining space around the object leaving a more faint shadow.
The only way to get a more visible shadow with the built-in method is to use a smaller radius. You can also "cheat" using a radial gradient, or draw a bigger object with shadow applied to an off-screen canvas but offset relative to the shadow itself so the object doesn't overlap it, then draw the shadow only (using clipping arguments with drawImage()) back to main canvas at desired size before drawing main object.
In newer versions of the browsers you can also produce Gaussian blurred shadows manually using the new filter property on the context with CSS filters. It do require some extra compositing steps and most likely an off-screen canvas for most scenarios, but you can with this method overdraw shadows in multiple steps with variable radii from small to bigger producing a more pronounced shadow at the cost of some performance.
Example of manually generated shadow using filter:
This allow for more complex shapes like with the built-in shadow, but offer more control of the end result. "Falloff" in this case can be controlled by using a easing-function with an initial normalized radius value inside the loop.
// note: requires filter support on context
var ctx = c.getContext("2d");
var iterations = 16, radius = 50,
step = radius / iterations;
for(var i = 1; i < iterations; i++) {
ctx.filter = "blur(" + (step * i) + "px)";
ctx.fillRect(100, 50, 10, 10);
}
ctx.filter = "none";
ctx.fillStyle = "#fff";
ctx.fillRect(100, 50, 10, 10);
<canvas id=c></canvas>
Example of gradient + filter:
This is a more cross-browser friendly solutions as if filter is not supported, at least the gradient comes close to an acceptable shadow. The only drawback is it is more limited in regards to complex shapes.
Additionally, using a variable center point for the gradient allows for mimicking fall-off, light size, light type etc.
Based on #Kaiido's example/mod in comment -
// note: requires filter support on context
var ctx = c.getContext("2d");
var grad = ctx.createRadialGradient(105,55,50,105,55,0);
grad.addColorStop(0,"transparent");
grad.addColorStop(0.33,"rgba(0,0,0,0.5)"); // extra point to control "fall-off"
grad.addColorStop(1,"black");
ctx.fillStyle = grad;
ctx.filter = "blur(10px)";
ctx.fillRect(0, 0, 300, 150);
ctx.filter = "none";
ctx.fillStyle = "#fff";
ctx.fillRect(100, 50, 10, 10);
<canvas id=c></canvas>
Normally to cut one shape out from another using Canvas, I've used the globalCompositeOperation option "xor":
var c2 = document.getElementById('canvas').getContext('2d');
c2.globalCompositeOperation = "xor";
c2.fillRect(0, 0, 200, 200);
c2.fillRect(170, 0, 30, 30); // shape 2 is cut out from shape 1
However, when either the fillStyle has a alpha value < 1, or the globalAlpha of the context is < 1, the "cut-out" shape is no longer completely invisible.
Specifically, if the alpha is >0.5 and <1, you see a lighter version of the shape. If the alpha is 0.5, there is no cut-out visible at all. And if alpha is <0.5, we get the inverse: the shape that's supposed to be cut out is in fact darker than the first shape.
This can be seen at http://jsfiddle.net/N7aXY/2/.
You can try changing the alpha value to see the different effects.
Is there any way to completely cut out a shape when the background shape has an alpha < 1?
Ok, this is a bit "hackish", but here we go anyway:
Set compositing to XOR.
Draw to "cut" shape2 from shape1 normally.
Save the canvas.
Set compositing to normal (source-over).
Set globalAlpha to your desired level.
Clear the canvas and redraw the saved image.
Results: globalAlpha and globalCompositing work in harmony!
Here is code and a Fiddle: http://jsfiddle.net/utttk/1/
ctx.fillStyle="red";
ctx.globalCompositeOperation="xor";
ctx.fillRect(0,0,200,200);
ctx.fillRect(170,0,30,30);
var png=canvas.toDataURL();
ctx.globalCompositeOperation="source-over"; // "normal" compositing
ctx.globalAlpha=.2;
var image=new Image();
image.onload=function(){
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(image,0,0);
}
image.src=png;
I am using Raphael js to draw circled numbers. The problem is that each number has a different width/height so using one set of coordinates to center the text isn't working. The text displays differently between IE, FF, and safari. Is there a dynamic way to find the height/width of the number and center it accordingly?
Here is my test page:
http://jesserosenfield.com/fluid/test.html
and my code:
function drawcircle(div, text) {
var paper = Raphael(div, 26, 26); //<<
var circle = paper.circle(13, 13, 10.5);
circle.attr("stroke", "#f1f1f1");
circle.attr("stroke-width", 2);
var text = paper.text(12, 13, text); //<<
text.attr({'font-size': 15, 'font-family': 'FranklinGothicFSCondensed-1, FranklinGothicFSCondensed-2'});
text.attr("fill", "#f1f1f1");
}
window.onload = function () {
drawcircle("c1", "1");
drawcircle("c2", "2");
drawcircle("c3", "3");
};
Thanks very much!
(Answer rewritten): Raphael.js centers text nodes both horizontally and vertically by default.
"Centering" here means that the x, y argument of paper.text() method expects the center of the text's bounding box.
So, just specifying the same x, y value as the circle should produce the desired result:
var circle = paper.circle(13, 13, 10.5);
var text = paper.text(13, 13, "10");
(jsFiddle)
Relevant source code:
source line responsible for vertical alignment
source line responsible for horizontal alignment
Maybe this:
var paper = Raphael(div, 26, 26); //<<
var circle = paper.circle(13, 13, 10.5);
circle.attr("stroke", "#f1f1f1");
circle.attr("stroke-width", 2);
var text = paper.text(0, 0, text); //<<
text.attr({'font-size': 15, 'font-family': 'FranklinGothicFSCondensed-1, FranklinGothicFSCondensed-2'});
text.attr("fill", "#f1f1f1");
text.translate((35 - text.getBBox().width)/2, (45 - text.getBBox().height)/2);
Use this attribute: 'text-anchor':'start':
paper.text( x, y, text ).attr( {'text-anchor':'start'} );
The Rotating Text Exactly example (listed in the right-hand column of the page, or here in github), discusses putting text in a precise position, along with, as usual, extra steps required to make things work in IE.
It does find a bounding box for the text; I imagine it is straightforward to move the text by half the bounding box as Jan suggested.
I'm building chart in Action Script 3.0 and need to set background color of the area where chart is drawn. I found solutions how to set background color for all chart, but it's not exactly what I need: I need to color chart part where plot is drawn
in your chart you need to add a background element with a CartesianDataCanvas. Then in the AS you can add elements to that chartBackground. For Example
<mx:LineChart id="chart">
<mx:backgroundElement>
<mx:CartesianDataCanvas id="chartBackground" includeInRanges="true"/>
</mx:bakgroundElement>
</mx:LineChart>
...
private function addToBackground_():void
{
var box:Canvas = new Canvas();
box.setStyle("backgroundColor", "green");
box.setStyle("backgroundAlpha", 0.5);
box.width = 100;
box.height = 100;
chartBackground.addDataChild(box, new CartesianCanvasValue(chart.horizontalAxis.minimum, 0),
CartesianCanvasValue(chart.verticalAxixs.maximum, 0));
}
This will add a transparent green square at the top left corner of the plot