how to overwrite ( or update) shape of width and hiehgt in konva js? - konvajs

I am using konva js in my project. i am having doubt how to update already existing value of shape width and height.
Ex:
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height,
fill: "white",
});
var layer = new Konva.Layer();
stage.add(layer);
var bg = new Konva.Rect({
x: 0,
y: 0,
width:width ,
height:height ,
fill: 'white',
draggable: false,
});
layer.add(bg);
// ---------------------------------
var update_shape=()=>{
//i want to update here <-------------just calling this function
}
now i want to update above width and height values dynamically

shape.width(newWidth);
// or
shape.setAttr('width', newWidth);
// or
shape.setAttrs({ width: newWidth });

Related

Konvajs - how to take a screenshot without transparency

Im just trying to let my user take a screenshot using the toDataUrl() function.
but, without a background rectangle, all pixel are transparent , and appear black .
so the solution is to dynamicly add a rectangle, generate the image, destroy the rectangle
saveImage(){
const stage=this.$parent.$refs.stage.getStage()
var stageRect = new Konva.Rect({
x:0,
y:0,
width: stage.attrs.width,
height: stage.attrs.height,
fill: 'green',
})
console.log(stage)
const backg=new Konva.Layer();
backg.add(stageRect)
stage.add(backg)
backg.setZIndex(0)
const dataURL = stage.toDataURL({ pixelRatio: 1, mimeType:"image/png" });
backg.destroy();
this.downloadURI(dataURL, 'stage.png');
},
it works (rectangle is created before all other layer) but... i can't get the size of the stage, i mean, the viewport because the user can zoom/dezoom the stage ....
any idea ?
Just use a scale to calculate background properties:
var stageRect = new Konva.Rect({({
x: -stage.x()/ stage.scaleX(),
y: -stage.y()/ stage.scaleY(),
width: stage.width() / stage.scaleX(),
height: stage.height() / stage.scaleY(),
fill: 'green',
});
Demo: https://jsbin.com/lehasitaje/2/edit?html,js,output

Is there a way to set negative/Inverted color as stroke/fill color

I'm drawing a closed line over a busy image as a background. It's working fine.
But my goal is to highlight the stroke as much as possible. Therefore, I'm looking for a way to make the line's stroke color 'negative/inverted' pixel of what's underneath that line.
For example:
<Line ... stroke="inverted" />
Possible? Achievable in some other way?
You may be able to use the globalCompositionOperation.
Mozilla docs here
Konva example here - see the parameters for the Konva.Rect() call. The example is for text, so not exactly as you require but hopefully you can adapt for the line requirement.
I tried to create a snippet to illustrate this but could not get exactly what you require. However, you can see how to apply the globalCompositionOperation parameter for a Konva line. Change the value of the comp variable to the other composition mode names from the Mozilla page to see their effects. The line is draggable.
An alternative may be to get the canvas pixel data, work out the pixels under the line and invert them individually.
// This is the color-composition mode
var comp = 'exclusion'
var stage = new Konva.Stage({
container: 'container',
width: 500,
height: 230
});
var layer = new Konva.Layer();
stage.add(layer)
var rect = new Konva.Rect({ x: 10, y: 0, width:500, height: 230,
fillLinearGradientStartPoint: { x: -50, y: -50 },
fillLinearGradientEndPoint: { x: 250, y: 150 },
fillLinearGradientColorStops: [0, 'red', 1, 'yellow']
})
layer.add(rect)
var ln = new Konva.Line({
points: [25, 70, 300, 20],
stroke: 'red',
strokeWidth: 15,
lineCap: 'round',
lineJoin: 'round',
draggable: true,
globalCompositeOperation: comp
});
layer.add(ln);
layer.draw()
stage.draw()
#container {
width: 500px;
height: 230px;
background-color: #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/3.2.5/konva.js"></script>
<div id="container"></div>

Konvajs shape stroke color lingers after change

I'm trying to change the stroke color of a hexagon on mouseover, and then back to the original color on mouseout.
My problem is that, if I redraw only the hexagon after updating the stroke color, the previous color lingers around the edges of the stroke.
hexagon.on('mouseover', function(e) {
e.target.stroke('red');
e.target.draw();
});
hexagon.on('mouseout', function(e) {
e.target.stroke('gray');
e.target.draw();
});
Demo at https://codepen.io/jsgarvin/pen/dmRJXj
Here the original color is gray, and it changes to red on mouse over, but on mouse out it changes back to gray with a red dusting around all of the edges.
If I redraw the entire layer though, it seems to do what I expect, but in my particular use case I expect to have several thousand hexagons, among other things, on the layer, and that seems inefficient to redraw the entire layer if I just need to update one hexagon. Is there a more correct way to do this that I'm overlooking? Thanks!
You need to draw the layer.
hexagon.on('mouseover', function(e) {
e.target.stroke('red');
e.target.draw();
layer.draw(); // <<<<< THIS LINE IS THE FIX
});
I found this out as I was coding an alternative which I include below in the snippet. It uses a second shape and we show & hide the two so as to provide the mouseover effect. I can imagine that this will not be viable in all cases but it might help someone out so here is a working snippet.
Left hand is your example copied from your Pen with the fix included, the right is the shape switcher, just for fun.
var stage = new Konva.Stage({
container: 'container',
width: 400,
height: 150
});
var layer = new Konva.Layer();
stage.add(layer);
var c = layer.getCanvas();
var ctx = c.getContext();
var hexagon = new Konva.RegularPolygon({
x: 75,
y: 75,
radius: 55,
sides: 6,
stroke: 'gray',
strokeWidth: 10
});
hexagon.on('mouseover', function(e) {
e.target.stroke('red');
e.target.draw();
layer.draw(); // <<<<< THIS LINE IS THE FIX
});
hexagon.on('mouseout', function(e) {
e.target.stroke('gray');
e.target.draw();
layer.draw(); // <<<<< THIS LINE IS THE FIX
});
var hexagon2 = new Konva.RegularPolygon({
x: 250,
y: 75,
radius: 55,
sides: 6,
stroke: 'gray',
strokeWidth: 10
});
hexagon2.on('mouseover', function(e) {
e.target.visible(false);
hexagon3.visible(true);
layer.draw();
});
var hexagon3 = new Konva.RegularPolygon({
x: 250,
y: 75,
radius: 55,
sides: 6,
stroke: 'red',
strokeWidth: 10,
visible: false
});
hexagon3.on('mouseout', function(e) {
e.target.visible(false);
hexagon2.visible(true);
layer.draw();
});
layer.add(hexagon);
layer.add(hexagon2);
layer.add(hexagon3);
stage.draw();
<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>
<p>Left image is OP's version, right is shape-switching. Mouse-over the hexagons.</p>
<div id='container'></div>

Highcharts: circle with image background

i'm using Highcharts to create a pie, and I need to put user's profile image in a circle in the middle of it. I have managed to add the image but couldn't get it to be round, and I managed to add a circle but without image background :/
what it the best way to combine the tow?
by the way it must be part of the svg and not an absolute div on top of the pie, because the tooltip needs to be on top of that image with opacity
to add a circle I used this code :
var pixelX = 438;
var pixelY = 276;
var pixelR = 70;
// add my circle
chart.renderer.circle(pixelX, pixelY, pixelR)
.attr({
zIndex: 100,
align: 'center',
// fill: 'url(https://lh6.googleusercontent.com/-gaAgFzRLxQQ/AAAAAAAAAAI/AAAAAAAAAjc/ies0iU4BEqU/photo.jpg)',
color: 'url(https://lh6.googleusercontent.com/-gaAgFzRLxQQ/AAAAAAAAAAI/AAAAAAAAAjc/ies0iU4BEqU/photo.jpg)',
stroke: 'black',
'stroke-width': 2
})
.css({
backgroundImage :'url(https://lh6.googleusercontent.com/-gaAgFzRLxQQ/AAAAAAAAAAI/AAAAAAAAAjc/ies0iU4BEqU/photo.jpg)'
})
.add();
});
this example shows how to do it with pure SVG : http://jsfiddle.net/9zkfodwp/1/
resolved it by defining a pattern with the img, works fine but now need to find a way for the pattern to be no-repeat.
code used to add pattern:
function(chart) { // on complete
var r = chart.renderer,
pattern = r.createElement('pattern')
.attr({
id: 'pattern',
patternUnits: 'userSpaceOnUse',
x: 0,
y: 0,
width: 180,
height: 190,
viewBox: '0 0 135 135'
})
.add(r.defs);
r.rect(0, 0, 135, 135, 0)
.attr('fill', '#ddd')
.add(pattern);
r.image(profileImg,0,0,135,135)
.add(pattern);
});
and when I add the circle it can have a fill of the pattern:
// add my circle
this.circle = chart.renderer.circle(pixelX, pixelY, pixelR).attr({
fill: 'url(#pattern)'
});
this.circle.add();

