Change water color in d3 orthographic transition map - d3.js

I am new to D3 and this is my first question to stackoverflow.
I am trying to change the color of the water in this example that contains transitions:
http://bl.ocks.org/mbostock/4183330
I am able to change the color in this example, which is static: http://bl.ocks.org/mbostock/3757125
I found this thread: How can I color ocean with topojson in d3 when I have coordinate info for land? However, this changes the area outside of the globe as well.
This section of the code appears to be the styling, but I can't figure what to add to change the water color.
c.fillStyle = "#bbb", c.beginPath(), path(land), c.fill();
c.fillStyle = "#f00", c.beginPath(), path(countries[i]), c.fill();
c.strokeStyle = "#fff", c.lineWidth = .5, c.beginPath(), path(borders), c.stroke();
c.strokeStyle = "#000", c.lineWidth = 2, c.beginPath(), path(globe), c.stroke();
Also, seeing the line of code below, I searched online for a reference list of possible topojson features and/or objects that might indicate water, and maybe I could figure out how to style that, but couldn't find one:
land = topojson.feature(world, world.objects.land),
I'm wondering if maybe this has something to do with canvas (which I don't really grasp).
Hopefully, I'm overlooking something obvious and noob-like.
Thanks much!

Ha! Of course:
Modify this line:
c.strokeStyle = "#ccc", c.lineWidth = .5 * ratio, c.beginPath(), path(globe), c.stroke();
To this:
c.fillStyle = "#000", c.beginPath(), path(globe), c.fill();
I feel silly, but I guess sometimes it takes writing it all out for the brain cells to click. Thanks!

Related

Outline object (normal scale + stencil mask) three.js

For some time, I've been trying to figure out how to do an object selection outline in my game. (So the player can see the object over everything else, on mouse-over)
This is how the result should look:
The solution I would like to use goes like this:
Layer 1: Draw model in regular shading.
Layer 2: Draw a copy in red color, scaled along normals using vertex shader.
Mask: Draw a black/white flat color of the model to use it as a stencil mask for the second layer, to hide insides and show layer 1.
And here comes the problem. I can't really find any good learning materials about masks. Can I subtract the insides from the outline shape? What am I doing wrong?
I can't figure out how to stack my render passes to make the mask work. :(
Here's a jsfiddle demo
renderTarget = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, renderTargetParameters)
composer = new THREE.EffectComposer(renderer, renderTarget)
// composer = new THREE.EffectComposer(renderer)
normal = new THREE.RenderPass(scene, camera)
outline = new THREE.RenderPass(outScene, camera)
mask = new THREE.MaskPass(maskScene, camera)
// mask.inverse = true
clearMask = new THREE.ClearMaskPass
copyPass = new THREE.ShaderPass(THREE.CopyShader)
copyPass.renderToScreen = true
composer.addPass(normal)
composer.addPass(outline)
composer.addPass(mask)
composer.addPass(clearMask)
composer.addPass(copyPass)
Also I have no idea whether to use render target or renderer for the source of the composer. :( Should I have the first pass in the composer at all? Why do I need the copy pass? So many questions, I know. But there are just not enough resources to learn from, I've been googling for days.
Thanks for any advice!
Here's a js fiddle with working solution. You're welcome. :)
http://jsfiddle.net/Eskel/g593q/6/
Update with only two render passes (credit to WestLangley):
http://jsfiddle.net/Eskel/g593q/9/
The pieces missing were these:
composer.renderTarget1.stencilBuffer = true
composer.renderTarget2.stencilBuffer = true
outline.clear = false
Now I think I've found a bit simpler solution, from the THREEx library. It pre-scales the mesh so you dont need a realtime shader for it.
http://jeromeetienne.github.io/threex.geometricglow/examples/geometricglowmesh.html

Kineticjs - Rotate image clockwise 90 degrees

I am really liking kineticjs lib but I am struggling to find any resource/examples on rotating a kinetic image object.
I have seen many on rotating shapes but all seem, from looking, like they rotate the whole canvas and not the image object.
Is this true and If not, could anyone point out any documentation please?
regards
p.s.
for those who want code, It's just the standard image deleration:
mainImage = new Kinetic.Image({
image: imageObj,
x: 0,
y: 0,
draggable: true,
startScale: 1
});
and have tried:
function rotateLeft(){
$('#rotate-left').bind( $bind, function(){
mainImage.rotate(90);
layer.draw();
});
}
which makes the image disappear...
regards
Kinetic.Image inherits rotateDeg and rotate -methods from Kinetic.Node -class. rotateDeg is the one you are looking for. rotate is the same, but uses radians instead of degrees.
These will rotate relative to the current rotation.
There are also setRotate and setRotateDeg -methods, which will set the rotation to some absolute value.
So try this:
mainImage.rotateDeg(90);
I hope this helps!

