Autor Tema: JavaScript. Crear sumas y restas aprender niños aplicación didáctico educativa  (Leído 8532 veces)

pedro,,

  • Moderador Global
  • Experto
  • *******
  • APR2.COM
  • Mensajes: 1292
    • Ver Perfil
Hola.

Voy  a dejar un pequeño código que he elaborado, y consiste en generar sumas y restas(sin llevadas) de una sola cifra. Lo hice básicamente para que mis hijos practiquen en su aprendizaje. Es algo muy básico pero me gustaría que le echasen un ojo para ver que puedo mejorar. La idea es mejorarlo tomando tiempos, guardando datos, etc..

Código: [Seleccionar]
<!DOCTYPE html>
<html>
<head>
<title>Juego Sumas</title>
<meta charset="utf-8" />
<style>
*{font-family: arial}
body{
background: #FFE4C4;
}
#contenedor{
width: 800px;
margin: 10px auto;
padding: 1%;
text-align: center;
}

#contOperacion{
margin-top: 5px;
}
#contOperacion div{
float: left;
}
#propuestaResultado{
outline: 0px;
border: solid 1px #FFFFFF;
text-align: center;
font-size: 150px;
border-radius: 11px;
width: 222px;
}
#operacion{
font-size: 150px;
width: 60%;
}
#propResultado{
width: 40%;
}
#mensaje{
font-size: 150px;
width: 100%;
height: 200px;
}
#contRadios {
width: 100%;
font-size: 44px;
padding: 5px;
}
.boton{
color: #FFFFFF;
border: solid 1px #FFFFFF;
border-radius: 40px;
background: #5F9EA0;

}
#botonResultado, #botonSiguiente{
outline: 0px;
font-size: 77px;
text-align: center;
padding:15px;
margin-top: 5px;
box-shadow: 0px 3px 15px 0px rgb(0, 105, 202);
transition: all 0.10s ease-in-out;
position:relative;
cursor: pointer;
}
#botonResultado:active, #botonSiguiente:active{
top:5px;
box-shadow: 0px 1px 0px 0px rgb(0, 105, 202)
}
</style>
<script>
'use strict';
window.onload = function(){
crearSuma();
var nodoRadioSuma = document.getElementById('suma');
var nodoTipoOperacion = document.getElementsByName('tipoOperacion');
var btnSiguiente = document.getElementById('botonSiguiente');
var btnComprobar = document.getElementById('botonResultado');

// Evento que se ejecuta al hacer click en el botón "Comprobar".
btnComprobar.addEventListener('click', comprobarChecked);

/* Evento para decidir como se actuará al hacer click en el botón "Siguiente"
dependiendo de la opción que este marcada en los botones radio.   */
btnSiguiente.addEventListener('click', function(){
if(nodoRadioSuma.checked){
crearSuma();
}else{
crearResta();
}
});

// Evento que recoge cualquier tipo de pulsación de teclado y comprueba si se ha pulsado la tecla intro.
document.addEventListener('keypress', function(codTecla){
var foco = document.activeElement.id;
if(codTecla.keyCode==13 & foco=='propuestaResultado'){comprobarChecked();}
});

// Evento que se producirá al hacer click en la opción "suma" del botón radio. 
nodoTipoOperacion[0].addEventListener('click', crearSuma);

// Evento que se producirá al hacer click en la opción "suma" del botón radio.
nodoTipoOperacion[1].addEventListener('click', crearResta);

/* Función que usan dos de los eventos anteriores para saber que opción está marcada en el botón radio y
dependiendo de esto, invocar una función determinada.*/
function comprobarChecked(){
if(nodoRadioSuma.checked){
comprobarResultado('suma');
}else{
comprobarResultado('resta');
}
}
}

/**
  * Función que recibe un parámetro booleano, que se encarga del diseño de algunos elementos
  * según si se ha cometido un error o no en la respuesta dada, también
  * indicará que elemento debe de coger el foco después de la comprobación.
*/
function apariencia(hayError){
if(hayError){
document.getElementById('propuestaResultado').disabled = false;
document.getElementById('propuestaResultado').focus();
document.getElementById('mensaje').innerHTML = '';
document.getElementById('propuestaResultado').value = '';
document.getElementById('botonSiguiente').disabled = true;
} else {
document.getElementById('botonSiguiente').disabled = false;
document.getElementById('botonSiguiente').focus();
document.getElementById('propuestaResultado').disabled = true;
}

}

/**
  *Función que crea dos números aleatorios entre el 0 y el 9 que formará la operación(suma).
  */
function crearSuma(){
var sumando = [];
apariencia(true);
sumando[0] = Math.floor(Math.random()*(9-1))+1;
sumando[1] = Math.floor(Math.random()*(9-1))+1;
document.getElementById('operacion').innerHTML = sumando[0] + ' + ' + sumando[1] + ' = ';
}

