Outils pour utilisateurs

Outils du site


wiki:tutoriels:ascii-camera-html:accueil

Ceci est une ancienne révision du document !


Caméra ASCII Html - JavaScript


Introduction

Ce tutoriel vous permet de créer une page web générant une vidéo Ascii. L'Ascii est une norme informatique de codage de caractères apparue dans les années 1960. Elle fut utilisé dans les domaine de l'imprimerie et de l'art pour générer des images imprimables sur imprimante typographique numérique ainsi que pour générer des images sur des écrans ne les prenants pas en compte (tel que le minitel). De plus une image composée de texte est moins lourde qu'une image composée de pixels, l'Ascii est d'ailleurs de plus en plus utilisé dans des sites Low-Tech.

Image écran en Ascii Impression en Ascii

Présentation de l'effet

On peut changer la couleur de la typographie et du fond d'écran dans le fichier “ascii.css”, en inversant l'ordre des caractères dans le fichier “ascii.js”

Version classique

Positif blanc Positif noir

Version négatif

Négatif noir Négatif blanc

Téléchargement et Exemple

Vous pouvez retrouver l'exemple de cette Expérimentation sur mon site web.

Vous pouvez également télécharger les 4 styles d'effets montrés plus haut en Fichier RAR (compression) ou en Fichier ZIP (compression)

Explication du programme

Le programme se compose de plusieurs parties, un fichier “index.html” composant la structure de création de la page web, un fichier “asciiCss.css” c'est la feuille de style en cascade, qui permet de composer le style graphique de la page. Et trois autre fichier en JavaScript (language de programmation de scripts utilisé pour les pages internet intéractives), “camera.js” qui définit les fonction et variable de la caméra, “ascii.js” sert à traduire l'image en caractères et en à les organiser et “app.js” donnant un cadre visuel, c'est l'interface.

Structure Html

Les commentaires/explications se situent entre “<!–” et “–>”

<!doctype html>
<html lang="fr"> 
<head> <!-- entête -->
<!-- Titre -->
<title> Ascii video </title>
<!-- META -->
<meta charset="utf-8"> <!-- prise en charge de tout les caractères et langues autre que alphabet latin -->
<meta name="Webcam Ascii" content="Webcam to Ascii, .">
<!-- RESPONSIVE -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Meta Author / champ modifiable  -->
<meta name="author" content="Jean-Alexis BONNET">
<meta name="copyright" content="lookitsgraphic">
<meta name="creation_Date" content="02/02/2020">
<!-- Lien CSS -->
<link href="css/asciiCss.css" rel="stylesheet" type="text/css">
<!-- application tel -->
<meta name="mobile-web-app-capable" content="yes"> <!-- autorisation pour téléphone -->

</head> <!-- fin du l'entête -->

<body> <!-- Corp du site visible -->
<hgroup>

<div id='background'> <!-- section arrière plan du site internet --> 
	<h1 class='title' lang="en"> ASCII VIDEO </h1> <!-- Titre -->
<h2><button id="button">start</button> </h2> <!-- Bouton de lancement -->
<pre id="ascii"></pre> <!-- Identifiant avec vairable pour le programme ascii.js et app.js -->
<script src="ascii/camera.js"></script> <!-- Appel programme Camera -->
<script src="ascii/ascii.js"></script> <!-- Appel programme ascii -->
<script src="ascii/app.js"></script> <!-- Appel programme app -->
	<h6 id="info">Active ta caméra <br> pour commencer.</h6> <!-- Variable appellé dans les programmes Ascii.js et app.js avec texte apparaissant avant -->
</div>

<div id="notSupported"> <!-- Variable appellé dans les programmes Ascii.js et app.js  -->
	<h6>Ton naviguateur ne supporte pas la caméra de l'API.</h6> <!-- Message qui apparait lorsque la caméra n'est pas activé  -->
</div>
</hgroup>
</body>
</html>

Structure Css

Les commentaires/explications se situent entre “/*” et “*/”