Zoom toward mouse (eg. Google maps)

I've written a home-brew view_port class for a 2D strategy game. The panning (with arrow keys) and zooming (with mouse wheel) work fine, but I'd like the view to also home towards wherever the cursor is placed, as in Google Maps or Supreme Commander
I'll spare you the specifics of how the zoom is implemented and even what language I'm using: this is all irrelevant. What's important is the zoom function, which modifies the rectangle structure (x,y,w,h) that represents the view. So far the code looks like this:
void zoom(float delta, float mouse_x, float mouse_y)
{
zoom += delta;
view.w = window.w/zoom;
view.h = window.h/zoom;
// view.x = ???
// view.y = ???
}
Before somebody suggests it, the following will not work:
view.x = mouse_x - view.w/2;
view.y = mouse_y - view.h/2;
This picture illustrates why, as I attempt to zoom towards the smiley face:
As you can see when the object underneath the mouse is placed in the centre of the screen it stops being under the mouse, so we stop zooming towards it!
If you've got a head for maths (you'll need one) any help on this would be most appreciated!
I managed to figure out the solution, thanks to a lot of head-scratching a lot of little picture: I'll post the algorithm here in case anybody else needs it.
Vect2f mouse_true(mouse_position.x/zoom + view.x, mouse_position.y/zoom + view.y);
Vect2f mouse_relative(window_size.x/mouse_pos.x, window_size.y/mouse_pos.y);
view.x = mouse_true.x - view.w/mouse_relative.x;
view.y = mouse_true.y - view.h/mouse_relative.y;
This ensures that objects placed under the mouse stay under the mouse. You can check out the code over on github, and I also made a showcase demo for youtube.
In my concept there is a camera and a screen.
The camera is the moving part. The screen is the scalable part.
I made an example script including a live demo.
The problem is reduced to only one dimension in order to keep it simple.
https://www.khanacademy.org/cs/cam-positioning/4772921545326592
var a = (mouse.x + camera.x) / zoom;
// now increase the zoom e.g.: like that:
zoom = zoom + 1;
var newPosition = a * zoom - mouse.x;
camera.setX(newPosition);
screen.setWidth(originalWidth * zoom);
For a 2D example you can simply add the same code for the height and y positions.

On OSX, how do I gradient fill a path stroke?

Using the plethora of drawing functions in Cocoa or Quartz it's rather easy to draw paths, and fill them using a gradient. I can't seem to find an acceptable way however, to 'stroke'-draw a path with a line width of a few pixels and fill this stroke using a gradient. How is this done?
Edit: Apparently the question wasn't clear enough. Thanks for the responses so far, but I already figured that out. What I want to do is this:
(source: emle.nl)
The left square is NSGradient drawn in a path followed by a path stroke message. The right is what I want to do; I want to fill the stroke using the gradient.
If you convert the NSBezierPath to a CGPath, you can use the CGContextReplacePathWithStrokedPath() method to retrieve a path that is the outline of the stroked path. Graham Cox's excellent GCDrawKit has a -strokedPath category method on NSBezierPath that will do this for you without needing to drop down to Core Graphics.
Once you have the outlined path, you can fill that path with an NSGradient.
I can't seem to find an acceptable way however, to 'stroke'-draw a path with a line width of a few pixels and fill this stroke using a gradient. How is this done?
[Original answer replaced with the following]
Ah, I see. You want to apply the gradient to the stroke.
To do that, you use a blend mode. I explained how to do this in an answer on another question. Here's the list of steps, adapted to your goal:
Begin a transparency layer.
Stroke the path with any non-transparent color.
Set the blend mode to source in.
Draw the gradient.
End the transparency layer.
According to Peter Hosey's answer I've managed to do a simple gradient curve, which looks like this:
I've done this in drawRect(_:) method of UIView class by writing the code below:
override func drawRect(rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
CGContextBeginTransparencyLayer (context, nil)
let path = createCurvePath()
UIColor.blueColor().setStroke()
path.stroke()
CGContextSetBlendMode(context, .SourceIn)
let colors = [UIColor.blueColor().CGColor, UIColor.redColor().CGColor]
let colorSpace = CGColorSpaceCreateDeviceRGB()
let colorLocations :[CGFloat] = [0.0, 1.0]
let gradient = CGGradientCreateWithColors(colorSpace, colors, colorLocations)
let startPoint = CGPoint(x: 0.0, y: rect.size.height / 2)
let endPoint = CGPoint(x: rect.size.width, y: rect.size.height / 2)
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, CGGradientDrawingOptions.DrawsBeforeStartLocation)
CGContextEndTransparencyLayer(context)
}
Function createCurvePath() returns an UIBezierPath object. I've also set path.lineWidth to 5 points.