/**
  * Función que crea dos números aleatorios, el primero entre el 0 y el 9, y el segundo entre 0 y
  * el número anterior, que formará la operación(resta).
  */
function crearResta(){
var minuendo = 0;
var sustraendo = 0;
apariencia(true);
minuendo = Math.floor(Math.random()*(10-1))+1;
sustraendo = Math.floor(Math.random()*(minuendo-1))+1;
document.getElementById('operacion').innerHTML = minuendo + ' - ' + sustraendo + ' = ';
}

/**
  * Función que recibe un parámetro que contiene una cadena de texto, 'suma' o 'resta',
  * a partir de ese parámetro comprobará el resultado de la operación creada anteriormente,
  * dependiendo de si es una resta o una suma y acabará mostrando en pantalla 'erroneo' o
  * 'correcto' dependiendo del resultado.
  */
function comprobarResultado(sumaResta){
var msgBienMal = document.getElementById('mensaje');
var resultadoPropuesto = Number(document.getElementById('propuestaResultado').value);
var operacionPropuesta = document.getElementById('operacion').textContent;
if(sumaResta=='suma'){
var resultado = Number(operacionPropuesta.slice(0,1)) + Number(operacionPropuesta.slice(4,5));
}else{
var resultado = Number(operacionPropuesta.slice(0,1)) - Number(operacionPropuesta.slice(4,5));
}
if(resultado==resultadoPropuesto){
msgBienMal.style.color = 'green';
msgBienMal.innerHTML = '¡Correcto!';
apariencia(false);
}else{
msgBienMal.style.color = 'red';
msgBienMal.innerHTML = '¡Incorrecto!';
}
}

</script>
</head>
<body>
<div id="contenedor">
<div id="contRadios" class="boton">
<label ><input type="radio" name="tipoOperacion" id="suma" checked="checked"/>Suma</label>
<label><input type="radio" name="tipoOperacion" id="resta"/>Resta</label>
</div>
<div id="contOperacion">
<div id="operacion"></div>
<div id="propResultado"><input type="text" id="propuestaResultado"/></div>
</div>
<div id="contBotones" >
<button class="boton" id="botonResultado" >Comprobar</button>
<button id="botonSiguiente" class="boton" >Siguiente</button>
</div>
<div id="mensaje"></div>
</div>
</body>
</html>


Saludos. ;D
« Última modificación: 15 de Septiembre 2016, 10:05 por Ogramar »

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Buenas Pedro sobre el código en sí pocos comentarios, me ha parecido un código bien ordenado, comentado, bien estructurado, etc. Me ha llamado la atención que utilices 'use strict'; ya que es poco habitual ver esto (los programadores prefieren no complicarse). Creo que se usa poco también pensando en evitar posibles problemas con navegadores.

Sobre aspectos estéticos y de funcionamiento al visualizarlo me ha parecido que el diseño se podría mejorar un poco para que se vea más claro (y así incidir más en el aspecto "educativo"), en concreto me refiero a:

Dejar más separación horizontal entre las palabras suma y resta

Hacer más grandes los botones de radio para elección de la opción suma o resta

Dejar más margen en horizontal entre los botones comprobar y siguiente

Dejar más margen en vertical entre las tres partes (suma/resta, la operación en sí y los botones).

Y ya puestos, si el fin es educativo, en vez de ¡Incorrecto! que parece un poco agresivo para un niño, quizás sería más amable algo como "No has acertado", o "Inténtalo otra vez!" y quizás en vez de ¡correcto! un niño entienda mejor ¡Muy bien!

Otra cosa: supongo que el botón siguiente solo lo habilitas cuando el resultado ha sido correcto. Pero para hacer eso patente pienso que quedaría mejor cambiarlo de color (digamos ponerle un gris de modo que se vea que está desactivado) y devolverle el color normal cuando esté operativo. A mí me ha costado un poco entender que solo podía pulsar siguiente después de haber acertado, pensaba que el botón no respondía.

La idea me parece muy buena, me imagino que ya hay aplicaciones educativas pero usando imaginación puedes hacer algo único o adaptado especialmente a lo que tú quieras (como has comentado podrías ir añadiéndole funcionalidades si quisieras)

Salu2

pedro,,

  • Moderador Global
  • Experto
  • *******
  • APR2.COM
  • Mensajes: 1292
    • Ver Perfil
Hola Ogramar.

Lo primero darte las gracias por tomarte un tiempo para revisar el código y tus comentarios.

Sobre 'use strict'; creo recordar que en el curso de JavaScript se recomienda su uso como una buena práctica, por eso lo suelo usar.

