How to add in layer a upload image - konvajs

I would like to know how to add in image.src a upload image.
I know that with convas i do image.src = event.target.result but it don't work.
ts
onFileSelected(event){
var layer = new Konva.Layer();
var stage: Konva.Stage;
var box: Konva.Rect;
var image = new Image();
image.onload = function()
{
var img = new Konva.Image({ image: image });
stage = new Konva.Stage({
container: 'container',
width: image.width,
height: image.height
});
layer.add(img);
stage.add(layer);
}
image.src = '' /* Image to put event.target.result */;
}
html
<input type="file" (change)="onFileSelected($event)" accept="image/*"> <br><br>
<div id="container" style="border: 2px solid red;"></div>

Your sample code looks basically functional. Open your browser dev tools (F12) and see if here are any messages or errors. I suspect cross-origin issues - search SO or Google for cross-origin for resolutions.
I can't give you a working angular example, nor even a working plain JS example that uses a file select because my Chrome browser insists I cannot load local files to this website. Anyway, the snippet below uses the change event of a select box in the same way that you would for a file select. It is based around the intention of your code.
$('#daFile').on('change', function(e){
var layer = new Konva.Layer();
var stage = new Konva.Stage({container: 'container'})
var image = new Image();
var path = $(this).val(); // jquery way of retreiving new path
image.onload = function()
{
var img = new Konva.Image({ image: image });
stage.size({width: image.width, height: image.height});
layer.add(img);
stage.add(layer);
stage.draw();
}
image.src = path;
})
setTimeout( function(){$('#daFile')
.val('https://i.stack.imgur.com/kSo4z.jpg')
.trigger('change');
}, 500);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/konvajs/konva/1.6.5/konva.min.js"></script>
<div>
Select a file
<select id='daFile'>
<option value='https://i.stack.imgur.com/Awa0C.png'>Nosey dog</option>
<option value='https://i.stack.imgur.com/kSo4z.jpg'>Snow dog</option>
</select>
</div>
<div id='container' style="display: inline-block; width: 300px, height: 200px; background-color: silver; overflow: hidden; position: relative;"></div>
<div id='img'></div>

Related

net mvc: Signaturepad toDataURL generates no line

Using Net MVC and Signaturepad, I´m taking a signature from users and generating a PNG by using this:
<canvas id="#("canvas" + flat.ID)" width="400" height="200" style="background-color: lightgrey;"></canvas>
<script type="text/javascript">
var canvas = document.querySelector("#("#canvas" + flat.ID)");
var signaturePad = new SignaturePad(canvas, {
backgroundColor: 'rgba(211,211,211, 1)',
penColor: 'rgb(0, 0, 0)'
});
</script>
I´m storing the signature in a database by using
<button class="btn btn-shadow btn-block btn-primary" onclick="saveSignature('#Url.Action("SaveSignature", "Home", new { Area = "AssemblyOrders" })', signaturePad.toDataURL(), '#flat.ID', '#ViewBag.AssemblyOrderID')">Speichern</button>
This does nothing but setting the value in database.
In database I find the generated string:
data:image/png;base64,iVBORw...
I´m loading the view and if the viewmodel has that string I´m displaying it as an image:
<img src="#flat.Signature" style="width: 100%; height: 200px;"/>
This is only showing the lightgrey background from signaturepad but not the handwritten signature.
Where is the problem?
edit: I also tried saving it to desktop, but this png is also only lightgrey without lines.
Problem were this lines of code:
var signaturePad = new SignaturePad(canvas, {
backgroundColor: 'rgba(211,211,211, 1)',
penColor: 'rgb(0, 0, 0)'
});
Because of multiple canvas, as you can see from <canvas id="#("canvas" + flat.ID)" ..., the var signaturePad existed multiple times. Thus always the last var was used.
I solved it like this:
var pads = {};
...
pads["#("#canvas" + flat.ID)"] = new SignaturePad(canvas, {
backgroundColor: 'rgba(211,211,211, 1)',
penColor: 'rgb(0, 0, 0)'
});
and
onclick="saveSignature('#Url.Action("SaveSignature", "Home", new { Area = "AssemblyOrders" })', pads['#("#canvas" + flat.ID)'].toDataURL(), '#flat.ID', '#ViewBag.AssemblyOrderID')"

Vector tiles:GetTile WMTS ol.format.MVT() with Openalyer v5.3.0 From Geoserver