Trouble with OpenLayers Styles

So, tired of always seeing the bright orange default regular polygons, I'm trying to learn to style OpenLayers.
I've had some success with:
var layer_style = OpenLayers.Util.extend({},OpenLayers.Feature.Vector.style['default']);
layer_style.fillColor = "#000000";
layer_style.strokeColor = "#000000";
polygonLayer = new OpenLayers.Layer.Vector("PolygonLayer");
polygonLayer.style = layer_style;
But sine I am drawing my polygons with DrawFeature, my style only takes effect once I've finished drawing, and seeing it snap from bright orange to grey is sort of disconcerting. So, I learned about temporary styles, and tried:
var layer_style = new OpenLayers.Style({"default": {fillColor: "#000000"}, "temporary": {fillColor: "#000000"}})
polygonLayer = new OpenLayers.Layer.Vector("PolygonLayer");
polygonLayer.style = layer_style;
This got me a still orange square--until I stopped drawing, when it snapped into completely opaque black. I figured maybe I had to explicitly set the fillOpacity...no dice. Even when I changed both fill colors to be pink and blue, respectively, I still saw only orange and opaque black.
I've tried messing with StyleMaps, since I read that if you only add one style to a style map, it uses the default one for everything, including the temporary style.
var layer_style = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']);
var style_map = new OpenLayers.StyleMap(layer_style);
polygonLayer = new OpenLayers.Layer.Vector("PolygonLayer");
polygonLayer.style = style_map;
That got me the black opaque square, too. (Even though that layer style works when not given to a map). Passing the map to the layer itself like so:
polygonLayer = new OpenLayers.Layer.Vector("PolygonLayer", style_map);
Didn't get me anything at all. Orange all the way, even after drawn.
polygonLayer = new OpenLayers.Layer.Vector("PolygonLayer", {styleMap: style_map});
Is a lot more succesful: Orange while drawing, translucent black with black outline when drawn. Just like when I didn't use a map. Problem is, still no temporary...
So, I tried initializing my map this way:
var style_map = new OpenLayers.StyleMap({"default": layer_style, "temporary": layer_style});
No opaque square, but no dice for the temporary, either... Still orange snapping to black transparent. Even if I make a new Style (layer_style2), and set temporary to that, still no luck. And no luck with setting "select" style, either.
What am I doing wrong? Temporary IS for styling things that are currently being sketched, correct? Is there some other way specific to the drawFeature Controller?
Edit: setting extendDefault to be true doesn't seem to help, either...
var style_map = new OpenLayers.StyleMap({"default": layer_style, "temporary": layer_style}, {"extendDefault": "true"});
I've found two solutions for this problem. In both solution, you have to change some parameters of DrawFeature to get the functionality you wish.
1.Change handler style of the DrawFeature. Function drawFeature in OpenLayers.Handler.Polygon uses parameter style of the handler for the feature. So you have to change this style.
When creating Feature use:
var drawPolygon = new OpenLayers.Control.DrawFeature(polygonLayer, OpenLayers.Handler.Polygon, {handlerOptions:{style:myStyle}});
Later, you can change it by:
drawPolygon.handler.style = myStyle;
2.Change create callback of the DrawFeature. Change style of the newly created temporary feature in create callback.
var drawPolygon = new OpenLayers.Control.DrawFeature(polygonLayer, OpenLayers.Handler.Polygon, {
callbacks:{create: function(vertex, feature) {
feature.style = myStyle;
this.layer.events.triggerEvent("sketchstarted", {vertex:vertex,feature:feature})
}}});
Similarly, you can change the callback later.
If you want all vectors to be of a constant style, but not the boring orange then try this:
vecLayer = new OpenLayers.Layer.Vector(
"Route Layer", //layer name
{styleMap: new OpenLayers.StyleMap({
pointRadius: "6",
fillColor: "#666666"
}),
renderers:renderer}
);
You have loads of properties you can mess about with, have a look at these pages:
dev.openlayers (check the Constants section)
docs.openlayers (more useful info)

Resources