Aquí dejo el código adaptado un poco a los comentarios que me hiciste.

Código: [Seleccionar]
<!DOCTYPE html>
<html>
<head>
<title>Juego Sumas</title>
<meta charset="utf-8" />
<style>
*{font-family: arial}
body{
background: #FFE4C4;
}
#contenedor{
width: 800px;
margin: 10px auto;
padding: 1%;
text-align: center;
}

#contOperacion{
margin-top: 20px;
}
#contOperacion div{
float: left;
}
#propuestaResultado{
outline: 0px;
border: solid 1px #FFFFFF;
text-align: center;
font-size: 150px;
border-radius: 11px;
width: 222px;
}
#operacion{
font-size: 150px;
width: 60%;
}
#propResultado{
width: 40%;
}
#mensaje{
font-size: 100px;
width: 100%;
height: 200px;
}
#contRadios {
width: 100%;
font-size: 44px;
padding: 5px;
}
#contRadios label{
margin: 0 20px 0 20px;
}
.boton{
color: #FFFFFF;
border: solid 1px #FFFFFF;
border-radius: 40px;
background: #5F9EA0;
}
#botonResultado, #botonSiguiente {
outline: 0px;
font-size: 66px;
text-align: center;
padding:15px;
margin: 20px;
box-shadow: 0px 3px 15px 0px #1E90FF;
transition: all 0.10s ease-in-out;
position:relative;
}
#botonResultado {
cursor: pointer;
}
#botonSiguiente {
opacity: 0.5;
cursor: not-allowed;

}
#botonResultado:active, #botonSiguiente:active {
top:5px;
box-shadow: 0px 1px 0px 0px #1E90FF;
}
</style>
<script>
'use strict';
window.onload = function(){
crearSuma();
var nodoRadioSuma = document.getElementById('suma');
var nodoTipoOperacion = document.getElementsByName('tipoOperacion');
var btnSiguiente = document.getElementById('botonSiguiente');
var btnComprobar = document.getElementById('botonResultado');

// Evento que se ejecuta al hacer click en el botón "Comprobar".
btnComprobar.addEventListener('click', comprobarChecked);

/* Evento para decidir como se actuará al hacer click en el botón "Siguiente"
dependiendo de la opción que este marcada en los botones radio.   */
btnSiguiente.addEventListener('click', function(){
if(nodoRadioSuma.checked){
crearSuma();
}else{
crearResta();
}
});
// Evento que recoge cualquier tipo de pulsación de teclado y comprueba si se ha pulsado la tecla intro.
document.addEventListener('keypress', function(codTecla){
var foco = document.activeElement.id;
if(codTecla.keyCode==13 & foco=='propuestaResultado'){comprobarChecked();}
});

// Evento que se producirá al hacer click en la opción "suma" del botón radio. 
nodoTipoOperacion[0].addEventListener('click', crearSuma);

// Evento que se producirá al hacer click en la opción "suma" del botón radio.
nodoTipoOperacion[1].addEventListener('click', crearResta);

/* Función que usan dos de los eventos anteriores para saber que opción está marcada en el botón radio y
dependiendo de esto, invocar una función determinada.*/
function comprobarChecked(){
if(nodoRadioSuma.checked){
comprobarResultado('suma');
}else{
comprobarResultado('resta');
}
}
}

/**
  * Función que recibe un parámetro booleano, que se encarga del diseño de algunos elementos
  * según si se ha cometido un error o no en la respuesta dada, también
  * indicará que elemento debe de coger el foco después de la comprobación.
*/
function apariencia(hayError){
var btnSiguiente = document.getElementById('botonSiguiente');
var resultadoPropuesto =  document.getElementById('propuestaResultado');
if(hayError){
resultadoPropuesto.disabled = false;
resultadoPropuesto.focus();
document.getElementById('mensaje').innerHTML = '';
resultadoPropuesto.value = '';
btnSiguiente.style.opacity = '0.5';
btnSiguiente.style.cursor = 'not-allowed';
btnSiguiente.disabled = true;
} else {
resultadoPropuesto.disabled = true;
btnSiguiente.style.opacity = '1';
btnSiguiente.style.cursor = 'pointer';
btnSiguiente.disabled = false;
btnSiguiente.focus();
}
btnSiguiente.visibility = 'hidden';
}

/**
  *Función que crea dos números aleatorios entre el 0 y el 9 que formará la operación(suma).
  */
function crearSuma(){
document.getElementById('botonSiguiente').visibility='hidden';
var sumando = [];
apariencia(true);
sumando[0] = Math.floor(Math.random()*(9-1))+1;
sumando[1] = Math.floor(Math.random()*(9-1))+1;
document.getElementById('operacion').innerHTML = sumando[0] + ' + ' + sumando[1] + ' = ';
}

