I've got the following task:
Attaching a ground layer (provided as an jpg-image) over an plant.
I thought that I've found an solution.
Live-Demo on CodePen: http://codepen.io/mizech/full/dXBoRq/
But it doesn't work as expected. If one zooms into or out the map the image doesn't scale bigger or smaller.
Moreover: The image is supposed to rotate with the map. That doesn't work neither.
Therefore my question:
What do I have to do to make it work the way it should (image scales when zoomed-in and -out, images follows when rotating) ?
Or should I choose a complete different approach?
Then any hints concerning code-examples are very appreciated.
Here my code so far:
var layer = new ol.layer.Tile({
source: new ol.source.OSM()
});
var control = new ol.control.FullScreen();
var center = ol.proj.transform([6.9690055, 49.2175355], 'EPSG:4326', 'EPSG:3857');
var overlay = new ol.Overlay({
position: center,
element: document.getElementById('plant')
});
var view = new ol.View({
center: center,
zoom: 17
});
var map = new ol.Map({
target: 'map',
layers: [layer],
controls: [control],
overlays: [overlay],
view: view
});
#plant {
width: 1300px;
height: 400px;
border: 1px solid black;
transform: rotate(16.5deg);
}
#plant img {
opacity: 0.6;
}
<div id="map" class="map">
<div id="plant"><img src="http://placehold.it/1300x400" alt="bild" /></div>
</div>
You can try to use another option to accomplish the preferred effect, there are two options I can think of:
1. Use ol.layer.Image(), code sample:
var extent = ol.proj.transformExtent([7.2, 49.3, 6.5, 49.1],
'EPSG:4326', 'EPSG:3857');
new ol.layer.Image({
opacity: 0.6,
source: new ol.source.ImageStatic({
url: 'http://placehold.it/1300x400',
imageExtent: extent
})
})
The extent is just a rough estimation yet.
2. Use a vector Layer to style an Icon using your image, already explained here:
https://gis.stackexchange.com/questions/130603/how-to-resize-a-feature-and-prevent-it-from-scaling-when-zooming-in-openlayers-3/
To rotate it along with the map use rotateWithView: true in your icon style, like this:
var iconStyle = new ol.style.Icon({
src: 'http://placehold.it/1300x400',
rotateWithView: true,
opacity: 0.6
});
I'm using Google maps, with Drawning Manager
var latlng = new google.maps.LatLng(41.7318187, 44.8627138);
var mapOptions = {
zoom: 8,
center: latlng,
disableDoubleClickZoom: true
}
bounds = new google.maps.LatLngBounds();
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
//Define a symbol using SVG path notation, with an opacity of 1.
var lineSymbol = {
path: 'M 0,-1 0,1',
strokeOpacity: 1,
scale: 4
};
drawingManager = new google.maps.drawing.DrawingManager({
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
google.maps.drawing.OverlayType.MARKER,
google.maps.drawing.OverlayType.POLYLINE
]
},
markerOptions: {
icon: $imgFolderFullPath + '/' + $('#TourObjectType').val() + '.png',
draggable: true
},
polylineOptions: {
strokeColor: $("#LineType").val()
}
});
drawingManager.setMap(map);
The problem is when map renders some element that has visibility hidden and z-index 107 which overflows half of the map and i cant insert, edit, move, poly lines and markers in that part
DOM structure of the problematic part looks like this :
<div style="transform: translateZ(0px); position: absolute; left: 0px; top: 0px; z-index: 107; width: 100%;">
<div style="cursor: default; width: 53px; height: 191px; visibility: hidden;">...</div>
</div>
and also when i comment visibility hidden in the code snippet above, there is something like white comment box with star shown on the map
i what to know what causes the problem
This happens when the signed_in=true is used.
Bug report: https://code.google.com/p/gmaps-api-issues/issues/detail?id=7788
I added a link to this post in the bug report for reference. Hope Google will fix that very soon.
I can not tell you why this occurs, only that for me it also does in the example that is provided in the documentation. You can't draw in that area, but you can zoom into it, etc.
https://developers.google.com/maps/documentation/javascript/examples/drawing-tools.
EDIT: It seems to be a bug with the signed-in mode, as #MrUpsidown pointed out
Suppose you have a 2d array like the ones often used to organise tile maps, 1 represents solid tiles.
var map = [
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,1,1,1,1,1,1,0,0,0,0,0],
[0,0,0,0,1,1,1,1,1,1,0,0,0,0,0],
[0,0,0,0,1,1,1,1,1,1,0,0,0,0,0],
[0,0,0,0,1,1,1,1,1,1,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,1,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,1,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
];
Instead of square tiles, I want to convert this shape in to points of a polygon. Each 1 in the array would have a set width and height like a tile map, but I only want the corner points necessary to recreate the shape as a solid polygon. I also want diagonal slopes instead of a step-like effect when the 1's are diagonal like in the array. I've played around and searched for an answer but I can't figure out the best way to do this, any ideas?
Thanks.
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.0.1.min.js"></script>
<script defer="defer">
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var poly = new Kinetic.Line({
points: [73, 192, 73, 160, 340, 23, 500, 109, 499, 139, 342, 93],
fill: '#00D2FF',
stroke: 'black',
strokeWidth: 5,
closed: true
});
// add the shape to the layer
layer.add(poly);
// add the layer to the stage
stage.add(layer);
</script>
</body>
</html>
You could put those points you want in the points array ,and use kinetic js for ur project.
Link : http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-polygon-tutorial/
I am attempting to use kinetic.js with an existing canvas. The problem is that the kinetic.js API requires that you specify the id of the container element and then kinetic.js creates a Kinetic.Stage (which creates and uses its own canvas).
For instance:
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var rect = new Kinetic.Rect({
x: 239,
y: 75,
width: 100,
height: 50,
fill: 'green',
stroke: 'black',
strokeWidth: 4
});
// add the shape to the layer
layer.add(rect);
// add the layer to the stage
stage.add(layer);
</script>
I want to be able to use an existing canvas element with kinetic.js instead of it creating its own. Is this possible?
A similar question has been asked before, however it doesn't seem to provide a correct answer.
Any ideas? Thanks!
An html canvas is just a bunch of pixels.
You can convert those pixels into an image and then use that image as the source for a Kinetic.Image.
// create an image from the existing canvas
var canvas2Image=new Image();
canvas2Image.onload=function(){
// create a Kinetic.Image using that image
var kImage=new Kinetic.Image({
x:0,
y:0,
width:canvas2Image.width,
height:canvas2Image.height,
image:canvas2Image
});
}
canvas2Image.src=canvas.toDataURL();
I want to draw multiple figures on a canvas on different button clicks.
HTML
<body>
<div id="container">
</div>
<div id="option">
<button value="rect" onclick="rect();">rect</button>
<button value="circle" onclick="circle();">circle</button>
</div>
</body>
Javascript:
var stage = new Kinetic.Stage({
container: 'container',
width: 500,
height: 500
});
var layer = new Kinetic.Layer();
function rect(){
var redLine = new Kinetic.Line({
points: [100, 5, 100, 300, 450,300],
stroke: 'black',
strokeWidth: 3,
lineCap: 'square',
lineJoin: 'mitter'
});
// add the shape to the layer
layer.add(redLine);
// add the layer to the stage
stage.add(layer);
}
function circle(){
var wedge = new Kinetic.Wedge({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: 70,
angleDeg: 60,
fill: 'red',
stroke: 'black',
strokeWidth: 4,
rotationDeg: -120
});
// add the shape to the layer
layer.add(wedge);
// add the layer to the stage
stage.add(layer);
}
But it gives error as layer and stage are not defined. How do I solve it ?
The reasons that stage and layer would not be defined are that either they are outside of scope, or your code is breaking before they are instantiated in the first place.
First, make sure that your stage and layer are outside of any functions; global scope.
Second, your functions 'circle()' and 'rect()' are being called with the button click, which I suspect is breaking your code. You want to remove this onclick handler from inline:
<button value="circle" onclick="circle();">circle</button>
and assign onclick using javascript, after you have created your stage. You can assign handlers easily using jQuery. So your code should look something like:
HTML
<button value="rect" id='rect'>rect</button> //assign an id to your button
JS
var stage = new Kinetic.Stage({
container: 'container',
width: 500,
height: 500
});
var layer = new Kinetic.Layer();
$('#yourButtonId').click(function(){ // button id here would be '#rect' if you use the id above
rect();
});