Ok, I'm trying to put the javascript in a separate source file. This is a newbie question, but I'm getting an 'undefined' error on layer.add(imageObj).
I'm guessing it's because of window.onLoad, but I didn't find an immediate answer.
<html>
<head>
<link rel="stylesheet" type="text/css" media="screen" href="index.css">
<script type="text/javascript" src="js/kinetic-v5.1.0.min.js"></script>
<script type="text/javascript" src="js/game.js" defer="defer"></script>
</head>
<body>
<div id="board"></div>
</body>
The javascript:
window.onload = function(){
var stage = new Kinetic.Stage({
container: 'board'
});
var layer = new Kinetic.Layer();
var imageObj = new Image();
imageObj.onload = function() {
var image = new Kinetic.Image({
x: 0,
y: 0,
image: imageObj,
width: 100,
height: 100
});
};
imageObj.src = 'resources/map.jpg';
layer.add(imageObj);
stage.add(layer);
};
You need to add into layer Kinetic.Image instance (image in your source) not imageObj. You can do this in onload function. See: http://jsbin.com/buroyi/2/edit
Related
Using latest leaflet library, I generated a plot in python from a GraDs file and supposedly I have the correct corners or bounds, but when overlaying in leaflet does not fit.
here is the simple code
<!DOCTYPE html>
<html>
<head>
<title>Image Overlay Example</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"></script>
<style type="text/css">
html,
body,
#map {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
}
</style>
</head>
<body>
<div id = "map"></div>
<script>
// Creating map options
var mapOptions = {
center: [14, -85],
zoom: 5
}
var map = new L.map('map', mapOptions); // Creating a map object
// Creating a Layer object
// var layer = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
// map.addLayer(layer); // Adding layer to the map
var esriImages = new L.TileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}');
var esriLabels = new L.TileLayer('https://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}');
var esri = L.layerGroup([esriImages, esriLabels]);
//default basemap
map.addLayer(esri);
// Creating Image overlay
var imageUrl = 'https://i.imgur.com/KNTRLHR.png';
var imageBounds = [[30,-115], [6,-59.03836]];
var overlay = L.imageOverlay(imageUrl, imageBounds,{ opacity:.7});
overlay.addTo(map);
map.on('click', function(e) {
// var popup = L.popup()
// .setLatLng(e.latlng)
// .setContent('<p>Hello, world!</p>')
// .openOn(map);
console.log ('click en ',e.latlng);
});
</script>
</body>
</html>
The representation of the image is like this as per NOAA site but is poor quality and also if i overlay does not fit.
What is the issue or how to fix it.
Thanks for any help
Edited: 2020.10.17 04Z
how to add Info Bubbles to HERE maps. I follow the steps on the HERE api page, but the info bubble doesn't popup.
According to the Here api, here is the way to add popup.
https://developer.here.com/documentation/maps/topics/map-controls.html
var bubble = new H.ui.InfoBubble({ lng: 13.4, lat: 52.51 }, {
content: '<b>Hello World!</b>'
});
// Add info bubble to the UI:
ui.addBubble(bubble);
I follow the code and the map loads correctly with the right coordinates, but I don't see any info bubble on the map.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0,
width=device-width" />
<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.0/mapsjs-ui.css?dp-version=1533195059" />
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-core.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-service.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-ui.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-mapevents.js"></script>
<script src="http://js.api.here.com/v3/3.0/mapsjs-core.js" type="text/javascript" charset="utf-8"></script>
<script src="http://js.api.here.com/v3/3.0/mapsjs-service.js" type="text/javascript" charset="utf-8"></script>
<script src="http://js.api.here.com/v3/3.0/mapsjs-ui.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" type="text/css" href="http://js.api.here.com/v3/3.0/mapsjs-ui.css" />
</head>
<body>
<div id="map" style="width: 100%; height: 400px; background: grey" />
<script type="text/javascript" charset="utf-8">
//Initialize the Platform object:
var platform = new H.service.Platform({
'app_id': '{YOUR_APP_ID} ',
'app_code': '{YOUR_APP_CODE} '
useHTTPS: true
});
var pixelRatio = window.devicePixelRatio || 1;
var defaultLayers = platform.createDefaultLayers({
tileSize: pixelRatio === 1 ? 256 : 512,
ppi: pixelRatio === 1 ? undefined : 320
});
//Step 2: initialize a map - not specificing a location will give a whole world view.
var map = new H.Map(document.getElementById('map'),
defaultLayers.normal.map, {pixelRatio: pixelRatio});
//Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// Get the default map types from the Platform object:
map.setCenter({lng: 13.4, lat: 52.51});
map.setZoom(10);
// Instantiate the map:
// Create the default UI:
var ui = H.ui.UI.createDefault(map, defaultLayers, 'de-DE');
var mapSettings = ui.getControl('mapsettings');
var zoom = ui.getControl('zoom');
var scalebar = ui.getControl('scalebar');
var panorama = ui.getControl('panorama');
panorama.setAlignment('top-left');
mapSettings.setAlignment('top-left');
zoom.setAlignment('top-left');
scalebar.setAlignment('top-left');
var bubble = new H.ui.InfoBubble({ lng: 13.4, lat: 52.51 }, {
content: '<b>Hello World!</b>'
});
// Add info bubble to the UI:
ui.addBubble(bubble);
</script>
</body>
</html>
I'm Richard and I'm a developer evangelist for HERE.
Your code breaks in this line:
panorama.setAlignment('top-left');
This line indicates that you want to move the StreetLevel UI element to the top-left of the map. However this element does not exist, as you've forgotten to import the mapsjs-pano.js library. This library is required for StreetLevel functionality. Add the following line to your and your code should work.
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-pano.js"></script>
Also note that you are missing a comma after setting your app_code and that your importing some libraries twice. You may have to fix these issues as well for your code to work. Here is a cleaned up version of your code that does what you want to do.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.0/mapsjs-ui.css" />
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-core.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-service.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-ui.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-mapevents.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-pano.js"></script>
</head>
<body>
<div id="map" style="width: 100%; height: 400px; background: grey" />
<script type="text/javascript" charset="UTF-8" >
function createInfoBubble(map) {
// Create info bubble
var bubble = new H.ui.InfoBubble({ lng: 13.4, lat: 52.51 }, {
content: '<b>Hello World!</b>'
});
// Add info bubble to the UI:
ui.addBubble(bubble);
}
// Step 1: initialize the platform
var platform = new H.service.Platform({
app_id: '{YOUR_APP_ID}',
app_code: '{YOUR_APP_CODE}',
useHTTPS: true
});
var pixelRatio = window.devicePixelRatio || 1;
var defaultLayers = platform.createDefaultLayers({
tileSize: pixelRatio === 1 ? 256 : 512,
ppi: pixelRatio === 1 ? undefined : 320
});
// Step 2: initialize a map
var map = new H.Map(document.getElementById('map'),
defaultLayers.normal.map, {pixelRatio: pixelRatio});
// Step 3: make the map interactive
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// Step 4: create the default UI components
var ui = H.ui.UI.createDefault(map, defaultLayers);
// Move UI elements to the top left of the map
var mapSettings = ui.getControl('mapsettings');
var zoom = ui.getControl('zoom');
var scalebar = ui.getControl('scalebar');
var panorama = ui.getControl('panorama');
panorama.setAlignment('top-right');
mapSettings.setAlignment('top-left');
zoom.setAlignment('top-left');
scalebar.setAlignment('top-left');
// Move map to Berlin
map.setCenter({lat:52.5159, lng:13.3777});
map.setZoom(14);
createInfoBubble(map);
</script>
</body>
</html>
In a canvas painting application I want to add feature to create overlay over the whole canvas and then when I make a particular rectangle on the canvas the overlay should get removed from that region ,exactly like one on https://onpaste.com/ (select focus tool) . What I have thought is that if a rectangle is made on the canvas , then I can crop the current image and then paste the image on the canvas again over the overlay at the place which was selected . I am not sure , how to crop the image before pasting it on the canvas , I tried to use method setFillPaternImage of Kinetic.Image object ,but here I want to feed Kinetic.Image object instead of javascript image object because on Kinetic.Image object I can use setAttrs method .
Please tell how I can crop and add the image or if there is a better way to achieve the same . Link to fiddle -> http://jsfiddle.net/hearsid/9a2Hn/
<html>
<head>
<style>
</style>
</head>
<body>
<div id="container"></div>
<button id="button">this</button>
<script src="js/jquery.js"></script>
<script src="js/kinetic.js"></script>
<script>
var stage = new Kinetic.Stage({
container:'container',
width:500,
height:300
});
var layer=new Kinetic.Layer();
var img = new Image();
img.onload = function() {
imgObj = new Kinetic.Image({
x:0,y:0,width:400,height:300,image:img
});
layer.add(imgObj);
var circle = new Kinetic.Circle({
x:30,y:30,radius:30,fill:'red'
});
layer.add(circle);
var rect = new Kinetic.Rect({
x:0,y:0,width:300,height:500,fill:'gray',opacity:0.5
});
layer.add(rect);
stage.add(layer);
}
img.src="some.jpg";
$("#button").click(function() {
rect2 = new Kinetic.Rect({
x:200,y:30,width:100,height:100
});
/*
Careful with the commented area , here I wanted to crop the image before using FillPaternImage
var img2 = new Image();
img2.onload = function() {
imgObj2 = new Kinetic.Image({
image: img2 ,
x:300
});
imgObj2 = imgObj.clone();
imgObj2.setAttrs({image :img2 ,x:100 , y:0 });
*/
img2 = img ;
rect2.setFillPatternImage(img2);
layer.add(rect2);
layer.draw();
});
</script>
</body>
</html>
Your "clipped reveal" can be accomplished like this:
A Demo: http://jsfiddle.net/m1erickson/qXHAJ/
In a bottom layer:
Add an image.
Add a semi-transparent Rect to "frost" the bottom image.
In an overlay layer:
Add a group to a top overlay layer.
Set the clip property of the group to the area you want revealed.
In the group:
Add the image again (this second image will be "revealed" only in the groups clip area).
Add a draggable Rect to act as your "view"
(the Rect will have its X/Y/width/height set to the groups clip area.
When the user drags the Rect:
Change the group's clipping area to the Rect's X/Y.
The Rect will act as a draggable indicator of where the reveal should be.
The result is that the image is "frosted" everywhere except the draggable Rect.
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/qXHAJ/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.2.min.js"></script>
<style>
body{padding:20px;}
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:300px;
height:300px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 300,
height: 300
});
var layer = new Kinetic.Layer();
var frostlayer=new Kinetic.Layer();
stage.add(layer);
stage.add(frostlayer);
var view;
var img=new Image();
img.onload=function(){
start();
}
//img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/KoolAidMan.png";
img.src="KoolAidMan.png";
function start(){
var image=new Kinetic.Image({
image:img,
x:0,
y:0,
width:300,
height:300
});
layer.add(image);
var frost=new Kinetic.Rect({
x:0,
y:0,
width:300,
height:300,
fill:"white",
opacity:0.70
});
layer.add(frost);
var viewport=new Kinetic.Group({
x:0,
y:0,
width:300,
height:300,
clip:[30,30,100,100]
});
frostlayer.add(viewport);
unfrosted=new Kinetic.Image({
image:img,
x:0,
y:0,
width:300,
height:300
});
viewport.add(unfrosted);
view=new Kinetic.Rect({
x:30,
y:30,
width:100,
height:100,
strokeWidth:3,
stroke:"purple",
draggable:true
});
view.on("dragmove",function(){
viewport.setClip(this.getX(),this.getY(),100,100);
});
viewport.add(view);
layer.draw();
frostlayer.draw();
}
}); // end $(function(){});
</script>
</head>
<body>
<h3>Drag the unfrosted Rect</h3>
<div id="container"></div>
</body>
</html>
I have to be missing something simple. I have gone fairly line-by-line, but it just doesn't seem to work. I can't get the image to load.
var imageToCanvas = function(){
var stage = new Kinetic.Stage("imgarea", 250, 256);
var layer = new Kinetic.Layer();
var imageobj = new Image();
imageobj.onload = function(){
var img = new Kinetic.Image({
x: 10,
y: 10,
image: imageobj,
});
layer.add(img);
stage.add(layer);
};
imageobj.src = "/static/img/unit-test-image.png";
console.log(imageobj);
};
$(document).ready( function(){
imageToCanvas();
});
<canvas id="imgarea" width="250px" height="256px"></canvas>
the same code seems to work in another canvas app that I used Kinetc.js with. I just can't seem to figure out why this one isn't working.
The code also looks fairly similar to the tutorial as well: http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-image-tutorial/
It looks like you're not defining the stage properly.. When I tried your code above I got an error about the container not being defined.. Try this instead..
var stage = new Kinetic.Stage({
container: "imgarea",
width: 250,
height: 256
});
I get this error when I call map.AddPopup() in OpenLayers:
Unable to get value of the property 'Left'; object is null or undefined
http://www.openlayers.org/api/OpenLayers.js
The same error occurs in both Chrome and IE. The map works fine when I comment out that line, and the markers work fine as well. Later, icon0 and lonLat0 will be several items in a loop, but I'll handle that. The end result should be a text box of some kind that would display on the marker.
The marker at lonLat0 displays, so it doesn't seem like a problem with the lonLat object.
Yes, I will end up displaying many markers with text on them all at once. I know, it seems silly, but that's the requirement.
Why does addPopup give me this error?
<html><body>
<div id='mapdiv'></div> <script src='http://www.openlayers.org/api/OpenLayers.js'></script>
<script>
map = new OpenLayers.Map('mapdiv');
map.addLayer(new OpenLayers.Layer.OSM());
var lonLat = new OpenLayers.LonLat(-104.73,38.92).transform(new OpenLayers.Projection('EPSG:4326'), map.getProjectionObject() );
var markers = new OpenLayers.Layer.Markers( 'Markers' );
map.addLayer(markers);
markers.addMarker(new OpenLayers.Marker(lonLat));
function onPopupClose(evt) {selectControl.unselect(this.feature); }
var icon0 = new OpenLayers.Icon("pinMS.png", new OpenLayers.Size(32,32), new OpenLayers.Pixel(-16,-32));
var lonLat0 = new OpenLayers.LonLat(-104.73,38.92).transform(new OpenLayers.Projection('EPSG:4326'), map.getProjectionObject());
markers.addMarker(new OpenLayers.Marker(lonLat0, icon0.clone()));
// Error throws here
map.addPopup(new OpenLayers.Popup.FramedCloud("featurePopup", lonLat0, new OpenLayers.Size(10, 10), "<h2>Title</h2>description", null, true, onPopupClose));
map.setCenter (lonLat, 1);
</script></body></html>
I was able to reproduce your error and fix it. That demo code is really bad. I would start with a working example and modify it to fit your needs.
For example you need to call your javascript on <body onload="init()"> or else i'm surprised it even renders for you.
Anyway, All i did was replaced the map = new OpenLayers.Map('mapdiv'); for this:
map = new OpenLayers.Map({
div: "mapdiv",
center: new OpenLayers.LonLat(0, 0)
});
But here's the complete code incase you want to improve the structure of your file.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>Open Popup on Layer.Vector</title>
<link rel="stylesheet" href="http://openlayers.org/dev/theme/default/style.css" type="text/css">
<link rel="stylesheet" href="http://openlayers.org/dev/examples/style.css" type="text/css">
<script src="http://www.openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript">
function init() {
map = new OpenLayers.Map({
div: "mapdiv",
center: new OpenLayers.LonLat(0, 0)
});
map.addLayer(new OpenLayers.Layer.OSM());
var lonLat = new OpenLayers.LonLat(-104.73, 38.92).transform(new OpenLayers.Projection('EPSG:4326'), map.getProjectionObject());
var markers = new OpenLayers.Layer.Markers('Markers');
map.addLayer(markers);
markers.addMarker(new OpenLayers.Marker(lonLat));
function onPopupClose(evt) { selectControl.unselect(this.feature); }
var icon0 = new OpenLayers.Icon("pinMS.png", new OpenLayers.Size(32, 32), new OpenLayers.Pixel(-16, -32));
var lonLat0 = new OpenLayers.LonLat(-104.73, 38.92).transform(new OpenLayers.Projection('EPSG:4326'), map.getProjectionObject());
markers.addMarker(new OpenLayers.Marker(lonLat0, icon0.clone()));
// Error throws here
map.addPopup(new OpenLayers.Popup.FramedCloud("featurePopup", lonLat0, new OpenLayers.Size(10, 10), "<h2>Title</h2>description", null, true, onPopupClose));
map.setCenter(lonLat, 1);
}
</script>
</head>
<body onload="init()">
<div id="mapdiv" class="smallmap"></div>
</body>
</html>