/**
  * Función que crea dos números aleatorios, el primero entre el 0 y el 9, y el segundo entre 0 y
  * el número anterior, que formará la operación(resta).
  */
function crearResta(){
var minuendo = 0;
var sustraendo = 0;
apariencia(true);
minuendo = Math.floor(Math.random()*(10-1))+1;
sustraendo = Math.floor(Math.random()*(minuendo-1))+1;
document.getElementById('operacion').innerHTML = minuendo + ' - ' + sustraendo + ' = ';
}

/**
  * Función que recibe un parámetro que contiene una cadena de texto, 'suma' o 'resta',
  * a partir de ese parámetro comprobará el resultado de la operación creada anteriormente,
  * dependiendo de si es una resta o una suma y acabará mostrando en pantalla 'erroneo' o
  * 'correcto' dependiendo del resultado.
  */
function comprobarResultado(sumaResta){
var msgBienMal = document.getElementById('mensaje');
var resultadoPropuesto = Number(document.getElementById('propuestaResultado').value);
var operacionPropuesta = document.getElementById('operacion').textContent;
if(sumaResta=='suma'){
var resultado = Number(operacionPropuesta.slice(0,1)) + Number(operacionPropuesta.slice(4,5));
}else{
var resultado = Number(operacionPropuesta.slice(0,1)) - Number(operacionPropuesta.slice(4,5));
}
if(resultado==resultadoPropuesto){
msgBienMal.style.color = 'green';
msgBienMal.innerHTML = '¡Muy bien!';
apariencia(false);
}else{
msgBienMal.style.color = 'red';
msgBienMal.innerHTML = '!Ups¡ prueba otra vez';
}
}

</script>
</head>
<body>
<div id="contenedor">
<div id="contRadios" class="boton">
<label><input type="radio" name="tipoOperacion" id="suma" checked="checked"/>Suma</label>
<label><input type="radio" name="tipoOperacion" id="resta"/>Resta</label>
</div>
<div id="contOperacion">
<div id="operacion"></div>
<div id="propResultado"><input type="text" id="propuestaResultado"/></div>
</div>
<div id="contBotones" >
<button class="boton" id="botonResultado" >Comprobar</button>
<button id="botonSiguiente" class="boton" >Siguiente</button>
</div>
<div id="mensaje"></div>
</div>
</body>
</html>

Aún así, aunque se vea la pantalla muy vacía, es porque lo adaptaré para que tenga un menú vertical en la izquierda y un encabezado que contendrá un título, y de momento no sé si le añadiré algo mas.

Dejo el código del menú vertical también, por si a alguien le sirve.

Código: [Seleccionar]
<!DOCTYPE html>
<html lang="es">
<head>
<title>Menú</title>
<meta name="author" content="Pedro Paredes" />
<meta charset="utf-8" />
</head>
<style>
*{
margin: 0;
padding: 0;
}
body {
background: #FFE4C4;
}

#menuIzq{
width: 280px;
height: 550px;
}
.flotaLeft{
float: left;
}

.borraFlujo{
clear: both;
}
#menuIzq label{
display: block;
font-size: 33px;
}
.cajaTexto {
border: solid 1px #5F9EA0;
font-size: 16px;
width:150px;
height:150px;
background: #FFFFFF;
color: #5F9EA0;
visibility: hidden;
position: absolute;
}
.menu, .cajaTexto{
border-radius: 5px;
padding: 5px;
cursor: pointer;
}
.menu {
color: #FFFFFF;
background: #5F9EA0;
border: solid 1px #FFFFFF;
}
input[type="radio"]{
display: none;
}
</style>
<script>
'use strict';
window.onload = function(){
var nodoCajaTexto = document.getElementsByClassName('cajaTexto');
var nodosMenu = document.getElementsByName('tipoOperacion');
for (var i=0; i<nodosMenu.length; i++){
nodosMenu[i].parentNode.addEventListener('mouseover', muestraCaja.bind(this, i));
nodosMenu[i].parentNode.addEventListener('mouseout', muestraCaja.bind(this, i));
}
function muestraCaja(i, ev){
if(ev.type == 'mouseover'){
nodoCajaTexto[i].style.visibility = 'visible';
nodoCajaTexto[i].style.top = nodosMenu[i].parentNode.offsetTop + 'px';
nodoCajaTexto[i].style.left = nodosMenu[i].parentNode.offsetWidth + 'px';
nodosMenu[i].parentNode.style.backgroundColor = '#FFFFFF';
nodosMenu[i].parentNode.style.color = '#5F9EA0';
}else{
nodoCajaTexto[i].style.visibility = 'hidden';
nodosMenu[i].parentNode.style.backgroundColor = '#5F9EA0';
nodosMenu[i].parentNode.style.color = '#FFFFFF';
}
}
}
</script>
<body>
<div id="menuIzq" class="flotaLeft">
<label id="plus" class="menu">
<input type="radio" name="tipoOperacion" value="suma" checked="checked"/>Sumas sin llevadas
<div class="cajaTexto">Explicación</div>
</label>
<label id="caja2" class="menu">
<input type="radio" name="tipoOperacion" value="sumaN2"/>Sumas con llevadas
<div class="cajaTexto">Explicación</div>
</label>
<label id="caja3" class="menu">
<input type="radio" name="tipoOperacion" value="resta"/>Restas sin llevadas
<div class="cajaTexto">Explicación</div>
</label>
<label id ="caja4" class="menu">
<input type="radio" name="tipoOperacion" value="restaN2"/>Restas con llevadas
<div class="cajaTexto">Explicación</div>
</label>
<label id ="caja4" class="menu">
<input type="radio" name="tipoOperacion" value="restaN2"/>Tablas Multiplicar
<div class="cajaTexto">Explicación</div>
</label>
<label id ="caja4" class="menu">
<input type="radio" name="tipoOperacion" value="restaN2"/>Multiplicaciones
<div class="cajaTexto">Explicación</div>
</label>
<label id ="caja4" class="menu">
<input type="radio" name="tipoOperacion" value="restaN2"/>Divisiones
<div class="cajaTexto">Explicación</div>
</label>
</div>
</body>
</html>

