/*
* Created by yvesb on 16/09/2016.
*/
/*
* MathGraph32 Javascript : Software for animating online dynamic mathematics figures
* https://www.mathgraph32.org/
* @Author Yves Biton (yves.biton@sesamath.net)
* @License: GNU AGPLv3 https://www.gnu.org/licenses/agpl-3.0.html
*/
// on importe kernel
import { ce, getMousePositionToParent, getStr, getTouchPositionToParent } from './kernel'
import NatObj from '../types/NatObj'
import NatCal from '../types/NatCal'
import constantes from '../kernel/constantes'
export const listeAngleDeg = ['90', '-90', '60', '-60', '30', '-30', '45', '-45', '120', '-120', '135', '-135']
export const listeAngleRad = ['pi/2', '-pi/2', 'pi/3', '-pi/3', 'pi/6', '-pi/6', 'pi/4', '-pi/4', '2*pi/3', '-2*pi/3', '3*pi/4', '-3*pi/4']
/**
* Fonction renvoyant un Point formé des coordonnées d'un événement touch relatives
* à un svg dans lequel travaille une mtgApp (version éditeur)
* @param svg Le svg de l'application
* @param evt l'événement
* @param zoomFactor le zoomFactor de l'appli
* @returns {Point}
*/
export function touchPosition (svg, evt, zoomFactor = 1) {
const par = svg.parentNode // Dans le cas de l'appli le parent du svg de la figure est un autre svg
return getTouchPositionToParent(evt, par, constantes.svgPanelWidth * zoomFactor, constantes.topIconSize * zoomFactor)
}
/**
* Fonction renvoyant un Point formé des coordonnées d'un événement souris relatives
* à un svg dans lequel travaille une mtgApp
* @param svg
* @param evt
* @param zoomFactor le zoomFactor de l'appli
* @returns {Point}
*/
export function mousePosition (svg, evt, zoomFactor = 1) {
const par = svg.parentNode // Dans le cas de l'appli le parent du svg de la figure est un autre svg
return getMousePositionToParent(evt, par, constantes.svgPanelWidth * zoomFactor, constantes.topIconSize * zoomFactor)
}
/**
* Fonction sélectionnant les caractères d'indice selectionStart à selectionEnd
* dans le input input
* @param input
* @param selectionStart
* @param selectionEnd
*/
export function setSelectionRange (input, selectionStart, selectionEnd) {
if (input.setSelectionRange) {
input.focus()
input.setSelectionRange(selectionStart, selectionEnd)
} else if (input.createTextRange) {
const range = input.createTextRange()
range.collapse(true)
range.moveEnd('character', selectionEnd)
range.moveStart('character', selectionStart)
range.select()
}
}
export function insertAfter (newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling)
}
export function distancePointDroite (xp, yp, xd, yd, u) {
return Math.abs(u.y * (xd - xp) - u.x * (yd - yp)) / Math.sqrt(u.x * u.x + u.y * u.y)
}
export function getButtonArrow (app, id) {
const btn = ce('input', {
class: 'buttonarrow',
type: 'image',
id
})
import('src/images/menuArrow.png')
.then(({ default: img }) => {
btn.setAttribute('src', img)
})
.catch(error => console.error(error))
btn.style.width = '25px'
btn.style.height = '18px'
return btn
}
/**
* remplace dans une chaîne les caractères < et > par leur équivalent html
* @param {string} ch
* @returns {string}
*/
export function replaceIneg (ch) {
let st = ch.replace(/</g, '<')
st = st.replace(/>/g, '>')
return st
}
/**
* Retourne ch avec les caractères % non précédés d'un \ remplacé par \% pour code Tikz
* @param {string} ch
* @returns {string}
*/
export function adaptStringTikz (ch) {
let s = ch.replace(/([^\\]){1}%{1}/, '$1\\%')
if (s.charAt(0) === '%') s = '\\' + s
return s
}
/**
* Fonction qui à partir d'une chaine Base64 décrivant une image fournit un blob
* de façon à pouvoir être utiisé dans FileSaver
* @param base64Data
* @param imageType
* @returns {Blob}
*/
export function base64toBlob (base64Data, imageType) {
const byteCharacters = atob(base64Data)
const byteNumbers = new Array(byteCharacters.length)
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i)
}
const byteArray = new Uint8Array(byteNumbers)
return new Blob([byteArray], { type: 'image/' + imageType })
}
/**
* Fonction renvoyant la chaîne de caractères représentant le type d'objet grahique dont la présence est nécessaire
* pour un objet source de prototype de nature nat.
* Aussi utilisé dans les exercices de construction.
* @param {Nat} nat
* @returns {string}
*/
export function chaineNatGraphPourProto (nat) {
const ar1 = ['NDroite', 'NDemiDroite', 'NCercle', 'NSegment', 'NArc', 'NPointLie', 'NTtPoint', 'NPolygone', 'NLigneBrisee', 'NLieu']
const ar2 = ['Dte', 'Ddte', 'Cerc', 'Seg', 'Arc', 'PointLie', 'Point', 'Polygone', 'LigneBrisee', 'LieuPt']
for (let i = 0; i < ar1.length; i++) {
if (nat.isOfNature(NatObj[ar1[i]])) return getStr(ar2[i])
}
return '' // Par précaution
}
/**
* Fonction renvoyant la chaîne de caractères représentant le type d'objet non grahique dont la présence est nécessaire
* pour un objet source de prototype de nature calcul nat.
* Aussi utilisé dans les exercices de construction.
* @param {Nat} nat
* @returns {string}
*/
export function chaineNatCalcPourProto (nat) {
const ar1 = ['NVariable', 'NTteValR', 'NTteValC', 'NRepere', 'NFonction', 'NFonction2Var', 'NFonction3Var',
'NFonction4Var', 'NFonction5Var', 'NFonction6Var', 'NFonctionComplexe',
'NFonctionComplexe2Var', 'NFonctionComplexe3Var', 'NFonctionComplexe4Var', 'NFonctionComplexe5Var', 'NFonctionComplexe6Var',
'NSuiteRecurrenteReelle', 'NSuiteRecurrenteComplexe',
'NSuiteRecurrenteReelle2', 'NSuiteRecurrenteReelle3', 'NSuiteRecurrenteComplexe2', 'NSuiteRecurrenteComplexe3',
'NTteMatrice']
const ar2 = ['Variable', 'ValR', 'ValC', 'Repere', 'Fonc', 'Fonc2Var', 'Fonc3Var',
'Fonc3Var', 'Fonc3Var', 'Fonc3Var', 'FoncComp',
'FoncComp2Var', 'FoncComp3Var', 'FoncComp3Var', 'FoncComp3Var', 'FoncComp3Var',
'SuiteRec', 'SuiteRecComplexe',
'SuiteRec2', 'SuiteRec3',
'SuiteRecComplexe2', 'SuiteRecComplexe3',
'Matrice']
for (let i = 0; i < ar1.length; i++) {
if (nat.isOfNature(NatCal[ar1[i]])) return getStr(ar2[i])
}
return '' // Par précaution
}
/**
* Fonction qui renvoie pour une implémentation de prototype quel est la nature d'objet numérique qui est compatible
* pour l'implémentation avec la nature nat
* @param {Nat} nat la nature de l'objet testé qui est un objet source pour une construction
* @returns {Nat} Une nature de type Calcul (élément de NatCal)
*/
export function natObjCalPourProto (nat) {
if (nat.isOfNature(NatCal.NCalculReel)) return NatCal.NTteValR
if (nat.isOfNature(NatCal.NCalculComplexe)) return NatCal.NTteValC
// Ligne suivante ajoutée version 6.7 pour les constructions ayant des objest sources de type matrice
if (nat.isOfNature(NatCal.NTteMatrice)) return NatCal.NTteMatrice
// Dans les autres cas même nature attendue
return nat
}
/**
* Fonction qui renvoie pour une implémentation de prototype quel est la nature d'objet graphique qui est compatible
* pour l'implémentation avec la nature nat
* @param {NatObj} nat la nature de l'objet testé qui est un objet source pour une construction
* @returns {NatObj}
*/
export function natObjGraphPourProto (nat) {
if (nat.isOfNature(NatObj.NTtPoint) && !nat.isOfNature(NatObj.NPointLie)) return NatObj.NTtPoint
else return nat
}
/**
* Fonction regardant si le calcul contenu dans ch (qui est vérifié correct avant appel) ne contient
* pas de constantes utilisant plus de 12 décimales
* @param {string} ch
* @returns {boolean}
*/
export function nbDecimalesOK (ch) { // Fonction ajoutée version 6.8.0
let st = ch
let ind
while ((ind = st.indexOf('.')) !== -1) {
st = st.substring(ind + 1)
let indfin = st.search(/[^\d]/)
if (indfin === -1) indfin = st.length
let cha = st.substring(0, indfin)
while (cha.charAt(cha.length - 1) === '0') cha = cha.substring(0, cha.length - 1)
if (cha.length > 12) return false // 12 décimales maxi dans les constantes
}
return true
}