How can i turn a card into its original position? - javascript

I want to know how I can turn back to its original position BOTH cards that didn't match.
If there is a match, there is an alert saying congrats, otherwise try again, but i want that two cards to return to its original position.
The card images are not in here. Can someone help with this?
I want to know how I can turn back to its original position BOTH cards that didn't match.
If there is a match, there is an alert saying congrats, otherwise try again, but i want that two cards to return to its original position.
The card images are not in here. Can someone help with this?
// HOW TO RESTART EVERYTHING WITH TIMEOUT 2s AFTER WINNING OR LOOSING?
//HOW TO BACKFLIP BOTH CARDS IF WRONG?
//GLOBAL VAR
const box = document.getElementsByClassName('box')[0];
var cards = [{
name: 'queen',
clase: 'diamonds',
pic: 'images/queen-of-diamonds.png'
},
{
name: 'queen',
clase: 'hearts',
pic: 'images/queen-of-hearts.png'
},
{
name: 'king',
clase: 'diamonds',
pic: 'images/king-of-diamonds.png'
},
{
name: 'king',
clase: 'hearts',
pic: 'images/king-of-hearts.png'
}
];
function createBoard() {
for (var i = 0; i < cards.length; i++) {
var photo = document.createElement('img');
// console.log(foto);
photo.setAttribute('src', 'images/back.png');
photo.setAttribute('data-id', i);
box.appendChild(photo);
photo.style.paddingLeft = '20px';
photo.style.marginTop = '20px';
photo.style.height = '40%';
photo.style.width = '15%';
photo.style.borderRadius = '3%';
photo.addEventListener('click', function flipcard() {
var cardId = this.getAttribute('data-id');
console.log(cardId + ' is my card id');
var myThis = this; // I want to export THIS cause i cannot access from the other function
cardsInPlay.push(cards[cardId].name);
this.setAttribute('src', cards[cardId].pic);
// console.log(this);
if (cardsInPlay.length === 2) {
checkForMatch(myThis, cardId, photo);
}
});
}
}
createBoard()
var cardsInPlay = [];
//2
function checkForMatch(myThis, cardId, photo) { // match cards dont turn back
if (cardsInPlay[0] === cardsInPlay[1]) {
alert('CONGRATS!!! YOU FOUND A MATCH');
} else {
alert('SORRY TRY AGAIN');
myThis.setAttribute('src', 'images/back.png');
console.log(myThis);
}
}
.box {
background-color: white;
width: 860px;
margin: 50px auto;
/*background-color: black;*/
text-align: center;
background-color: inherit;
}
body {
background-color: #0caab6;
text-align: center;
margin-top: 50px;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<meta charset="utf-8">
<title>CARDS</title>
</head>
<body>
<header>
<h1>PLAY GAME</h1>
</header>
<div class="box">
</div>
<script src="app.js" charset="utf-8"></script>
</body>
</html>

Right now, your cardsInPlay array contains the names of the cards clicked. If you use it to store references to the clicked img elements instead, you'll be able to access everything you need to check for matches and flip the cards back over without passing anything to checkForMatch. Make sure to empty the array after checking!
There's a lot that can be improved here. After you get it working, consider posting to Code Review.

Related

Set backgroundImage in HTML with URL pulled from JSON data

var ourRequest = new XMLHttpRequest();
ourRequest.open('GET', 'https://spreadsheets.google.com/feeds/cells/1PzTMW6xH5cjLgvLn_LOq25XEbmrCw2MP9C9vvt4rhoM/1/public/full?alt=json')
ourRequest.onload = function() {
var ourData = JSON.parse(ourRequest.responseText);
var TEXT = ourData.feed.entry[2].gs$cell.inputValue;
var IMG = ourData.feed.entry[3].gs$cell.inputValue;
console.log(TEXT);
console.log(IMG);
document.getElementById('testoutput').innerHTML = TEXT;
document.getElementById('backgroundIMG').style.backgroundImage = "url('IMG')";
};
ourRequest.send();
html, body {
height: 100%;
margin: 0;
overflow: hidden; /* Hide scrollbars */
}
div {
text-align: left;
min-height: 100%;
font-family: motiva-sans, sans-serif;
font-weight: 800;
font-size: 15vw;
padding: 15px;
padding-top: 30px;
padding-left: 10%;
}
<html lang="en">
<head>
<link rel="stylesheet" href="https://use.typekit.net/vbl6jef.css">
<link href="https://fonts.googleapis.com/css?family=Open+Sans&display=swap" rel="stylesheet">
<meta charset="utf-8">
<title>Google Sheets - Werkend</title>
</head>
<body>
<div id="backgroundIMG"><div>
<div id="testoutput"></div>
</body>
</html>
I'm working on a HTML document that gets its styling from Google Sheets JSON data. So far it works for setting properties such as backgroundColor.
Right now i'm trying to set the backgroundImage and have set a variable that contains the url:
document.getElementById('backgroundIMG').style.backgroundImage = "url('IMG')";
When I console.log the variable it returns the url just fine. When I place the URL directly into the code above, it works. When I put the variable in the code (like shown above) it won't load the URL.
My limited knowledge stops me from searching the right terms on what is going on here. I have tried reading up on variables but no succes yet.
Can anyone point me in the right direction by either telling me what to read up on or by offering a sollution based on my code below?
It's not using the IMG variable, just IMG as a string, so try:
document.getElementById('backgroundIMG').style.backgroundImage = "url(" + IMG + ")";
Adding a variable to a string:
"Traditional" ways (plus sign is expands a string):
let s = "number: " + num;
let s = 'number: ' + num;
ES6 template literals:
let s = `number: ${num}`
Get more information on these links:
JS Strings
Template literals

Dynamic timed text track for captions on canvas video

I have researched and experimented my brains out on this one. I have built a working application that uses the HTML5 canvas to play videos and interact with users through a web page (a game, sort of). Works like a charm, but I want to add captions to the video to make it more accessible. I don't even seem to be able to get the WebVTT file to load and I've reached the stage of voodoo programming by trying examples from the web and am making no progress. I have tried to distill the application down to its bare minimum here in hopes someone can provide some insight into what I'm doing wrong.
The video plays when I click on the canvas, the "...waiting for cuechange event..." message stays up while it plays, and then it goes to the "video complete ... reload to try again" message when done (kept it simple by requiring a page reload to try the test again), so the basic mechanics seem to be working. It never gets into the "load" function for the text track (never displays "... loaded text track ..."), and the updateSubtitle() function is never invoked. If I insert a trackElement.readyStatus() call, it always returns 0 (unsurprisingly). As a further note, if I add a testStatus.innerHTML = "...loaded metadata..."; statement in the "loadedmetadata" listener, it does get there.
var canvasContext, videoElement, intervalHandle, testStatus, trackElement;
function processFrame() {
canvasContext.drawImage(videoElement, 193, 50, 256, 194);
}
function videoEnded() {
clearInterval(intervalHandle);
testStatus.innerHTML = "video complete ... reload to try again";
}
var count = 0;
function updateSubtitle(event) {
count = count + 1;
testStatus.innerHTML = "count" + count;
}
function clickHandler(event) {
testStatus.innerHTML = "...waiting for cuechange event...";
videoElement.setAttribute("src", "start.ogg");
videoElement.load();
intervalHandle = setInterval(processFrame, 25);
videoElement.play();
}
function init() {
var canvasElement, textTrack;
canvasElement = document.createElement("canvas");
videoElement = document.createElement("video");
videoElement.addEventListener("loadedmetadata", function() {
trackElement = document.createElement("track");
trackElement.kind = "captions";
trackElement.label = "English";
trackElement.srclang = "en";
trackElement.src = "start_en.vtt";
trackElement.addEventListener("load", function() {
testStatus.innerHTML = "... loaded text track ...";
trackElement.mode = "showing";
});
videoElement.appendChild(trackElement);
trackElement.addEventListener("cuechange", updateSubtitle, false);
});
var mainDiv = document.getElementById("arghMainDiv");
canvasElement.setAttribute("id", "mediaScreen");
canvasElement.width = 640;
canvasElement.height = 480;
var firstChild;
if(mainDiv.hasChildNodes()) {
firstChild = mainDiv.firstChild;
mainDiv.insertBefore(canvasElement, firstChild);
} else {
firstChild = mainDiv.appendChild(canvasElement);
}
testStatus = document.createElement("p");
testStatus.setAttribute("id", "testStatus");
mainDiv.insertBefore(testStatus, firstChild);
testStatus.innerHTML = "click on canvas to test";
canvasContext = canvasElement.getContext('2d');
canvasElement.addEventListener("click", clickHandler);
videoElement.addEventListener("ended", videoEnded);
}
#fatalError {
color: red;
}
#arghMainDiv {
text-align: center;
}
#mediaScreen {
border: 5px solid #303030;
margin-left: auto;
margin-right: auto;
display: block;
cursor: default;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Problems With TextTrack Object</title>
<link rel="stylesheet" type="text/css" href="subargh.css">
<script src="subargh.js"></script>
</head>
<body onload="init()">
<div id="arghMainDiv">
</div>
</body>
</html>
If you want the video and WebVTT files I'm using (just a few seconds long), they are here and here (respectively). I should also mention that if I play the video using VLC, that it recognizes and plays the .vtt file as subtitles properly on the video (so it appears to be well-formed). I am running my tests on Firefox 57.0.4 (64-bit) on a Windows 7 system if that makes any difference (but I am under the impression that Firefox is mostly fixed where Timed Text Tracks are concerned now).

