kernel/kernelAdd.js

/*
 * 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, '&lt;')
  st = st.replace(/>/g, '&gt;')
  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
}