I'm trying to make a really simple website in javascript.
I want the website to have a stack of images that you can drag.
So far I managed to do it. But now I want to always bring to front the last clicked image.
How can I do this ? Thanks !
Here is my code :
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/konva#8.4.0/konva.min.js"></script>
<meta charset="utf-8" />
<title></title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #f0f0f0;
}
</style>
</head>
<body>
<div id="container"></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();
stage.add(layer);
var img1 = new Konva.Image({
x: 20,
y: 20,
width: 400,
height: 566,
draggable: true,
});
layer.add(img1);
var img2 = new Konva.Image({
x: 100,
y: 20,
width: 400,
height: 566,
draggable: true,
});
layer.add(img2);
var imageObj1 = new Image();
imageObj1.onload = function () {
img1.image(imageObj1);
};
imageObj1.src = 'imgs/img1.jpg';
var imageObj2 = new Image();
imageObj2.onload = function () {
img2.image(imageObj2);
};
imageObj2.src = 'imgs/img2.jpg';
</script>
</body>
</html>
I've seen this code on another post, but I don't know how to make it work ..
$("img.myclass").click(function() {
$("img.myclass").not(this).css("z-index", 0);
$(this).css("z-index", 100);
});
The "code on another post" is written in jQuery wich is an javascript library and need to be added to your page as you do with konva.
Konva is a tool that draw an canvas.
You can change zIndex (property that will change order of your stack) when you click on image.
For example:
img1.zIndex(0);
img2.zIndex(1); // will set img2 higher
If image didn't have zIndex() function you can try to wrap it to a group.
const group1 = new Konva.Group();
group1.add(img1);
group1.zIndex(0);
Edit:
Increase zIndex on click.
let zIndex = 0;
img.onclick = function () {
zIndex += 1;
img.zIndex(zIndex);
}
I'm trying to do an app in which you can draw custom rectangle shape objects and be able to drag your stage at the same time. Is it possible with Konva.js?
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});
document.addEventListener('mousedown', (e) => {
switch (e.button) {
case 0:
stage.draggable(false);
break;
case 2:
stage.draggable(true);
break;
}
});
Use Konva.dragButtons like so:
import Konva from 'konva';
Konva.dragButtons = [2];
Where the list represents the buttons that can be used for dragging (0=left,1=middle,2=right)
Ok, so if you wondering how to do it this is a possible solution:
var stage = new Konva.Stage({
container: 'container',
width: width,
height: height
});
document.addEventListener('mousedown', (e) => {
if(e.button === 0) stage.draggable(false);
});
document.addEventListener('mouseup', (e) => {
if(e.button === 0) stage.draggable(true);
});
To achieve your goals you can use this:
const stage = new Konva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight,
draggable: true
});
const layer = new Konva.Layer();
stage.add(layer);
const circle = new Konva.Circle({
x: stage.width() / 2,
y: stage.height() / 2,
radius: 50,
fill: 'green'
});
layer.add(circle);
layer.draw();
stage.on('contextmenu', e => {
e.evt.preventDefault();
})
stage.on('mousedown', (e) => {
const isLeft = e.evt.button === 0;
stage.draggable(!isLeft);
});
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="Konva demo">
<script src="https://unpkg.com/konva#^2/konva.min.js"></script>
<meta charset="utf-8">
</head>
<body>
<div id="container"></div>
</body>
</html>
I'd like to drag a Konva layer even if empty. I see that I can drag the layer only where objects are present (the code shows that you can drag where the rectangle is but nowhere else).
How can I drag the layer dragging empty parts?
Moreover, I see that also the mouseenter and mousleave aren't respected if you are out of the objects of the layer.
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
</head>
<body>
<script src="js/modulePattern.js"></script>
<script src="https://unpkg.com/konva#2.4.2/konva.min.js"></script>
<div id="container"></div>
<script>
function demo() {
var stage = new Konva.Stage({
container: 'container',
width: 100,
height: 100
});
var layer = new Konva.Layer({draggable: true});
stage.add(layer);
layer.on("dragmove", function() {
console.log(this.x(), this.y())
});
layer.on("mouseenter", function() {
stage.container().style.cursor = 'pointer';
});
layer.on("mouseleave", function() {
stage.container().style.cursor = 'default';
});
var rect = new Konva.Rect({
width: 50,
height: 50,
fill: 'red',
stroke: 'black',
strokeWidth: 5
});
layer.add(rect);
stage.draw();
}
demo();
</script>
</body>
</html>
Konva does not detect events on empty space of layers. And it is unclear how can it do it if you have several layers on the stage.
If you still need to listen on empty layers and make a layer draggable at any space you can:
Make stage draggable instead and listen events on it (click will work on empty space too).
Add a transparent rectangle as a background, so it will be used to listen to events:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
</head>
<body>
<script src="js/modulePattern.js"></script>
<script src="https://unpkg.com/konva#2.4.2/konva.min.js"></script>
<div id="container"></div>
<script>
function demo() {
var stage = new Konva.Stage({
container: 'container',
width: 300,
height: 300
});
var layer = new Konva.Layer({draggable: true});
stage.add(layer);
layer.on("mouseenter", function() {
stage.container().style.cursor = 'pointer';
});
layer.on("mouseleave", function() {
stage.container().style.cursor = 'default';
});
var rect = new Konva.Rect({
width: 50,
height: 50,
fill: 'red',
stroke: 'black',
strokeWidth: 5
});
var back = new Konva.Rect({
fill: 'red',
width: stage.width(),
height: stage.height()
})
layer.add(back);
// move rectangle so it always stay on the screen, no matter where layer it
layer.on('dragend', function() {
back.setAbsolutePosition({x: 0, y: 0});
layer.draw();
});
layer.add(rect);
stage.draw();
}
demo();
</script>
</body>
</html>
I'm having some problems with my javascript canvas application, where I try to change the background color of an html element outside the canvas area when mouse the mouse cursor is over a canvas shape. I'm using konva library.
What I'm trying to do in code is to target the html side text class and colorize its background when mouse cursor is over canvas element shape building. Moving to different buildings it highlights different text elements to show what areas are in that building. When cursors leaves the canvas building area and is not on any other building it highlights no text elements. Its like an interactive map.
So what I'm asking is, how can I highlight text element on html side when hovering over canvas shape then stop highlighting when leaving the canvas shape while using konva library?
var stage = new Konva.Stage({
container: 'container',
width: 600,
height: 800
});
var layer = new Konva.Layer();
//just few buildings for example
var shapes = [];
shapes.push({
points: [117,188,218,188,218,218,137,218,137,225,117,225],
name: "Building-A",
link: "a-building-link",
});
shapes.push({
points: [230,185,255,185,255,310,250,310,250,318,237,318,237,310,230,310],
name: "Building-B",
link: "b-building-link",
});
shapes.push({
points: [261,134,367,134,367,152,261,152],
name: "Building-C",
link: "c-building-link",
});
for (var i = 0; i < shapes.length; i++) {
var s = shapes[i];
//var links = document.getElementsByClassName(s.link);
var poly = new Konva.Line({
points: s.points,
fill: 'rgba(255,0,0,0.2)',
stroke: 'black',
strokeWidth: 3,
closed : true,
name: s.link,
opacity: 0
});
poly.on('mouseover', function () {
this.opacity(1);
layer.draw();
//Some things I tried to get this working
//for (var i = 0; i < links.length; i++) {
//var item = links[i];
//item.style.backgroundColor = "#ffcc00";
//}
/////////////////
//var item = this.name;
//item.style.backgroundColor = "#ffcc00";
////////////////
//document.getElementsByClassName(this.name).style.backgroundColor = "#ffcc00";
///////////////
//highlight_target = this.name;
///////////////
//document.getElementsByClassName(${this.name}).style.backgroundColor = "#ffcc00";
///////////////
//document.getElementsByClassName(s.name).style.backgroundColor = "#ffcc00";
});
poly.on('mouseout', function () {
this.opacity(0);
layer.draw();
//Some things I tried to get this working
//for (var i = 0; i < links.length; i++) {
//var item = links[i];
//item.style.backgroundColor = "";
//}
/////////////
//var item = this.name;
//item.style.backgroundColor = "";
/////////////
//document.getElementsByClassName(this.name).style.backgroundColor = "";
/////////////
//highlight_target = "";
/////////////
//document.getElementsByClassName(${this.name }).style.backgroundColor = "";
/////////////
//document.getElementsByClassName(s.name).style.backgroundColor = "";
});
layer.add(poly);
}
stage.add(layer);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div id="container"></div>
<div class="textlink a-building-link b-building-link">
<span>Place 1</span>
<span>A, B</span>
<span>1</span>
</div>
<div class="textlink c-building-link">
<span>Place 4 and 5</span>
<span>C</span>
<span>3</span>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/konvajs/konva/1.7.6/konva.min.js"></script>
<script type="text/javascript" src="test.js"></script>
</body>
</html>
Thanks for any help.
You were very close. To get the name of the shape you need to use .name(). After that it looks like some of your code would have worked.
I moved the building shapes layer up the page and put the text at the top in the snippet so that it is more clear what is going on for other future readers. Additionally, since Konvajs relies on jquery being present, you can use the handy jquery selector mechanism to access your test elements. This is not critical to the solution.
var stage = new Konva.Stage({
container: 'container',
width: 600,
height: 400
});
var layer = new Konva.Layer();
//just few buildings for example
var shapes = [];
shapes.push({
points: [117,188,218,188,218,218,137,218,137,225,117,225],
name: "Building-A",
link: "a-building-link",
});
shapes.push({
points: [230,185,255,185,255,310,250,310,250,318,237,318,237,310,230,310],
name: "Building-B",
link: "b-building-link",
});
shapes.push({
points: [261,134,367,134,367,152,261,152],
name: "Building-C",
link: "c-building-link",
});
for (var i = 0; i < shapes.length; i++) {
var s = shapes[i];
//var links = document.getElementsByClassName(s.link);
var poly = new Konva.Line({
points: s.points,
fill: 'rgba(255,0,0,0.2)',
stroke: 'black',
strokeWidth: 3,
closed : true,
name: s.link,
opacity: 0.5
});
poly.on('mouseover', function () {
this.opacity(1);
layer.draw();
// use name() to ge the name. I then use the name as a jquery selector.
$('.' +this.name()).css({ backgroundColor: "#ffcc00"});
});
poly.on('mouseout', function () {
this.opacity(0.5);
layer.draw();
$('.' +this.name()).css({ backgroundColor: "transparent"});
});
layer.add(poly);
layer.move({x:0, y:-40}) // make layer nearer the top of page for SO.
stage.draw();
}
stage.add(layer);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div class="textlink a-building-link b-building-link">
<span>Place 1</span>
<span>A, B</span>
<span>1</span>
</div>
<div class="textlink c-building-link">
<span>Place 4 and 5</span>
<span>C</span>
<span>3</span>
</div>
<div id="container"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/konvajs/konva/1.7.6/konva.min.js"></script>
<script type="text/javascript" src="test.js"></script>
</body>
</html>
I am having troubles with my multidimensional array. There are no errors, but the images are not appearing. I don't know why. please help
<!doctype html>
<html>
<head><script src="kinetic.js"></script></head>
<body>
<div id="canvas" align="center">
<span id="timer"></span>
<div id="container"></div>
<script>
var stage = new Kinetic.Stage({
container: 'container',
width: 850,
height: 650
});
var layer = new Kinetic.Layer();
var image = [];
var img = [];
var images = [
["1.png","2.png","3.png","4.png"]
];
this is the part where I am having problems:
for (var a = 0; a < 4; a++) {
img[a] = new Image();
img.src = images[0][a];
img.onload = function(){
image[a] = new Kinetic.Image({
x: Math.floor(Math.random()*400),
y: Math.floor(Math.random()*400),
image: img[a],
width: 500,
height: 500
});
layer.add(image[a]);
image[a].draw();
}
}
</script>
</body>
</html>