/* */
body {  /* Corp*/
background: #ff; /* fond blanc */
margin: auto; /* marge auto (utiles pour la fixation des titres) */
	
}
h1 { /* titre niveau 1*/
position: fixed; /* position fixe */
top: 40px; /* à 40 px du haut */
left : 45px; /* à 45 de la gauche */
border: 5px solid #000; /* bordure noir autour de la typo de 5 mm */
padding-left: 5px; /* 5 mm entre la typo et la bordure sur gauche*/
padding-right: 5px;  /* 5 mm entre la typo et la bordure sur droite*/
padding-top: 3px;  /* 5 mm entre la typo et la bordure sur haut*/
padding-bottom: 3px;  /* 5 mm entre la typo et la bordure sur bas*/
color: #000; /* typo couleur noir */
font-size: 25px; /* taille typo */
font-family: Gotham, Helvetica Neue, Helvetica, Arial," sans-serif"; /* Choix typographique via le naviguateur (sir gotham non présente, choisir celle d'apres, etc) */
}
h2{ /* Titre niveau 2 */
position: fixed; /* // */
top: 36px; /* // */
right : 40px; /* // */
font-size: 20px;/* // */
font-family: Gotham, Helvetica Neue, Helvetica, Arial," sans-serif"; /* // */
color: rgba(0,0,0,1.00); /* // */
text-transform: uppercase; /* Texte en majuscule */
}
button { /* Bouton (play) */
text-decoration: none; /* Permet d'enlever le surlignage automatique du texte du bouton */
border: 5px solid rgba(0,0,0,1.00); /* // */
cursor: cell; /* Change la forme du curseur lorsque l'on passe dessus */
overflow: hidden; /* Pas de contenu qui dépasse de la zone */
background: none; /* pas de fond */
font-size: 18px; /* // */
font-weight: bolder; /* typo en gras */
font-family: Gotham, Helvetica Neue, Helvetica, Arial,' sans-serif'cursive; /* // */
padding: 0.5rem 2rem; /* permet de remplacer les notions de padding left, right, ... la première valeur est pour la largeur, la seconde pour la hauteur, rem est une unité variable qui change en fonction de la taille de la typo(valeur native) */
color: rgba(0,0,0,1.00); /* Couleur de la typo, rgba est une autre manière de l'indiquer  */

}
button:hover { /* Changement de Style graphique lorsque on passe par dessus le bouton */
box-shadow: 1px 1px 25px 10px rgba(0, 0, 0, 0.4);} /* mettre un dégradé en arrière plan / blanc / opacité 40% */

button:active { /* Changement de Style graphique lorsque on clique sur  le bouton */
box-shadow: 1px 1px 80px 25px rgba(0, 0, 0, 0.8); /* mettre un dégradé en arrière plan / blanc / opacité 80% */
}

#ascii { /* Style graphique de la classe ascii */
	font-family: 'Courier New', 'Courier', monospace; /* La typographie courier est celle fonctionnant le mieux pour l'image asci car ses bordure et font toute la même largeur*/
	font-size: 10px; /* taille de la typographie */
	line-height: 10px; /* réglage de l'interlignage pour que le tout soit carré */
	color: black; /* // */
	letter-spacing: -1.5px; /* Réduction de l'espacement des lettres */
	text-align: center; /* alignement des lettres au millieu */
}

h6 { /* Typographie 'active ta caméra' */
	font-size: 55px; /* // */
	font-weight: 300; /* // */
	color: #000; /* Autre méthode de colorisation */
	text-align: center; /* // */
	position: relative; /* position sous forme d'élement indépendant qui bouge en fonction de la taille de l'écran */
	top: 100%; /* // */	
	text-transform : uppercase; /* // */
	font-family: Gotham, Helvetica Neue, Helvetica, Arial," sans-serif"; /* // */
}

#notSupported { /* Même chose que le texte en haut */
	display: none;
}

#notSupported h6 { /* Texte ne fonctionne pas passe en rouge  */
	color: #b41a1a;
	margin-bottom: 20px;
}

.title { /* Classe titre est égale à appellé h1 pour un indication supplémentaire */
position: fixed; /* // */
top: 40px; /* // */
left : 45px; /* // */
border: 5px solid #000; /* // */
animation: glitch-middle 3s infinite;  /* Création d'une animation appellé 'glitch-middle' / durée 3seconde / qui se répete à l'infini */
}
@keyframes glitch-middle { /* Détail graphique de l'animation */
0%,26%,30%,72%,76%,100% { transform: translate(0em,0em) skew(0deg) ; box-shadow: none } /* Le pourcentage correspond à un moment en % de l'animation (60%de3sec) / n'agit pas */
30%,70% {transform: translate(0em,0em) skew(30deg);} /* déforme, penche le texte de 30 deg */
29%,31%,69%,71% {transform: translate(0em,0em) skew(0deg);} /* retour normale */
28%,74% { box-shadow: /* crée des ombrage à 100 % d'opacité, rose et cyan, qui sont décallés du texte */
-0.2em 0.1em 0 0 cyan,
0.2em -0.1em 0 0 magenta
}
}

Scripts JavaScript