Saludos. ;D

Ogramar

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2662
    • Ver Perfil
Buenas Pedro, sobre el strict mode efectivamente se supone que obliga a seguir algunas formas de programación más adecuadas, sin embargo también presenta algunos problemas y creo que muchos programadores prefieren no usarlo, pero depende de cada programador. A veces simplemente se trata de problemas como que usar strict mode te genera problemas con jQuery y la solución que se adopta es eliminar el strict mode y punto.

Veo que has aceptado algunas propuestas, un halago para mí. Ahora lo veo (yo al menos) mucho mejor.

Gracias por compartir el código (incluido el del menú vertical), lo veo bien programado y útil, seguro que algún padre o madre ya lo estará probando por ahí  :D

Salu2

pedro,,

  • Moderador Global
  • Experto
  • *******
  • APR2.COM
  • Mensajes: 1292
    • Ver Perfil
Hola, otra vez.

Lo del strict mode lo tendré en cuenta de aquí en adelante.

Cuando alguien tiene razón hay que dársela, y tus consejos se aprecian a la vista enseguida, por eso los apliqué.

He aumentado un poco más el código, en este caso la parte de las sumas y resta no aparecerán en el código para que no se vea tan extenso. He añadido el menú vertical y una opción que es 'Contar' y trata de contar objetos, esta vez lo solucioné con el uso de canvas.