I have layers on Geoserver(2.13.0) that configure with MSSQL DataStore.I install vector tile extension for the same version. After installed, while previewing with TileLayers pbf by selection from drop down result is displaying.
http://localhost:8080/geoserver/gwc/demo/mystate:State?gridSet=EPSG:900913&format=application/x-protobuf;type=mapbox-vector
And also while a request from OpenLayers client same result is coming.
<html>
<head>
<title>Vector tiles</title>
<script src="./js/build-ol.js"></script>
<link rel="stylesheet" href="./css/ol.css">
<style>
html,
body {
font-family: sans-serif;
width: 100%;
}
.map {
height: 500px;
width: 100%;
}
</style>
</head>
<body>
<h3>Mapbox Protobuf - vector tiles</h3>
<div id="map" class="map"></div>
<script>
var gridsetName = 'EPSG:900913';
var gridNames = ['EPSG:900913:0', 'EPSG:900913:1', 'EPSG:900913:2', 'EPSG:900913:3', 'EPSG:900913:4', 'EPSG:900913:5', 'EPSG:900913:6', 'EPSG:900913:7', 'EPSG:900913:8', 'EPSG:900913:9', 'EPSG:900913:10', 'EPSG:900913:11', 'EPSG:900913:12', 'EPSG:900913:13', 'EPSG:900913:14', 'EPSG:900913:15', 'EPSG:900913:16', 'EPSG:900913:17', 'EPSG:900913:18', 'EPSG:900913:19', 'EPSG:900913:20'];
var baseUrl = 'http://localhost:8080/geoserver/gwc/service/wmts';
var style = 'StateStyle';
var format = 'application/x-protobuf;type=mapbox-vector';
var infoFormat = 'text/html';
var layerName = 'myState:State';
var projection = new ol.proj.Projection({
code: 'EPSG:900913',
units: 'm',
axisOrientation: 'neu'
});
var resolutions = [156543.03390625, 78271.516953125, 39135.7584765625, 19567.87923828125, 9783.939619140625, 4891.9698095703125, 2445.9849047851562, 1222.9924523925781, 611.4962261962891, 305.74811309814453, 152.87405654907226, 76.43702827453613, 38.218514137268066, 19.109257068634033, 9.554628534317017, 4.777314267158508, 2.388657133579254, 1.194328566789627, 0.5971642833948135, 0.29858214169740677, 0.14929107084870338];
params = {
'REQUEST': 'GetTile',
'SERVICE': 'WMTS',
'VERSION': '1.0.0',
'LAYER': layerName,
'STYLE': style,
'TILEMATRIX': gridsetName + ':{z}',
'TILEMATRIXSET': gridsetName,
'FORMAT': format,
'TILECOL': '{x}',
'TILEROW': '{y}'
};
function constructSource() {
var url = baseUrl + '?'
for (var param in params) {
url = url + param + '=' + params[param] + '&';
}
url = url.slice(0, -1);
var source = new ol.source.VectorTile({
url: url,
format: new ol.format.MVT({}),
projection: projection,
tileGrid: new ol.tilegrid.WMTS({
tileSize: [256, 256],
origin: [-2.003750834E7, 2.003750834E7],
resolutions: resolutions,
matrixIds: gridNames
}),
wrapX: true,
});
return source;
}
var layer = new ol.layer.VectorTile({
source: constructSource()
});
var view = new ol.View({
center: [0, 0],
zoom: 2,
projection: projection,
extent: [-20037508.34, -20037508.34, 20037508.34, 20037508.34]
});
var map = new ol.Map({
layers: [layer],
target: 'map',
view: view
});
map.getView().fit([-13603589.920418553, 6450443.998733485, -12407892.278044553, 7757990.05940472], map.getSize());
</script>
</body>
</html>
But in the same example, I want to apply style for the wmts using GetTile.
I tried according to documentation
Below is the code not working:
<html>
<head>
<title>Vector tiles</title>
<script src="ol.js"></script>
<link rel="stylesheet" href="ol.css">
<style>
html, body {
font-family: sans-serif;
width: 100%;
}
.map {
height: 500px;
width: 100%;
}
</style>
</head>
<body>
<h3>Mapbox Protobuf - vector tiles</h3>
<div id="map" class="map"></div>
<script>
var style_simple = new ol.style.Style({
fill: new ol.style.Fill({
color: '#ADD8E6'
}),
stroke: new ol.style.Stroke({
color: '#880000',
width: 1
})
});
function simpleStyle(feature) {
return style_simple;
}
var layer = 'myState:State';
var projection_epsg_no = '900913';
var map = new ol.Map({
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2
}),
layers: [new ol.layer.VectorTile({
style:simpleStyle,
source: new ol.source.VectorTile({
tilePixelRatio: 1, // oversampling when > 1
tileGrid: ol.tilegrid.createXYZ({maxZoom: 19}),
format: new ol.format.MVT(),
url: 'http://localhost:8080/geoserver/gwc/service/wtms/1.0.0/' + layer +
'#EPSG%3A'+projection_epsg_no+'#pbf/{z}/{x}/{-y}.pbf'
})
})]
});
</script>
</body>
</html>
Could you suggest me how I can apply my custom styles and getTile from GeoServer with ol.format.MVT()?
I think you are facing a projection problem. I also have faced the same problems. I solved it by changing views.
You can try this:
var map = new ol.Map({
target: 'map',
view: new ol.View({
center: ol.proj.fromLonLat([89.5403, 22.8456]), ## change the long/lat values based on your data
zoom: 2
}),

How to set zindex in konva.js?

I have a problem with the Zindex in konva.js. After I added everything to the layer
I am trying to assign a property to a node for each element separately. But it does not work. For example
for(let i = 0; i<=this.layer['children']; i++){
this.layer['children'][i].setZIndex(someInt);
}
How can i set zindex for all elements in layer?
zIndex in Konva is just index of the element in an array of children of the parent element. So you can't set any number to it and it can not be bigger than children.length - 1.
Working snippet illustrating the getZIndex(), setZIndex(), moveUp() and moveDown() methods of the Kovajs.Shape object. See also example at Konvajs site.
Buttons allow use to move green circle up and down the z-index list by increments of 1, then also to try to move up +10 and down -100. Resulting z-index is shown in text below circles.
// Create the stage
var stage = new Konva.Stage({
container: 'container',
width: $('#container').width(),
height: $('#container').height()
});
// create the layer
var layer = new Konva.Layer();
var data = [ {x: 60, color: 'red'}, {x: 90, color: 'limegreen'}, {x: 120, color: 'gold'}]
var circles = [];
for (var i = 0; i < data.length; i = i + 1){
// create some circles
var circle = new Konva.Circle({
x: data[i].x,
y: 60,
radius: 50,
fill: data[i].color,
stroke: 'black',
strokeWidth: 2
});
layer.add(circle);
circles.push(circle);
}
stage.add(layer);
var green = circles[1];
function sayIndex(){
$('#info').html("Green zIndex=" + circles[1].getZIndex());
}
$('#greenup').on('click', function(){
green.moveUp();
sayIndex();
layer.draw();
})
$('#greendn').on('click', function(){
green.moveDown();
sayIndex();
layer.draw();
})
$('#greenup10').on('click', function(){
var ind = circles[1].getZIndex();
green.setZIndex(ind + 10);
sayIndex();
layer.draw();
})
$('#greendn100').on('click', function(){
var ind = circles[1].getZIndex();
green.setZIndex(ind - 100);
sayIndex();
layer.draw();
})
#container
{
width: 200px;
height: 150px;
border: 1px solid #666;
float: left;
}
#buttons
{
width: 200px;
height: 150px;
border: 1px solid #666;
float: left;
}
#info
{
position: absolute;
left: 20px;
top: 135px;
}
p
{
margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdn.rawgit.com/konvajs/konva/1.6.5/konva.min.js"></script>
<div id="container"></div>
<div id="buttons">
<p><button id='greenup'>Move Green + 1</button></p>
<p><button id='greendn'>Move Green -1</button></p>
<p><button id='greenup10'>Move Green +10</button></p>
<p><button id='greendn100'>Move Green -100</button></p>
<span id='info'></span>
</div>
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/konva#2.4.2/konva.min.js"></script>
<meta charset="utf-8">
<title>Konva Shape Layering Demo</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #F0F0F0;
}
#buttons {
position: absolute;
left: 10px;
top: 0px;
}
button {
margin-top: 10px;
display: block;
}
</style>
</head>
<body>
<div id="container"></div>
<div id="buttons">
<button id="toTop">
yellow z-index -2
</button>
<button id="toBottom">
yellow -9
</button>
<button id="up">
yellow z-index 1
</button>
<button id="down">
yellow z-index -5
</button>
<button id="zIndex">
Set yellow box zIndex to 3
</button>
</div>
<script>
var width = window.innerWidth;
var height = window.innerHeight;
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});
var layer = new Konva.Layer();
var offsetX = 0;
var offsetY = 0;
var colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple'];
var yellowBox = null;
for(var n = 0; n < 6; n++) {
// anonymous function to induce scope
(function() {
var i = n;
var box = new Konva.Rect({
x: i * 30 + 210,
y: i * 18 + 40,
width: 100,
height: 50,
fill: colors[i],
stroke: 'black',
strokeWidth: 4,
draggable: true,
name: colors[i]
});
box.on('mouseover', function() {
document.body.style.cursor = 'pointer';
});
box.on('mouseout', function() {
document.body.style.cursor = 'default';
});
if(colors[i] === 'yellow') {
yellowBox = box;
}
layer.add(box);
})();
}
stage.add(layer);
// add button event bindings
document.getElementById('toTop').addEventListener('click', function() {
yellowBox.setZIndex(-2);
layer.draw();
}, false);
document.getElementById('toBottom').addEventListener('click', function() {
yellowBox.setZIndex(-9);
layer.draw();
}, false);
document.getElementById('up').addEventListener('click', function() {
yellowBox.setZIndex(1);
layer.draw();
}, false);
document.getElementById('down').addEventListener('click', function() {
yellowBox.setZIndex(-5);
layer.draw();
}, false);
document.getElementById('zIndex').addEventListener('click', function() {
yellowBox.setZIndex(3);
layer.draw();
}, false);
</script>
</body>
</html>
Last
Fun messing with ZIndex code,
the setZIndex is all you need; It will vain the z-index inside Konva.JS
If you would prefer to be able to set the render order of nodes using arbitrary numbers (like CSS, or how it works in most game engines, etc), you can use this fork of Konva. Alternatively, you could also grab & apply just the rejected pull request for this feature if you already have a customized Konva version.
The new feature works by adding a zOrder property to all Nodes, and a special kind of group AbsoluteRenderOrderGroup that reads and understands this property for all children.