Les commentaires/explications se situent apres les . camera.js <code> Code de Jacob Seidelin (https://www.nihilogic.dk/labs/jsascii/) Modifié par Andrei Gheorghe (https://github.com/idevelop) remodifié et expliqué par Lookitsgraphic ( https://lookitsgraphic.com/Projects/Ascii.html/ )

var camera = (function() { utilise variable option, video, canvas, context, rendertimer var options; var video, canvas, context; var renderTimer; function initVideoStream() { fonction commencement de vidéo

	video = document.createElement("video"); //créer un element utilisant variable vidéo
	video.setAttribute('width', options.width); //attibut largeur
	video.setAttribute('height', options.height); //attibut hauteur
	video.setAttribute('playsinline', 'true'); // attribut booléen qui indique que la vidéo doit être jouée en incise, c'est-à-dire au sein de la zone de lecture de l'élément.
	video.setAttribute('webkit-playsinline', 'true'); //Même que pour playsinline mais pour navigateur safari et mozilla
	navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; //demande d'utilisation d'un périphérique de l'ordinateur (pour nous la caméra),
	window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL; // ne fonctionne que si le site est sécurisé (https) (depuis 2018 par convention de google et autres).
	if (navigator.getUserMedia) { //si autorisation
		navigator.getUserMedia({
			video: true, //vidéo activée
			audio: false, //son coupé
		}, function(stream) { 
			options.onSuccess();//renvoi une confirmation vers programme app.js
			if (video.mozSrcObject !== undefined) { // renvoi une confirmation programme pour Firefox < 19
				video.mozSrcObject = stream;
			} else {
				video.srcObject = stream; //actif
			}
			initCanvas(); 
		}, options.onError);
	} else {
		options.onNotSupported(); //sinon non supporté, renvoi non confirmation vers programme app.js
	}
}
function initCanvas() { //lorsque bouton play lancé 
	canvas = options.targetCanvas || document.createElement("canvas"); //creer une section écran dédier, un canvas
	canvas.setAttribute('width', options.width); //attribut largeur
	canvas.setAttribute('height', options.height); //attribut hauteur
	context = canvas.getContext('2d'); // CanvasRenderingContext2D est utilisée pour dessiner des rectangles (l'écran)
	// mirroir video
	if (options.mirror) { 
		context.translate(canvas.width, 0); //largeur du canvas uniquement
		context.scale(-1, 1); //-1 = rotation verticale 
	}
}
function startCapture() { //commencement capture vidéo 
	video.play(); //la vidéo se lance 
	renderTimer = setInterval(function() { // definir l'intervale de rendu  
		try {
			context.drawImage(video, 0, 0, video.width, video.height); //dessin des caractères
			options.onFrame(canvas); //Dans l'espace défini
		} catch (e) {
			// TODO //???
		}
	}, Math.round(1000 / options.fps)); //nombre définir par 1000 divisé par fps
}
function stopCapture() { //Fonction arreter la capture vidéo
	pauseCapture(); //Appel fonction vidéo en pause
	if (video.mozSrcObject !== undefined) {  //pour mozilla <19
		video.mozSrcObject = null;
	} else {
		video.srcObject = null; //pour autre naviguateur
	}
}
function pauseCapture() { //Fonction vidéo en pause
	if (renderTimer) clearInterval(renderTimer); //stopper sur dernière image du rendu fps
	video.pause(); // la vidéo est en pause 
}
return {
	init: function(captureOptions) { //fonction capture vidéo
		var doNothing = function(){}; //récupération image seulement 
		options = captureOptions || {}; //option de capture image
		options.fps = options.fps || 25; //fréquence
		options.width = options.width || 640; //taille capture vidéo largeur
		options.height = options.height || 480; // taille capture vidéo hauteur 
		options.mirror = options.mirror || false; // capture vidéo pas en mirroir
		options.targetCanvas = options.targetCanvas || null; // TODO: L'élèment est-il actuellement a <canvas> ?
		options.onSuccess = options.onSuccess || doNothing; //lorsque ça fonctionne, déclencher évennement  onSucces
		options.onError = options.onError || doNothing; // Lorsque erreur, déclencher évennement OnError
		options.onNotSupported = options.onNotSupported || doNothing; // si le navigateur ne fontionne pas avec caméra, déclencher évennemnt onNotSupported
		options.onFrame = options.onFrame || doNothing; //???
		initVideoStream(); 
	},
	start: startCapture, //bouton start, lancer capture
	pause: pauseCapture, //bouton pause, pause capture
	stop: stopCapture //si rien lancé, stop
};

})(); </code>

ascii.js



app.js



wiki/tutoriels/ascii-camera-html/accueil.1602779071.txt.gz · Dernière modification: 2020/10/15 18:24 de bonnetja