Código: [Seleccionar]
<!DOCTYPE html>
<html lang="es">
<head>
<title>Aprendemos?</title>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="0001.css">
<style>
*{
margin: 0;
padding: 0;
}
body {
background: #FFE4C4;
}
#encabezado{
width: 100%;
height: 70px;
}
#menuIzq {
width: 280px;
height: 550px;
}
.flotaLeft{
float: left;
}
.borraFlujo{
clear: both;
}
#menuIzq label{
display: block;
font-size: 33px;
}
.cajaTexto {
border: solid 1px #5F9EA0;
font-size: 22px;
width: 250px;
background: #FFFFFF;
color: #5F9EA0;
visibility: hidden;
position: absolute;
z-index: 10;
}
.menu, .cajaTexto{
border-radius: 5px;
padding: 5px;
cursor: pointer;
}
.menu {
color: #FFFFFF;
background: #5F9EA0;
border: solid 1px #FFFFFF;
}
input[type="radio"]{
display: none;
}
#menuDcha {
float: right;
width: 240px;
height: 550px;
}
#contenedor {
border: dashed 5px #33CCFF;
background-image: url('cuadricula0001.png');
background-repeat: repeat;
width: 790px;
height: 520px;
box-shadow: 0 0 30px #33CCFF;
padding: 15px;
text-align: center;
z-index: 30;
}
#operacion {
font-size: 125px;
height: 200px;
width: 460px;
}
#propResultado{
width: 40%;
}
#propuestaResultado{
clear: both;
outline: 0px;
border: solid 1px #FFFFFF;
background-color: transparent;
text-align: center;
font-size: 150px;
border-radius: 11px;
width: 222px;
margin-right: 15px;
}
#botonResultado, #botonSiguiente {
outline: 0px;
font-size: 66px;
text-align: center;
padding:15px;
margin:20px;
box-shadow: 0px 3px 15px 0px #1E90FF;
transition: all 0.10s ease-in-out;
color: #FFFFFF;
border: solid 1px #FFFFFF;
border-radius: 40px;
background: #5F9EA0;
position: relative;
}
#botonResultado {
cursor: pointer;
}
#botonSiguiente {
opacity: 0.5;
cursor: not-allowed;
}
#botonResultado:active, #botonSiguiente:active{
top:5px;
box-shadow: 0px 1px 0px 0px #1E90FF;
}
#mensaje {
font-size: 100px;
width: 100%;
height: 200px;
}
#pie {
width: 100%;
height: 30px;
}
.ocultaContenedor{
visibility: hidden;
}
</style>
<script>
window.onload = function(){
var btnSiguiente = document.getElementById('botonSiguiente');
var btnComprobar = document.getElementById('botonResultado');
var nodoCajaTexto = document.getElementsByClassName('cajaTexto');
var nodosMenu = document.getElementsByName('tipoOperacion');
btnComprobar.addEventListener('click', comprobarChecked);
btnSiguiente.addEventListener('click', operacionElegida);
document.addEventListener('keypress', function(codTecla){
var foco = document.activeElement.id;
if(codTecla.keyCode===13 & foco==='propuestaResultado'){comprobarChecked();}
});
for (var i=0; i<nodosMenu.length; i++){
nodosMenu[i].parentNode.addEventListener('mouseover', muestraCaja.bind(this, i));
nodosMenu[i].parentNode.addEventListener('mouseout', muestraCaja.bind(this, i));
nodosMenu[i].addEventListener('click', operacionElegida.bind());
}
function muestraCaja(i, ev){
if(ev.type === 'mouseover'){
nodoCajaTexto[i].style.visibility = 'visible';
nodoCajaTexto[i].style.top = nodosMenu[i].parentNode.offsetTop + 'px';
nodoCajaTexto[i].style.left = nodosMenu[i].parentNode.offsetWidth + 'px';
nodosMenu[i].parentNode.style.backgroundColor = '#FFFFFF';
nodosMenu[i].parentNode.style.color = '#5F9EA0';
}else{
nodoCajaTexto[i].style.visibility = 'hidden';
nodosMenu[i].parentNode.style.backgroundColor = '#5F9EA0';
nodosMenu[i].parentNode.style.color = '#FFFFFF';
}
}
function comprobarChecked(){
for(var z=0; z<nodosMenu.length; z++){
if(nodosMenu[z].checked){
comprobarResultado(nodosMenu[z].value);
}
}
}
}
function operacionElegida(){
var nodosOcultos = document.getElementsByClassName('ocultaContenedor');
for (var j=0; j<nodosOcultos.length; j++){
nodosOcultos[j].style.visibility = 'visible';
}
var nodosMenu = document.getElementsByName('tipoOperacion');
for(var i=0; i<nodosMenu.length; i++){
if(nodosMenu[i].checked){
var opcion = nodosMenu[i].value;
}
}
if(document.getElementById('canvas0')){
var nodosParaBorrar = document.querySelectorAll('#operacion div');
var nodoPadre = document.getElementById('operacion');
for(var i=0, j = nodosParaBorrar.length; i<j; i++){
nodoPadre.removeChild(nodosParaBorrar[i]);
}
}
switch (opcion){
case 'contar':
contar();
break;
case 'suma':
crearSuma(2, 9, 1, 10, false);
break;
case 'sumaN2':
crearSuma(2, 9, 1, 18, false);
break;
case 'sumaN3':
crearSuma(2, 20, 2, 20, false);
break;
case 'resta':
crearResta(10, 1, false);
break;
case 'restaN2':
crearResta(20, 1, false);
break;
}
}