Possible to layer a KonvaJS Stage/canvas on top of another canvas?

Newbie question, maybe.
HTML:
<div id="myDiv">
<canvas id="myCanvas" style="display:inline; border: 1px solid #000000;"> </canvas>
</div>
What I want to do is place a KonvaJS Stage on top of (i.e. higher on the z-axis) myCanvas above.
If I use the default code:
var stage = new Konva.Stage({
container: 'myDiv',
width: window.innerWidth,
height: window.innerHeight
});
The Stage is placed inline after myCanvas.
Is there a way to tell Konva to layer its canvas?
You can add a container for the stage into your myDiv:
<div id="myDiv">
<canvas id="myCanvas" style="display:inline; border: 1px solid #000000;"></canvas>
<div id="container"></div>
</div>
Then create a stage a place it on top of the absolute position.
const myCanvas = document.getElementById('myCanvas');
const stage = new Konva.Stage({
container: 'container',
width: myCanvas.width,
height: myCanvas.height
});
stage.container().style.position = 'absolute';
stage.container().style.top = '0';
stage.container().style.left = '0';
// add z-index if you need it

Kinetics saving image error

Im having problems with kinetics. I have a stage with kinetics with a one image and text, but that I want is export the stage to a image like myImage.jpg no like [data:image/wIlksoks.e] that it is the callback that return dataUrl() from kinetics.
Im trying with this code:
stage.toDataURL({
width: 350,
height: 350,
mimeType: "image/jpeg",
callback: function(dataUrl) {
/*
* here you can do anything you like with the data url.
* In this tutorial we'll just open the url with the browser
* so that you can see the result as an image
*/
window.open(dataUrl);
}
});
}, false);
King Regards!
You can use stage.toDataURL to get your dataURL for the server:
stage.toDataURL({
callback:function(dataURL){
// dataURL is available for saving to your server
}
});
Note: Be sure that your image and your .html are hosted on the same domain.
Otherwise your stage.toImage will fail because of CORS security.
So be sure to check your console for CORS security errors !
Alternatively:
You can use stage.toImage to create a dataURL from your image+text.
Then you can create a temp canvas to get the dataURL.
stage.toImage({
callback:function(stageImg){
var tempCanvas=document.createElement("canvas");
var tempCtx=tempCanvas.getContext("2d");
tempCanvas.width=stageImg.width;
tempCanvas.height=stageImg.height;
tempCtx.drawImage(stageImg,0,0);
var dataURL=tempCanvas.toDataURL();
// dataURL is available for saving to your server
}
});
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/RV694/
<!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.0.min.js"></script>
<style>
#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();
stage.add(layer);
var img=new Image();
img.onload=function(){
start();
}
img.crossOrigin="anonymous";
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/KoolAidMan.png";
function start(){
var kImage = new Kinetic.Image({
x: 0,
y: 0,
width: 300,
height: 300,
image:img
});
layer.add(kImage);
var kText = new Kinetic.Text({
x:20,
y:20,
fontSize:24,
fill:"blue",
text:"Hello!"
});
layer.add(kText);
layer.draw();
}
$("#stageAsImage").click(function(){
stage.toImage({
callback:function(stageImg){
var tempCanvas=document.createElement("canvas");
var tempCtx=tempCanvas.getContext("2d");
tempCanvas.width=stageImg.width;
tempCanvas.height=stageImg.height;
tempCtx.drawImage(stageImg,0,0);
var dataURL=tempCanvas.toDataURL();
var imageElement=document.getElementById("newImage");
imageElement.src=dataURL;
}
});
});
}); // end $(function(){});
</script>
</head>
<body>
<button id="stageAsImage">Save stage as image</button>
<div id="container"></div>
<img id="newImage">
</body>
</html>

Resources