I went through the initial tutorial for making a user radar on Zigfu's website. I am having trouble getting this radar to work in the canvas element.
I want to using the drawing methods in canvas, so I don't want it in the container.
Here is my code so far taken directly from the tutorial. Thanks so much for reading!
function loaded() {
var radardiv = document.getElementById('container');
var radar = {
onuserfound: function (user) {
var userdiv = document.createElement('div');
userdiv.className = 'user';
user.radarelement = userdiv;
radardiv.appendChild(user.radarelement);
},
onuserlost: function (user) {
radardiv.removeChild(user.radarelement);
},
ondataupdate: function (zigdata){
for (var userid in zigdata.users){
var user = zigdata.users[userid];
var pos = user.position;
//console.log(pos);
var el = user.radarelement;
var parentElement = el.parentNode;
var zrange = 2000;
var xrange = 700;
var pixelwidth = parentElement.offsetWidth;
var pixelheight = parentElement.offsetHeight;
var heightscale = pixelheight / zrange;
var widthscale = pixelwidth / xrange;
el.style.left = (((pos[0] / xrange) + 0.5) * pixelwidth - (el.offsetWidth / 2)) + "px";
el.style.top = ((pos[2] / zrange) * pixelheight - (el.offsetHeight / 2)) - 150 + "px";
}
}
};
zig.addListener(radar);
}
document.addEventListener('DOMContentLoaded', loaded, false);
<body>
<div id = 'container'></div>
</body>
</html>
<style>
div#container {
width: 800px;
height: 600px;
border: 1px solid black;
overflow: hidden;
}
div.user {
position: relative;
width: 10px;
height: 10px;
background-color: red;
}
It seems you are missing tags around the javascript, as well as some css for the users radar. Also - your 'container' div is missing a >
Try copying the code from the bottom of http://zigfu.com/en/zdk/tutorials/, or - check out http://zigfu.com/en/zdk/recipes/#omercy16 for a cleaner implementation of the users radar.
The radar used in the tutorial makes use of DOM div placement and positioning.
Unfortunately this can't be used inside the canvas element.
There are ways to overlay over the canvas and other workarounds. See: Placing a <div> within a <canvas>
You can also take the data directly from the plugin and draw to the canvas yourself.
Here is a demo using three.js and zigfu to draw the skeleton onto a canvas:
http://blog.kinect.tonkworks.com/post/30569123887/kinect-online-app-javascript-dev-tutorial-1
Related
I'm experimenting with adding divs to the DOM programmatically. I want to arrange them in a circle within a "master" div,
<body>
<div id="master">
</div>
<script src="js/main.js"></script>
</body>
thusly:
window.addEventListener('load',init);
let master;
function init() {
master = document.getElementById('master');
const count = 8;
const radius = 50;
for (let i=0; i<count;i++){
const diva = document.createElement('div');
diva.id = i;
master.appendChild(diva);
let {x,y} = returnCoords(100,100,degreesToRad((360/count) * i),radius);
diva.style.left = x + "px";
diva.style.top = y + "px";
console.log(diva.style.width); // empty!
}
}
function degreesToRad(degrees) {
return degrees * (Math.PI / 180);
}
function radToDegrees(rad) {
return radians * (180 / Math.PI);
}
function returnCoords(originX = 0, originY = 0,radians,radius) {
let x = originX + (Math.cos(radians) * radius);
let y = originY + (Math.sin(radians) * radius);
return ({x,y});
}
These divs are styled by SCSS:
#master {
background:pink;
height:300px;
width:300px;
position: relative;
div {
background: white;
height:20px;
width:20px;
border:blueviolet solid 1px;
position:absolute;
}
}
And this all works fine. However I can't get the width of the div, even after it's added into the DOM. The line console.log(diva.style.width); produces nothing. Thus I can't move the divs based on their width. What am I missing?
The .style property reads the inline styles of an element, not the ones assigned by CSS. Confusing, for sure. Read more about it here: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style
$(this).css({
position: 'absolute',
left: Math.random() * ($('.parentcontainer').width() - $(this).width()),
top: Math.random() * ($('.parentcontainer').height() - $(this).height())
});
I got this each loop that will randomly place elements within a div. The problem with this is that the elements will overlap each other sometimes because they are absolute positioned. Is there anyway to go around this in js to check position? or maybe rewrite this with margin values? Thanks a ton!
There's a few different ways you can do to achieve this. I find it easiest to try to define the problem in one sentence:
New square's position must be at least X distance from current square positions
Using this sentence, we can make some simple theories as to how the code will work.
Assuming all squares are 50x50 pixels, we can write some checks.
Here are some pseudo code steps we could follow:
Generate a random position for newSquare
Compare the x and y positions of newSquare to all existing squares
If either of the x and y positions of newSquare are further away from the other squares, newSquare can be placed
Otherwise, try again
var container = $('#container');
var squareSize = 50;
var containerSize = 500;
for (var i = 0; i < 20; i++) {
var foundSpace = false;
while (!foundSpace) {
// Generate random X and Y
var randX = Math.floor(Math.random() * (containerSize - squareSize));
var randY = Math.floor(Math.random() * (containerSize - squareSize));
var hitsSquare = false;
var squares = container.children();
squares.each(function(index, square) {
var square = $(square);
// parseInt() because .css() returns a string
var left = parseInt(square.css('left'));
var top = parseInt(square.css('top'));
// Check boundaries
var hitsSquareX = Math.abs(left - randX) < squareSize;
var hitsSquareY = Math.abs(top - randY) < squareSize;
// Will overlap a square
if (hitsSquareX && hitsSquareY) {
hitsSquare = true;
// jQuery break .each()
return false;
}
});
// If doesn't overlap any square
if (!hitsSquare) {
foundSpace = true;
var newSquare = $('<div class="square">');
newSquare.offset({
left: randX,
top: randY
});
container.append(newSquare);
}
}
}
#container {
position: relative;
}
.square {
position: absolute;
background-color: red;
width: 48px;
/* border adds 2px */
height: 48px;
/* border adds 2px */
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
</div>
You should look for collision detection.
In my opinion this is a great tutorial: https://www.youtube.com/watch?v=XYzA_kPWyJ8, but there are several other great ones out there.
Good luck :)
I've looked at all the questions on here asking the same thing and tried every suggestion, none of it is working for me.
I want to layer two dynamically created canvas elements on top of each other, inside the div with an id of "plotPlaceholder".
It continues to just show one below the other, like so:
// grab elements from form
var wid = document.getElementById("wid").value;
var hei = document.getElementById("hei").value;
// grab div container and create canvas elements
var canvasPlaceholder = document.getElementById("plotPlaceholder");
var baseCanvas = document.createElement("canvas");
var canvasElement = document.createElement("canvas");
canvasElement.width = wid;
canvasElement.height = hei;
baseCanvas.width = wid;
baseCanvas.height = hei;
baseCanvas.style.zIndex = "1";
canvasElement.style.zIndex = "2";
baseCanvas.id = "canvasToHoldGrid";
canvasElement.id = "plottingCanvas";
canvasPlaceholder.appendChild(baseCanvas);
canvasPlaceholder.appendChild(canvasElement);
canvas {
border: 2px solid #27a3ea;
position: absolute;
top: 0;
left: 0;
}
#plotPlaceholder {
position: relative;
}
<div id="plotPlaceholder"></div>
I found out what was happening - there was an extra div being created (parent of the canvas elements) with a class of 'canvas-container'. The position property was being overwritten.
.canvas-container {
position: absolute !important;
top: 0;
left: 0;
}
That !important fixed it, although I'm sure it's not best practice in most circumstances.
I'm currently learning canvas touch event function,I 'm able to draw line on the canvas, now I want to get the x and y coordinates when I draw any lines and show on the screen.please help and teach me how to get the x and y values, thank You!
here is the coding
<!DOCTYPE html>
<html><head>
<style>
#contain {
width: 500px;
height: 120px;
top : 15px;
margin: 0 auto;
position: relative;
}
</style>
<script>
var canvas;
var ctx;
var lastPt=null;
var letsdraw = false;
var offX = 10, offY = 20;
function init() {
var touchzone = document.getElementById("layer1");
touchzone.addEventListener("touchmove", draw, false);
touchzone.addEventListener("touchend", end, false);
ctx = touchzone.getContext("2d");
}
function draw(e) {
e.preventDefault();
if (lastPt != null) {
ctx.beginPath();
ctx.moveTo(lastPt.x, lastPt.y);
ctx.lineTo(e.touches[0].pageX - offX,
e.touches[0].pageY - offY);
ctx.stroke();
}
lastPt = {
x: e.touches[0].pageX - offX,
y: e.touches[0].pageY - offY
};
}
function end(e) {
var touchzone = document.getElementById("layer1");
e.preventDefault();
// Terminate touch path
lastPt = null;
}
function clear_canvas_width ()
{
var s = document.getElementById ("layer1");
var w = s.width;
s.width = 10;
s.width = w;
}
</script>
</head>
<body onload="init()">
<div id="contain">
<canvas id="layer1" width="450" height="440"
style="position: absolute; left: 0; top: 0;z-index:0; border: 1px solid #ccc;"></canvas>
</div>
</body>
</html>
Still not entirely confident I understand your question.
In the code you posted, you are already obtaining coordinates using e.touches[0].pageX/Y. The main problem with that is that the pageX/Y values are relative to the page origin. You are then subtracting fixed offX/Y in your code to try and convert these to canvas-relative coordinates. Right idea, wrong values. You need to subtract off the position of the canvas element which can be obtained by summing the offsetX/Y values as you traverse the tree upward using the offsetParent reference.
Something like:
offX=0;offY=0;
node = document.getElementById ("layer1");
do {
offX += node.offsetX;
offY += node.offsetY;
node = node.offsetParent;
} while(node);
should give you a better value for offX and offY.
If you just want to locate the actual drawing at the end, it would be easiest just to track a bounding box while the user draws.
Actually I'm looking for a jQuery plug-in that can handle this:
there is a container with overflow hidden
inside of this is another one, which is way larger
when i move over the div, the part I'm seeing depends on my current position
when I'm in the left top corner I see the top left corner of the inner container
when I'm in the middle i see the middle of the container …
I wrote a little JavaScript that does that:
this.zoom.mousemove( function(event) {
var parentOffset = $(this).parent().offset();
var relativeX = event.pageX - parentOffset.left;
var relativeY = event.pageY - parentOffset.top;
var differenceX = that.zoom.width() - that.pageWidth;
var differenceY = that.zoom.height() - that.pageHeight;
var percentX = relativeX / that.pageWidth;
var percentY = relativeY / that.pageHeight;
if (1 < percentX) {
percentX = 1;
}
if (1 < percentY) {
percentY = 1;
}
var left = percentX * differenceX;
var top = percentY * differenceY;
that.zoom.css('left', -left).css('top', -top);
});
But this isn't very smooth and kinda jumpy, when you enter from another point of the container. So, before reinventing the wheel: Is there one plug in, that does exactly that and has iOS support (drag instead of mouse move)? All zoom plug ins (like Cloud Zoom) are over the top for this purpose and most have no support for dragging on iOS.
And if there's not something like this. How can I make this smoother and cooler. Any approach would be helpful. :)
Many thanks.
So, here is my solution - which works pretty well and is easy to achieve. There could be done some improvement, but to get the idea i'll leave it that way. :)
there is a demo on jsfiddle:
http://jsfiddle.net/insertusernamehere/78TJc/
CSS
<style>
div.zoom_wrapper {
position: relative;
overflow: hidden;
width: 500px;
height: 500px;
border: 1px solid #ccc;
cursor: crosshair;
}
div.zoom_wrapper > * {
position: absolute;
}
</style>
HTML
<div class="zoom_wrapper">
<img id="zoom" src="http://lorempixel.com/output/people-q-c-1020-797-9.jpg" alt="">
</div>
JAVASCRPT
<script>
var zoom = null;
// this function will work even if the content has changed
function move() {
// get current position
var currentPosition = zoom.position();
var currentX = currentPosition.left;
var currentY = currentPosition.top;
// get container size
var tempWidth = zoom.parent().width();
var tempHeight = zoom.parent().height();
// get overflow
var differenceX = zoom.width() - tempWidth;
var differenceY = zoom.height() - tempHeight;
// get percentage multiplied by difference (in pixel) cut by percentage (here 1/4) that is used as "smoothness factor"
var tempX = zoom.data('x') / tempWidth * differenceX / 4;
var tempY = zoom.data('y') / tempHeight * differenceY / 4;
// get real top and left values to move to and the last factor slows it down and gives the smoothness (and it's corresponding with the calculation before)
var left = (tempX - currentX) / 1.25;
var top = (tempY - currentY) / 1.25;
// finally apply the new values
zoom.css('left', -left).css('top', -top);
}
$(document).ready(function () {
zoom = $('#zoom');
//handle mousemove to zoom layer - this also works if it is not located at the top left of the page
zoom.mousemove( function(event) {
var parentOffset = $(this).parent().offset();
zoom.data('x', event.pageX - parentOffset.left);
zoom.data('y', event.pageY - parentOffset.top);
});
// start the action only if user is over the container
zoom.hover(
function() {
zoom.data('running', setInterval( function() { move(); }, 30) );
},
function() {
clearInterval(zoom.data('running'));
}
);
});
</script>
Note:
This one has, of course, no support for touch devices. But for that I use (again)/I can recommend the good old iScroll … :)