function comprobarResultado(operacion){
var msgBienMal = document.getElementById('mensaje');
var resultadoPropuesto = Number(document.getElementById('propuestaResultado').value);
var operacionPropuesta = document.getElementById('operacion').textContent;
if(operacion==='suma' || operacion==='sumaN2' || operacion==='sumaN3'){
var resultado = operacionPropuesta.split('+');
resultado[2]= Number(resultado[0]) + parseInt(resultado[1]);
}else if(operacion==='resta' || operacion==='restaN2'){
var resultado = operacionPropuesta.split('-');
resultado[2] = Number(resultado[0]) - parseInt(resultado[1]);
} else if(operacion==='contar') {
var resultado = document.querySelectorAll('#operacion div').length;
}
if(resultado[2]===resultadoPropuesto || resultado===resultadoPropuesto){
msgBienMal.style.color = 'green';
msgBienMal.innerHTML = '¡Correcto!';
apariencia(false);
}else{
msgBienMal.style.color = 'red';
msgBienMal.innerHTML = '¡Incorrecto!';
}
}
function apariencia(hayError){
var btnSiguiente = document.getElementById('botonSiguiente');
var resultadoPropuesto = document.getElementById('propuestaResultado');
if(hayError){
resultadoPropuesto.disabled = false;
resultadoPropuesto.focus();
resultadoPropuesto.value = '';
document.getElementById('mensaje').innerHTML = '';
btnSiguiente.style.opacity = '0.5';
btnSiguiente.style.cursor = 'not-allowed';
btnSiguiente.disabled = true;
} else {
btnSiguiente.disabled = false;
btnSiguiente.focus();
btnSiguiente.style.opacity = '1';
btnSiguiente.style.cursor = 'pointer';
resultadoPropuesto.disabled = true;
}
}
/**
  * Función que se encarga decidir que forma tomarán los objetos que aparecerán en pantalla (mediante el uso de canvas)
  * para contar, entre cuatro opciones (circulo, estrella, triangulo, cuadrado) de forma aleatoria.
  * También dará un número aleatorio del 1 al 10, que será el número de objetos que se dibujaran por pantalla y crear los
  * nodos canvas y se llamará a la función dibujar pasándole como parámetros el id del último elemento creado, el valor de
  * la variable i en ese momento y la forma elegida a dibujar.
  */
function contar(){
apariencia(true);
var contObjs = document.getElementById('operacion');
contObjs.innerHTML = '';
var nuevoNodo ;
var numObjs = Math.floor(Math.random()*(11-1))+1;
var forma = ['circulo', 'estrella', 'triangulo', 'cuadrado'];
var formaElegida = Math.floor(Math.random()*(forma.length));
for (var i=0; i<numObjs; i++){
nuevoNodo = document.createElement('div');
nuevoNodo.className = "flotaLeft";
nuevoNodo.style.width = '80px';
nuevoNodo.style.height = '80px';
contObjs.appendChild(nuevoNodo);
nuevoNodoCanvas = document.createElement('canvas');
nuevoNodo.appendChild(nuevoNodoCanvas);
nuevoNodoCanvas.id = "canvas" + i;
dibujar(nuevoNodoCanvas.id, i, forma[formaElegida]);
}
}

/**
  * Función que recibe tres parámetros, el id del elemento donde se creará el dibujo, el valor numérico de la varible i en
  * la función de la que viene, que dependerá del número de iteración en que se encuentre y que cuando se dibuje la
  * estrella intervenga en la rotación de esta y por último, la forma elegida a dibujar.
  * Se creará el objeto canvas, se llamará a una función, dependiendo de la forma que se vaya a dibujar y posteriormente, se
  * pintará el contorno y el relleno de la figura.
  */
function dibujar(id, i, formaElegida){
var canvas = document.getElementById(id);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
if(formaElegida==='circulo') {
dibujarCirculo(ctx);
} else if(formaElegida==='estrella') {
dibujarEstrella(ctx, i);
} else if(formaElegida==='triangulo') {
dibujarTriangulo(ctx);
} else if(formaElegida==='cuadrado') {
dibujarCuadrado(ctx);
}
ctx.fillStyle = colorAleatorio();
ctx.strokeStyle = colorAleatorio();
ctx.lineWidth = 3;
ctx.stroke();
ctx.fill();
}
}

/**
  * Función que establece los datos necesarior para que posteriormente se dibuje un cuadrado. Recibe como
  * parámetro el objeto canvas.
  */
function dibujarCuadrado(ctx){
ctx.beginPath();
ctx.moveTo(10,10);
ctx.lineTo(70,10);
ctx.lineTo(70,70);
ctx.lineTo(10,70);
ctx.lineTo(10,10);
ctx.lineCap='square';
}

/**
  * Función que establece los datos necesarios para que posteriormente se dibuje un circulo. Recibe como
  * parámetro el objeto canvas.
  */
function dibujarCirculo(ctx){
var X = 40;
var Y = 40;
var r = 30;
ctx.arc(X,Y,r,0,2*Math.PI);
}

/**
  * Función que establece los datos necesarios para que posteriormente se dibuje un triangulo. Recibe como
  * parámetro el objeto canvas.
  */
function dibujarTriangulo(ctx) {
ctx.beginPath();
ctx.moveTo(40,10);
ctx.lineTo(70,70);
ctx.lineTo(10,70);
ctx.lineTo(40,10);
ctx.lineJoin='miter';
}

/**
  * Función que establece los datos necesarios para que posteriormente se dibuje una estrella de 5 puntas. Recibe como
  * parámetro el objeto canvas y un número que  estará comprendido entre 0 y 9 y nos valdrá para que la estrella rote
  * en cada vez que se dibuje.
  */