How to crop the gallery images in appcelerator?

I am developing iOS application. In that I have a requirement to crop the images while uploading the images from gallery.can any one help me how to crop the images in appcelerator for ios platform.
Thanks in advance
You can use the internal blob.imageAsCrop() method:
https://docs.appcelerator.com/platform/latest/#!/api/Titanium.Blob-method-imageAsCropped
Properties are width, height, x, y (https://docs.appcelerator.com/platform/latest/#!/api/ImageAsCroppedDict)
It'll returns another blob which you can save or display again
Example:
var croppedImage = blob.imageAsCropped({x : 20, y : 20, width : 100, height : 100});
var imageView = Titanium.UI.createImageView({
image:croppedImage,
width: 100, height:100
});
Example 2:
Titanium.Media.openPhotoGallery({
success: function(event) {
var galleryImage = event.media;
var dict = {
x: 0,
y: 50,
width: 300,
height: 300
};
var croppedImage = galleryImage.imageAsCropped(dict);
var imageView = Ti.UI.createImageView({
image: croppedImage,
height: 'auto',
width: 'auto'
});
$.index.add(imageView);
},
cancel: function() {},
savedToPhotoGallery: true,
allowEditing: true,
mediaTypes: [Ti.Media.MEDIA_TYPE_PHOTO],
showControls: true
});

Resources