I am a 3 month beginner. I'm currently working on a simple game, to try different skills I learned recently and I have a problem I couldn't solve with Google.
My JS code generates a grid made out of divs, (coordinates in ID), and appends a child (the player) once they're here, but I can't get to display the player image. I previously just gave the div a #player id but I changed and tried appending the player as a child div, because later it'll be easier to move a div around rather than removing and adding IDs (when making player controls).
Here's my code:
The CSS
.tile{
margin:2px;
height:50px;
width:50px;
border:1px solid black;
display: inline-block;
}
#map{
height:482px;
width:730px;
background-image:url(bg.png);
}
#player{
background-image:url(player.png);
}
#monster{
background-image:url(monster.png);
}
#start{
margin:auto;
color:white;
background-color:grey;
border:2px solid black;
}
The JavaScript
var game = function(){
$("#hgrass").hide()
$("#htile").hide()
$("#hmnstr").hide()
$("#hplayr").hide()
$("#start").click(function(){startGame();
});
var genMap = function(){
var map = document.createElement("div");
document.body.appendChild(map);
map.setAttribute("id","map")
for(c=0;c<8;c++){
for(r = 0;r<13;r++){
var tile = document.createElement("div");
var tileId = c+"/"+r;
tile.setAttribute("id",tileId);
tile.setAttribute("class","tile");
map.appendChild(tile);
}
}
}
var spawnPlayer = function(){
var rrow = (Math.floor((Math.random() * 8)));
var rcol = (Math.floor((Math.random() * 13)));
var prow = rrow.toString();
var pcol = rcol.toString();
var coord = document.getElementById(prow+"/"+pcol)
var player = document.createElement("div")
player.setAttribute("id","player")
coord.appendChild(player)
}
var spawnMonster = function(){
var rrow = (Math.floor((Math.random() * 8)));
var rcol = (Math.floor((Math.random() * 13)));
var prow = rrow.toString();
var pcol = rcol.toString();
var monster = document.getElementById(prow+"/"+pcol)
monster.setAttribute("id","monster")
}
/*var turns = function(){
var pturn = true
$(document).keypress(function(event){
var pla = document.getElementById("player")
if (event.which == 37){
pla.removeAttribute("id","player");
pturn = false;
}
});
};*/
var startGame = function(){
genMap();
spawnPlayer();
spawnMonster();
// turns();
$("#start").hide()
$("#hgrass").show()
$("#htile").show()
$("#hmnstr").show()
$("#hplayr").show()
}
};
And the HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<link type="text/css" rel="stylesheet" href="test.css"/>
<script src="test.js"></script>
<script src="jquery-3.1.0.js"></script>
</head>
<body onload="game()">
<button type="button" id="start">Click to start</button>
<button type="button" id="hgrass">Click to hide grass
<button type="button" id="htile">Click to hide tiles</button>
<button type="button" id="hmnstr">Click to hide monster</button>
<button type="button" id="hplayr">Click to hide player</button>
</body>
</html>
Related
Note: I have updated my previous code with the suggestions provided below in the answer.
After following the suggestion, I've found that the docking panel is added to the DOM. But not being displayed(even though z-index is set to 2)
This is what I have tried so far. Also, find the screenshot of the console result below.
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=no" />
<meta charset="utf-8">
<link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/style.min.css" type="text/css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/viewer3D.min.js"></script>
<style>
body {
margin: 0;
}
#forgeViewer {
width: 100%;
height: 100%;
margin: 0;
background-color: #F0F8FF;
}
</style>
</head>
<body>
<div id="forgeViewer"></div>
</body>
<script>
var viewer;
var options = {
env: 'AutodeskProduction',
api: 'derivativeV2', // for models uploaded to EMEA change this option to 'derivativeV2_EU'
getAccessToken: function(onTokenReady) {
var token = 'access token here';
var timeInSeconds = 3600; // Use value provided by Forge Authentication (OAuth) API
onTokenReady(token, timeInSeconds);
}
};
SimplePanel = function(parentContainer, id, title, content, x, y)
{
this.content = content;
Autodesk.Viewing.UI.DockingPanel.call(this, parentContainer, id, title,{shadow:false});
// Auto-fit to the content and don't allow resize. Position at the coordinates given.
//
this.container.style.height = "150px";
this.container.style.width = "450px";
this.container.style.resize = "auto";
this.container.style.left = x + "px";
this.container.style.top = y + "px";
this.container.style.zIndex = 2;
};
SimplePanel.prototype = Object.create(Autodesk.Viewing.UI.DockingPanel.prototype);
SimplePanel.prototype.constructor = SimplePanel;
SimplePanel.prototype.initialize = function()
{
this.title = this.createTitleBar(this.titleLabel || this.container.id);
this.container.appendChild(this.title);
this.container.appendChild(this.content);
this.initializeMoveHandlers(this.container);
this.closer = this.createCloseButton();
this.title.appendChild(this.closer);
var op = {left:false,heightAdjustment:45,marginTop:0};
this.scrollcontainer = this.createScrollContainer(op);
var html = [
'<div class="uicomponent-panel-controls-container">',
'<div class="panel panel-default">',
'<table class="table table-hover table-responsive" id = "clashresultstable">',
'<thead>',
'<th>Name</th><th>Status</th><th>Found</th><th>Approved By</th><th>Description</th>',
'</thead>',
'<tbody>',
'<tr><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td></tr>',
'<tr><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td></tr>',
'<tr><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td></tr>',
'<tr><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td></tr>',
'<tr><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td></tr>',
'<tr><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td></tr>',
'<tr><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td></tr>',
'</tbody>',
'</table>',
'</div>',
'</div>'
].join('\n');
$(this.scrollContainer).append(html);
this.initializeMoveHandlers(this.title);
this.initializeCloseHandler(this.closer);
};
Autodesk.Viewing.Initializer(options, function() {
var htmlDiv = document.getElementById('forgeViewer');
viewer = new Autodesk.Viewing.GuiViewer3D(htmlDiv);
var startedCode = viewer.start();
if (startedCode > 0) {
console.error('Failed to create a Viewer: WebGL not supported.');
return;
}
console.log('Initialization complete, loading a model next...');
});
var documentId = 'urn:urn here';
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
function onDocumentLoadSuccess(viewerDocument) {
var defaultModel = viewerDocument.getRoot().getDefaultGeometry();
viewer.loadDocumentNode(viewerDocument, defaultModel);
viewer.addEventListener( Autodesk.Viewing.SELECTION_CHANGED_EVENT, event=>{
//console.log(viewer.model.getData());
console.log(viewer.model.getDocumentNode());
// console.log(SimplePanel.container)
viewer.getPropertyPanel(true).setVisible(true)
var content = document.createElement('div');
var mypanel = new SimplePanel(NOP_VIEWER.container,'mypanel','My Panel',content);
mypanel.setVisible(true);
})
}
function onDocumentLoadFailure() {
console.error('Failed fetching Forge manifest');
}
</script>
</html>```[![console output for the dom][1]][1]
[![DOM screenshot on console][1]][1]
[1]: https://i.stack.imgur.com/Lp1rm.png
You'd need to explicitly call Autodesk.Viewing.UI.DockingPanel.setVisible(true) to make the panel visible and put in the desired position with the correct z-index ahead of overlapping elements in the viewport as well:
SimplePanel.container.style.width = width
SimplePanel.container.style.height = height
SimplePanel.container.style.left = left
SimplePanel.container.style.top = top
SimplePanel.container.style.z-index = 2 // or another value to suit the rest of your UI
SimplePanel.setVisible(true)
Otherwise you'd notice it's already present in the DOMtree with display set to none or either rendered outside of the visible viewport (positioned at top:0,left:0 etc) or behind(blocked by) other elements ...
If the panel still does not appear try to look for relevant console output esp. error messages when you trigger the selection event and check if the panel is already rendered to the DOMtree in the browser's developer tool but somehow still not visible
setTimeout(function () {
var myImg = document.querySelector("#background");
var realWidth = myImg.naturalWidth;
var realHeight = myImg.naturalHeight;
$("canvas").attr("width", realWidth);
$("canvas").attr("height", realHeight);
var source = document.getElementById('background').src;
var canvas = new fabric.Canvas('canvas');
canvas.width = realWidth;
canvas.height = realHeight;
var ctx = canvas.getContext('2d');
document.getElementById('file').addEventListener("change", function (e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function (f) {
var data = f.target.result;
fabric.Image.fromURL(data, function (img) {
var oImg = img.set({
left: 320
, top: 180
, angle: 00
, width: 200
, height: 200
});
canvas.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({
format: 'png'
, quality: 0.8
});
});
};
reader.readAsDataURL(file);
});
canvas.setOverlayImage(source, canvas.renderAll.bind(canvas), {
backgroundImageOpacity: 0.5
, backgroundImageStretch: false
});
canvas.on('mouse:over', function (e) {
canvas.item(0).hasBorders = true;
canvas.item(0).hasControls = true;
canvas.setActiveObject(canvas.item(0));
});
canvas.on('mouse:out', function (e) {
canvas.item(0).hasBorders = false;
canvas.item(0).hasControls = false;
canvas.setActiveObject(canvas.item(0));
});
canvas.renderAll();
}, 2000);
$("#save").click(function () {
function blobCallback(iconName) {
return function (b) {
var a = document.getElementById('download');
a.download = iconName + ".jpg";
a.href = window.URL.createObjectURL(b);
}
}
canvas.toBlob(blobCallback('wallpaper'), 'image/vnd.microsoft.jpg', '-moz-parse-options:format=bmp;bpp=32');
});
.hide {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cricmovie.com/bb-asserts/js/fabric.min.js"></script>
<body>
<div class="container"> <img src="http://cricmovie.com/bb-asserts/images/person.png" id="background" class="hide">
<input type="file" id="file">
<br />
<canvas id="canvas" class="img-responsive"></canvas>
</div>
<div class="container"> <a class="btn btn-primary" id="save">Save</a> <a class="btn btn-primary" id="download">Download</a> </div>
</body>
I am using fabric js to build a facemask application when i have two images
1) Image without face which is applied to canvas using setOverlayImage method
2) Only head where the user will upload and adjust accordingly.
I have almost done with functionality but I want to show fabric handlers above the first image where now they are hiding behind first image.
Reference Image : Click here for reference Image
Please find the Run Code Snippet
I think all you need to do is specify controlsAboveOverlay when you get the fabric instance.
var canvas = new fabric.Canvas('canvas', {
controlsAboveOverlay : true
});
I am trying to create dynamically generated elements when the user clicks on a button. The should slide in from the right, and when the button is clicked again, another should slide in from the right. For some reason, it is not doing exactly what I need it to do. Here's the code:
<html>
<head>
<title>Chat Head</title>
<link rel="stylesheet" type="text/css" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script type="text/javascript" src = "http://maxcdn.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script>
$(document).ready(function(){
screenWidth = $(window).width();
screenHeight = $(window).height();
msgWidth = 0.7*screenWidth;
msgHeight = 0.7*screenHeight;
$("#note").css("width", msgWidth);
$("#note").css("height", msgHeight);
$("#slide").click(function(){
var textArea = '<textarea class = form-control rows = "3" id = "text"></textarea>';
$(textArea).appendTo('.note');
var effect = 'slide';
var duration = 1000;
$(".note").toggle(effect, {direction: 'right'}, duration);
});
});
</script>
</head>
<style type="text/css">
.note{
display: none;
}
</style>
<body>
<div class="row">
<div class="col-md-12">
<button class = "button" id = "slide">Slide</button>
<hr />
<div class="note">
<!-- <textarea class = "form-control" rows = "2" id = "note"></textarea> -->
</div>
</div>
</div>
</body>
</html>
Here's the JS Fiddle that goes with the code:
http://jsfiddle.net/ma6Jq/2/
Here is an implementation I came up with. http://jsfiddle.net/Ar7qw/1/
<script>
$(document).ready(function(){
var count = 0;
$("#slide").click(function(){
count = count + 1;
screenWidth = $(window).width();
screenHeight = $(window).height();
msgWidth = 0.7*screenWidth;
msgHeight = 0.7*screenHeight;
$("#note"+ count).css("width", msgWidth);
$("#note"+ count).css("height", msgHeight);
var newnote = '<div class="note' + count +'"></div>';
$(newnote).appendTo('.col-md-12');
var textArea = '<textarea class="form-control" rows = "3" id = "text"></textarea>';
$(textArea).appendTo('.note' + count);
$('.note' + count).effect('slide', {direction: 'right'}, 1000);
});
});
</script>
This gets you close. I'm out of time for now.
http://jsfiddle.net/isherwood/ma6Jq/10
.note-box {
margin-left: 150%;
}
.done {
margin-left: 10px;
transition: all 1s;
}
$("#slide").click(function () {
var textArea = '<textarea class="form-control note-box" rows="3"></textarea>';
var duration = 1000;
$(textArea).appendTo('#note').addClass('done', duration);
});
Another implementation for anybody needing one(or a couple different choices of solutions)
http://jsfiddle.net/ma6Jq/13/
var counter = 0;
$("#slide").click(function () {
counter ++;
var textArea = '<div class="note' + counter + '"><textarea class ="form-control" rows = "3" id = "text">'+ counter +'yo</textarea></div>';
$(textArea).appendTo('.note');
var effect = 'slide';
var duration = 1000;
var stringhere = ".note" + counter;
$(stringhere).effect('slide',
{
direction:'right'
}, duration);
/*
$(stringhere).animate({
marginLeft: parseInt($(stringhere).css('marginLeft'),1000) == 0 ?
$(stringhere).outerWidth() :
100
});
*/
/*
$(stringhere).toggle(effect, {
direction: 'left'
}, duration);
*/
});
});
I followed a tutorial for infinite loading. I managed this code, but the background just keeps loading again and again. I want to display my content just once. Can anyone help me please? Here's the code.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function yHandler(){
// Watch video for line by line explanation of the code
// http://www.youtube.com/watch?v=eziREnZPml4
var wrap = document.getElementById('wrap');
var contentHeight = wrap.offsetHeight;
var yOffset = window.pageYOffset;
var y = yOffset + window.innerHeight;
if(y >= contentHeight){
// Ajax call to get more dynamic data goes here
wrap.innerHTML += '<div class="newData"></div>';
}
var status = document.getElementById('status');
status.innerHTML = contentHeight+" | "+y;
}
window.onscroll = yHandler;
</script>
<style type="text/css">
div#status{position:fixed; font-size:24px;}
div#wrap{width:800px; margin:0px auto;}
div.newData{height:1000px; background:#09F; margin:10px 0px;}
</style>
</head>
<body>
<div id="status">0 | 0</div>
<div id="wrap"><img src="http://images.bwwstatic.com/tvnetworklogos/1470470F-930B-5791-2D55F77DC33EBA96.jpg"></div>
</body>
</html>
by setting the window.onscroll to null you essentially have a "fire once" event.
<script type="text/javascript">
function yHandler(){
var wrap = document.getElementById('wrap');
var contentHeight = wrap.offsetHeight;
var yOffset = window.pageYOffset;
var y = yOffset + window.innerHeight;
if(y >= contentHeight){
// Ajax call to get more dynamic data goes here
wrap.innerHTML += '<div class="newData"></div>';
window.onscroll = null;
}
var status = document.getElementById('status');
status.innerHTML = contentHeight+" | "+y;
}
window.onscroll = yHandler;
</script>
First of all. I was searching a long time, but I did not find what I want! How can I get next panorama? All what I know is need to get a panorama links. Links can get with getLinks();. I have read google's streetview manual, but I want to navigate with own navigation buttons not Google's!
Modified version of Google Maps Javascript API v3 streetview-events example below which adds buttons to navigate the streetview panorama via the link.
in the global scope:
var panorama = null;
var links = null;
function setPano2link(i) {
panorama.setPano(links[i].pano);
panorama.setPov({heading:links[i].heading,pitch:0});
panorama.setVisible(true);
}
Modify the "links_changed" event handler to add navigation buttons:
google.maps.event.addListener(panorama, 'links_changed', function() {
var linksTable = document.getElementById('links_table');
while(linksTable.hasChildNodes()) {
linksTable.removeChild(linksTable.lastChild);
};
links = panorama.getLinks();
for (var i in links) {
var row = document.createElement('tr');
linksTable.appendChild(row);
var labelCell = document.createElement('td');
labelCell.innerHTML = '<b>Link: ' + i + '</b>';
var valueCell = document.createElement('td');
valueCell.innerHTML = links[i].description;
var btnCell = document.createElement('td');
btnCell.innerHTML = '<input type="button" value="goto" onclick="setPano2link('+i+')"></input>';
var panoIdCell = document.createElement('td');
panoIdCell.innerHTML = links[i].pano;
var headingCell = document.createElement('td');
headingCell.innerHTML = links[i].heading;
linksTable.appendChild(labelCell);
linksTable.appendChild(valueCell);
linksTable.appendChild(btnCell);
linksTable.appendChild(panoIdCell);
linksTable.appendChild(headingCell);
}
});
working example
Complete code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Street View events</title>
<style>
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script>
var cafe = new google.maps.LatLng(37.869085,-122.254775);
var panorama = null;
var links = null;
function setPano2link(i) {
panorama.setPano(links[i].pano);
panorama.setPov({heading:links[i].heading,pitch:0});
panorama.setVisible(true);
}
function initialize() {
var panoramaOptions = {
position: cafe,
pov: {
heading: 270,
pitch: 0
},
visible: true
};
panorama = new google.maps.StreetViewPanorama(document.getElementById('pano'), panoramaOptions);
google.maps.event.addListener(panorama, 'pano_changed', function() {
var panoCell = document.getElementById('pano_cell');
panoCell.innerHTML = panorama.getPano();
});
google.maps.event.addListener(panorama, 'links_changed', function() {
var linksTable = document.getElementById('links_table');
while(linksTable.hasChildNodes()) {
linksTable.removeChild(linksTable.lastChild);
};
links = panorama.getLinks();
for (var i in links) {
var row = document.createElement('tr');
linksTable.appendChild(row);
var labelCell = document.createElement('td');
labelCell.innerHTML = '<b>Link: ' + i + '</b>';
var valueCell = document.createElement('td');
valueCell.innerHTML = links[i].description;
var btnCell = document.createElement('td');
btnCell.innerHTML = '<input type="button" value="goto" onclick="setPano2link('+i+')"></input>';
var panoIdCell = document.createElement('td');
panoIdCell.innerHTML = links[i].pano;
var headingCell = document.createElement('td');
headingCell.innerHTML = links[i].heading;
linksTable.appendChild(labelCell);
linksTable.appendChild(valueCell);
linksTable.appendChild(btnCell);
linksTable.appendChild(panoIdCell);
linksTable.appendChild(headingCell);
}
});
google.maps.event.addListener(panorama, 'position_changed', function() {
var positionCell = document.getElementById('position_cell');
positionCell.firstChild.nodeValue = panorama.getPosition() + '';
});
google.maps.event.addListener(panorama, 'pov_changed', function() {
var headingCell = document.getElementById('heading_cell');
var pitchCell = document.getElementById('pitch_cell');
headingCell.firstChild.nodeValue = panorama.getPov().heading + '';
pitchCell.firstChild.nodeValue = panorama.getPov().pitch + '';
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="pano" style="width: 45%; height: 100%;float:left"></div>
<div id="panoInfo" style="width: 45%; height: 100%;float:left">
<table>
<tr>
<td><b>Position</b></td><td id="position_cell"> </td>
</tr>
<tr>
<td><b>POV Heading</b></td><td id="heading_cell">270</td>
</tr>
<tr>
<td><b>POV Pitch</b></td><td id="pitch_cell">0.0</td>
</tr>
<tr>
<td><b>Pano ID</b></td><td id="pano_cell"> </td>
</tr>
<table id="links_table"></table>
</table>
</div>
</body>
</html>
Go to this link: https://developers.google.com/maps/documentation/embed/start
Go to Google Maps and enter the street-view mode in your browser on the location you want
Click on "Share .."
Search that hyperlink-string (CTRL-F/CMD-F) for "!2e", and copy the string from the first letter after "!" to the first letter after "s" in "!1s".
Example:
!1s
-SWqF6BeQEBI%2FWBXbp08W9pI%2FAAAAAAAACRo%2F17TZj7OS3OMBBkrcNfZ45YlZxGydVryDwCLIB
!2e
If you have any "%2F" in the HTML-string, you need to replace them with "/". If you have "-"-symbol at start, you need to replace it with
"F:-".
Now go back to the link given in the first bullet and click on the tab "Show Street View or a custom panorama"
Past the newly copied string into the field "Custom panorama ID:" and press enter
Now enter your API-key; remember to add the right API-key to your API-project that is made for panorama/street-view! (Google Maps Embed API; you can add more than one key to your project) Click on "Get Key" if you have not already
And that is it!
You will get a personal HTML-code you can past right in to you HTML-document. This is tested and works as of the date I wrote this.