function dibujarEstrella(ctx,i){
var x = 0;
var y = 0;
var radio = 30;
var puntas = 5;
var paso = 2;
var estrella= puntas / paso;
var rad = (2*Math.PI) / estrella;
ctx.translate(40, 40);
ctx.rotate(i*Math.PI/2);
ctx.beginPath();
for( var i = 0; i < puntas; i++ ){
x = radio * Math.cos( rad*i );
y = radio * Math.sin( rad*i );
ctx.lineTo(x, y);
}
ctx.closePath();
}

/**
  * Función que se encarga de crear los datos que forman un color rgb aleatoriamente.
  */
function colorAleatorio(){
var color = [];
for (var j=0; j<3; j++){
color[j]= Math.floor(Math.random()*222);
}
return 'rgb(' + color[0] + ', ' + color[1] + ', ' + color[2] + ')';
}
</script>
</head>
<body>
<div id="encabezado"></div>
<div id="menuIzq" class="flotaLeft">
<label class="menu">
<input type="radio" name="tipoOperacion" value="contar"/>Contar
<div class="cajaTexto">Cuenta objetos</div>
</label>
<label class="menu">
<input type="radio" name="tipoOperacion" value="suma" checked="checked"/>Suma
<div class="cajaTexto">Crea operaciones con dos sumandos de una cifra, con resultado hasta 10.<br/>Ej: 4+5</div>
</label>
<label class="menu">
<input type="radio" name="tipoOperacion" value="sumaN2"/>Suma+
<div class="cajaTexto">Crea operaciones con dos sumandos de una cifra del 1 al 9 cada uno.<br/>Ej: 8+7</div>
</label>
<label class="menu">
<input type="radio" name="tipoOperacion" value="sumaN3"/>Suma++
<div class="cajaTexto">Crea operaciones con dos sumandos, resultados hasta 20, sin llevadas.<br/>Ej: 12+7</div>
</label>
<label class="menu">
<input type="radio" name="tipoOperacion" value="resta"/>Resta
<div class="cajaTexto">Crea operaciones con minuendo y sustraendo de una cifra.<br/>Ej: 9-3</div>
</label>
<label class="menu">
<input type="radio" name="tipoOperacion" value="restaN2"/>Resta+
<div class="cajaTexto">Crea operaciones en las que el minuendo tendrá un valor máximo de 20, la resta resultante será sin llevadas.<br>Ej: 18-11</div>
</label>

</div>
<div id="contenedor" class="flotaLeft">
<div id="contOperacion" class="borraFlujo ocultaContenedor">
<div id="operacion" class="flotaLeft"></div>
<div id="propResultado" class="flotaLeft"><input type="text" id="propuestaResultado"/></div>
</div>
<div id="contBotones" class="ocultaContenedor">
<button class="boton" id="botonResultado" >Comprobar</button>
<button id="botonSiguiente" class="boton" >Siguiente</button>
</div>
<div id="mensaje" class="ocultaContenedor"></div>
</div>
<div id="menuDcha" ></div>
<div id="pie" class="borraFlujo">Copyright © 2016 | <a href="mailto:cannie18@hotmail.com">pedro,,</a></div>
</body>
</html>

Viendo que mi código aumenta, quisiera que me pudierais, si sería bueno que en la parte central de la página situase un iframe para cargar más tipos de operaciones o llamar a otro documento distinto, esto último me echa para atrás por el hecho de tener que volver a cargar todo otra vez cada vez que cambie de opción, u otras alternativas en las que no halla caído.

Saludos. ;D


« Última modificación: 25 de Septiembre 2016, 23:51 por pedro,, »

Chompy129

  • Intermedio
  • ***
  • Mensajes: 130
  • Programar es divertido. :)
    • Ver Perfil
Me parece GENIAL que hagas esto para niños.
No se mucho de javascript (aun). Pero tengo algunas ideas. :)
Por ejemplo:
  • Podrías poner algunas animaciones mas o menos sutiles, por ejemplo cuando se juzga la respuesta.
  • Algunos efectos de sonido(esto depende de que puedas o no).
  • Algún marcador de puntuaciones.
Bueno esas son mis propuestas, no creo que añadirlas sea díficil. :D

pedro,,

  • Moderador Global
  • Experto
  • *******
  • APR2.COM
  • Mensajes: 1292
    • Ver Perfil
Apuntadas quedan tus recomendaciones.

Muchas gracias Chompy129.

Saludos. ;D

Chompy129

  • Intermedio
  • ***
  • Mensajes: 130
  • Programar es divertido. :)
    • Ver Perfil
De nada pedro! ;D

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".