How to explain these lines of JavaScript?

Both light and order are arrays containing states with the period of time they are displayed.
However I'm not too sure about what Index does or 'sId'. could someone please explain these? The code changes the sequence of a traffic light. The code works however I wanted to know what lightIndex does, as when I change it it doesn't work.
<!DOCTYPE html>
<html>
<style type="text/css">
.light {
height: 30px;
width: 30px;
border-style: solid;
border-width: 2px;
border-radius: 25px;
}
.lightRed {
background-color: red;
}
.lightYellow {
background-color: yellow;
}
.lightGreen {
background-color: green;
}
</style>
<body>
<div id="trafficLight">
<div>Click to Start and Stop</div>
<div class="light" id="Red"></div>
<div class="light" id="Yellow"></div>
<div class="light" id="Green"></div>
</div>
<button type="button" onclick="changeState()">Change Lights</button>
<button type="button" onclick="changeState()">automatic</button>
<script>
var changeState = (function () {
var state = 0,
lights = ["Red", "Yellow", "Green"],
lightsLength = lights.length,
order = [
[7000, "Red"],
[2000, "Red", "Yellow"],
[7000, "Green"],
[2000, "Yellow"]
],
orderLength = order.length,
lightIndex,
orderIndex,
sId;
return function (stop) {
if (stop) {
clearTimeout(sId);
return;
}
var light,
lampDOM;
for (lightIndex = 0; lightIndex < lightsLength; lightIndex += 1) {
light = lights[lightIndex];
lightDOM = document.getElementById(light);
if (order[state].indexOf(light) !== -1) {
lightDOM.classList.add("light" + light);
} else {
lightDOM.classList.remove("light" + light);
}
}
sId = setTimeout(changeState, order[state][0]);
state += 1;
if (state >= orderLength) {
state = 0;
}
};
}());
document.querySelector('change Lights', 'automatic').addEventListener("click", (function () {
var state = false;
return function () {
changeState(state);
state = !state;
};
}()), false);
</script>
</body>
</html>
lightIndex and sId are both just variable names created by whoever wrote the code. They don't 'mean' anything inherently -- the creator of the code could have chosen whatever variable names they wanted. However, in your code, both of these variables have uses that are fairly self-evident from their names.
lightIndex is an integer (between 0 and 2), which is used as an index of the array lights, so that the current light (light) can access the relevant colour with light = lights[lightIndex];. Presumably lights is set up like var lights = ['green', 'orange', 'red']. So, for example, light = lights[lightIndex] becomes light = lights[1], making light become equivalent to orange.
sId is a time-delayed function (setTimeout(changeState, order[state][0]);). setTimeout() takes two parameters -- a function to execute, and a time delay in milliseconds. In this example, order[state][0] will be equivalent to something like 1000 (one second), and changeState() is the function to execute. Essentially, every one second, change the state of the light (to a different colour).
I don't know why you'd try to change lightIndex, but if you want to reverse the direction of the lights changing, you need to reverse the for loop:
for (lightIndex = 0; lightIndex < lightsLength; lightIndex += 1) {
Becomes:
for (lightIndex = lightsLength; lightIndex > 0; lightIndex -= 1) {
If you want to change the speed, you need to change order[state][0]. As you don't show the order variable's code, you'll need to work out how to change that yourself.
Hope this helps!

Panel tranparency firefox addon

I'm programming a firefox addon and using a panel to display info on a video, everything works fine althought I can't make the panel transparent. I define the panel styling in the html file as follow:
<html>
<head>
<meta charset="utf-8" />
<style type="text/css" media="all">
html
{
opacity:0.1;
border-style:none;
resize:none;
}
textarea
{
background-color:transparent;
resize: none;
border-style:none;
}
</style>
</head>
<body>
<textarea id="text" readonly=true rows="3" cols="60"></textarea>
</panel>
</body>
</html>
Except the panel is not transparent only the text area is. I tried with:
opacity:1 for textarea
It doesn't work either way. What am I doing wrong? Is this even possible?
From what I understand :
html
{
opacity:0.1;
border-style:none;
resize:none;
}
only applies to the panel content not to the panel itself. I found a post on this subject but it is outdated since the sdk/panel.js mentionned in the post is not the same anymore.
Anyway I tried downloading the panel.js and replacing the current one, but it doesn't seem to affect the panel I display at all. The panel is still white and the border-radius option does not work either. (I should say that I replaced all the "./" with "sdk/" as mentionned in that post).
Ok here is a pure addon sdk solution:
let myPanel = Panel({
width: 180,
height: 180,
contentURL: 'data:text/html,<textarea style="width:120px; height:80px;">this is my textarea</textarea>'
})
let { getActiveView }=require("sdk/view/core");
getActiveView(myPanel).setAttribute("noautohide", true);
getActiveView(myPanel).setAttribute("level", 'top');
getActiveView(myPanel).setAttribute("style", 'background-color:rgba(0, 0, 0, 0.2);');
You can't style the panel provided in the SDK, only the content but you can definitely follow the procedure you mention and provide your modified panel.
I had to solve this same problem today (transparent panel in SDK). The trick is getting at the anonymous content:
function makePanelTransparent() {
// Get the panel element in the XUL DOM and make its background transparent.
const { getActiveView } = require('sdk/view/core');
const el = getActiveView(panel);
el.style.background = 'rgba(0,0,0,0)';
// Go up the XUL DOM till you hit the Document (nodeType 9).
let parentNode = el;
while (parentNode !== null && parentNode.nodeType !== 9) {
parentNode = parentNode.parentNode;
}
if (!parentNode) {
console.error('unable to find the document parent; giving up');
return;
}
// Now that we've found it, call the document a document.
const xulDocument = parentNode;
// Use the document pointer to access and style 'anonymous' content.
const xulContainer = xulDocument.getAnonymousElementByAttribute(el, 'class', 'panel-arrowcontent')
xulContainer.style.background = 'rgba(0,0,0,0)';
xulContainer.style.boxShadow = 'none';
}
This works for me. Hope it helps some other person in the next 1-5 years ;-)
I found out that you could create a panel with transparency this way:
var win = Services.wm.getMostRecentWindow('navigator:browser');
var panel = win.document.createElement('panel');
var screen = Services.appShell.hiddenDOMWindow.screen;
var props = {
noautohide: true,
noautofocus: false,
level: 'top',
style: 'padding:15px; margin:0; width:' + screen.width + 'px; height:' + screen.height + 'px; background-color:rgba(180,180,180,.5);'
}
for (var p in props) {
panel.setAttribute(p, props[p]);
}
win.document.querySelector('#mainPopupSet').appendChild(panel);
panel.addEventListener('dblclick', function () {
panel.parentNode.removeChild(panel)
}, false);
panel.openPopup(null, 'overlap', screen.availLeft, screen.availTop);
To embed an iframe remember to set the path to your ".html" as:
"resource://"id of your addon"-at-jetpack/data/custom_panel.html".
Here is my code :
var win = Services.wm.getMostRecentWindow('navigator:browser');
var panel = win.document.createElement('panel');
var screen = Services.appShell.hiddenDOMWindow.screen;
var props = {
noautohide: true,
noautofocus: false,
backdrag: true,
level: 'top',
style: 'padding:10px; margin:0; width:530px; height:90px; background-color:rgba(180,180,180,.5);'
}
for (var p in props) {
panel.setAttribute(p, props[p]);
}
var iframe = win.document.createElement('iframe');
iframe.setAttribute('src','resource://"id of your addon"-at-jetpack/data/custom_panel.html');
panel.appendChild(iframe);
win.document.querySelector('#mainPopupSet').appendChild(panel);
panel.addEventListener('dblclick', function () {
panel.parentNode.removeChild(panel)
}, false);
panel.openPopup(null, 'overlap', screen.availLeft+screen.width/2-256, screen.availTop+760);
Thanks Noitidart for the help.

Drag and Drop Jquery function not working in site

I'm having a problem getting my code to work when it's incororated into a live site. The fiddle works just fine, but when I include the identical code in a webpage, I can't get the function to load/work at all.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Drag and Drop Assignment</title>
<!doctype html>
<link rel="stylesheet" href="styles/style1.css"/>
<style>
.drop{
float: left;
width: 350px;
height: 400px;
border: 3px solid blue;
background-image: url("http://debsiepalmer.com/images/tardis 2.jpg");
background-repeat: no-repeat;
background-size: cover;
}
#right{float: left;
width: 350px;
height: 400px;
border: 3px solid red;
}
</style>
<script src="draganddrop.js" ></script>
<script src="http://code.jquery.com/jquery-2.0.2.js" ></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js" ></script>
<script type="text/javascript">
$ (init);
function image(id, image1) {
this.id = id;
this.image1 = image1;
}
$('#deal').click(function () {dealAll(
dealCard(randomCard()));
});
$(function() {
$( "#draggable" ).draggable({ containment: "#left"});
});
function init() {
$('.drop').droppable( {
drop: handleDropEvent
} );
$("img").draggable();
}
// global variables
var cardsInDeck = new Array();
var numberOfCardsInDeck = 15;
cardsInDeck[0] = "Ace";
cardsInDeck[1] = "Grace";
cardsInDeck[2] = "Susan";
cardsInDeck[3] = "Ian";
cardsInDeck[4] = "Barbara";
cardsInDeck[5] = "Brigadier";
cardsInDeck[6] = "Romana I";
cardsInDeck[7] = "K9";
cardsInDeck[8] = "Tegan";
cardsInDeck[9] = "Jamie";
cardsInDeck[10] = "Sarah Jane";
cardsInDeck[11] = "Jo";
cardsInDeck[12] = "Romana II";
cardsInDeck[13] = "Yates";
cardsInDeck[14] = "Leela";
var cardsDealt = new Array();
function dealAll(){
var z=0;
for (z=0;z<5;z++) {
cardsDealt[z] = new Image(z,dealCard(randomCard()));
}
}
function dealCard(i) {
if (numberOfCardsInDeck == 0) return false;
var $img = new Image();
$img.src = "images/Companions/" + cardsInDeck[i] + ".jpg";
// Here I set the ID of the object
$img.id=cardsInDeck[i];
$img.class='drag';
document.body.appendChild($img);
$('#'+$img.id).draggable();
removeCard(i);
return $img;
}
// deal randomly - works
function randomCard() {
return Math.floor(Math.random() * numberOfCardsInDeck);
}
function removeCard(c)
{
for (j=c; j <= numberOfCardsInDeck - 2; j++)
{
cardsInDeck[j] = cardsInDeck[j+1];
}
numberOfCardsInDeck--;
numberOfCardsInDeck--;
numberOfCardsInDeck--;
}
function handleDropEvent( event, ui ) {
alert("Fantastic! You chose " + ui.draggable.attr("id") + " to be your companion.");
// Here I want the id of the dropped object
}
</script>
</head>
<body>
<div id="container" div style="width:750px; margin:0 auto;">
<div id="page_content" style="left: 0px; top: 0px; width: 750px" class="auto-style8">
<!--Begin Assignment 10 --->
<div id="left" class="drop">
<img id="tardis" ></img>
</div>
<input type="button" value="Get Companions" id="deal" />
<div id="content" style="left: 0px; top: 0px; width: 750px">
</div>
</div>
</div>
</body>
</html>
It's supposed to generate 5 images, one of which can be selected to be dropped onto the target and generate an alert with the id of the image being dropped. Like I said, it works just fine in the fiddle - and the code is identical on the web page, so I don't understand what I'm doing wrong.
fiddle: http://jsfiddle.net/reaglin/FUvT8/6/
I ordered some code...and for me it worked
// global variables
var cardsInDeck = [],
numberOfCardsInDeck = 5;
cardsInDeck[0] = "Ace";
cardsInDeck[1] = "Grace";
cardsInDeck[2] = "Susan";
cardsInDeck[3] = "Ian";
cardsInDeck[4] = "Barbara";
cardsInDeck[5] = "Brigadier";
cardsInDeck[6] = "Romana I";
cardsInDeck[7] = "K9";
cardsInDeck[8] = "Tegan";
cardsInDeck[9] = "Jamie";
cardsInDeck[10] = "Sarah Jane";
cardsInDeck[11] = "Jo";
cardsInDeck[12] = "Romana II";
cardsInDeck[13] = "Yates";
cardsInDeck[14] = "Leela";
//load "init" when document it's ready
$(document).on('ready',init);
function init() {
$( "#draggable" ).draggable({ containment: "#left"});
$('.drop').droppable( {drop: handleDropEvent});
}
$('#deal').click(function () {
dealAll();
});
$('#reset-pictures').click(function(){
$('img.drag').remove();
numberOfCardsInDeck = 5;
});
// deal 5 cards at once - works
function dealAll(){
// 5 cards max, no repeat cards
while(numberOfCardsInDeck){
var rand = randomCard();
dealCard(rand);
}
}
//deal cards - works
function dealCard(i) {
//create id, remove space id
var id_picture = (cardsInDeck[i] +'-'+i).replace(/\s/g, '');
//validate not exist image
if (!!$('img#'+id_picture).length) {
return;
}
var $img = $('<img/>', { src : "http://debsiepalmer.com/images/companions/" + cardsInDeck[i] + ".jpg", id : id_picture, class : 'drag', 'data-info': cardsInDeck[i]
})
$('body').append($img);
$('img.drag').draggable();
numberOfCardsInDeck--;
}
// deal randomly - works
function randomCard() {
return Math.floor(Math.random() * cardsInDeck.length);
}
// this is what to do when card drops in tardis
function handleDropEvent( event, ui ) {
alert(ui.draggable.attr("data-info"));
}
DEMO
JSFinddle
Are you linking to JQuery correctly in the live version? Sometimes when moving from a development area to a live system the references mess up, you can find out if a reference is working or not by viewing the source code and entering in the link into the URL.
This is how you fix it: Take all the javascript (from $ (init) to the alert()) and place it at the bottom of the loaded page, inside the body, after all the elements. This ensures that the javascript knows what named elements you are talking about.
I would like to emphasise that this is not a tip for writing good javascript. The problem arises because it's bad javascript to begin with. Well written pages do not rely on the position of the code within the page, rather the opposite in fact.
Postscript: I literally did the following: I came here after googling "drag and drop"; I didn't fully read the actual question; I went to the jfiddle; I copied all the code for my own purposes; I couldn't get it to work; I fixed it (just trial and error really); I fixed the bug which is still present even on the jfiddle page; and then I came back here to find out what the original query had been!
The other bug is the fact that you can't drag the images of "Romana I", "Romana II" and "Sarah Jane". As the code makes the array values the id of the image elements, maybe others can instantly spot what causes that problem.

Categories

Resources