/*
* 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
*/
import { zero11 } from '../kernel/kernel'
import CListeObjets from './CListeObjets'
import CMacro from './CMacro'
export default CMacroAnimationParVar
/**
* Macro d'animation de la igure par les mouvement d'un point lié.
* @returns {CMacroAnimationParVar}
*/
/**
* @constructor
* @extends CMacro
* @param {CListeObjets} listeProprietaire La liste propriétaire.
* @param {CImplementationProto} impProto null ou la construction propriétaire.
* @param {boolean} estElementFinal true si l'objet est un élément final de construction.
* @param {Color} couleur La couleur d'éciture de l'éditeur (et du cadre éventuel).
* @param {number} xNom L'abscisse d'affichage de la macro
* @param {number} yNom L'ordonnée d'affichage de la macro
* @param {number} decX Décalage horizontal du nom
* @param {number} decY Décalage vertical du nom
* @param {boolean} masque true si l'éditeur est masqué
* @param {CPt} pointLie null ou pointe sur un point auquel l'affichage est lié.
* @param {number} taillePolice Indice de la taiile de police utilisée
* @param {boolean} effacementFond true si on efface le fond de l'en-tête.
* @param {Color} couleurFond La couleur de fond de l'en-tête.
* @param {number} alignementHorizontal 0 pour alignement gauche, 1 pour centre, 2 pour droite.
* @param {number} alignementVertical 0 pour alignement vers le haut, 1 pour centré, 2 pour bas.
* @param {string} intitule Le titre de la macro
* @param {string} commentaireMacro Eventuel commentaire explicatif.
* @param {boolean} animationCyclique : true si animation cyclique (si non cyclique on repart au début).
* @param {number} frequenceAnimationMacro La fréquence d'animation en millièmes de seconde.
* @param {number} nombrePointsPourAnimation
* @param {number} dureeAnimation Durée de l'animation en dixièmes de seconde ou null pour une animation
* @param {CVariableBornee} variableAssociee La variable dont les valeurs génèrent l'animation.
* @param {boolean} inverserSens true pour que l'animation se fasse dans l'autre sens (Le sens usuel sur les cercles est
* le sens trigonométrique direct).
* @param {boolean} retourDepart trus pour que le point lié reviene à son point de départ à la fin de l'animation.
* @param {boolean} unCycle Si true l'animation se fait sur un seul cycle et s'arrête.
* @param {boolean} fixed true si l'affichage est punaisé et ne peut pas être capturé à la souris
* @returns {CMacroAnimationParVar}
*/
function CMacroAnimationParVar (listeProprietaire, impProto, estElementFinal, couleur,
xNom, yNom, decX, decY, masque, pointLie, taillePolice, effacementFond, couleurFond, alignementHorizontal,
alignementVertical, intitule, commentaireMacro, animationCyclique, frequenceAnimationMacro,
nombrePointsPourAnimation, dureeAnimation, variableAssociee, inverserSens,
retourDepart, unCycle, fixed = false) {
if (arguments.length !== 0) {
if (arguments.length === 1) CMacro.call(this, listeProprietaire)
else {
CMacro.call(this, listeProprietaire, impProto, estElementFinal, couleur,
xNom, yNom, decX, decY, masque, pointLie, taillePolice, effacementFond, couleurFond,
alignementHorizontal, alignementVertical, intitule, commentaireMacro, fixed)
this.animationCyclique = animationCyclique
this.frequenceAnimationMacro = frequenceAnimationMacro
this.nombrePointsPourAnimation = nombrePointsPourAnimation
this.dureeAnimation = dureeAnimation
this.variableAssociee = variableAssociee
this.inverserSens = inverserSens
this.retourDepart = retourDepart
this.unCycle = unCycle
this.listeDep = new CListeObjets(listeProprietaire)
}
}
}
CMacroAnimationParVar.prototype = new CMacro()
CMacroAnimationParVar.prototype.constructor = CMacroAnimationParVar
CMacroAnimationParVar.prototype.superClass = 'CMacro'
CMacroAnimationParVar.prototype.className = 'CMacroAnimationParVar'
CMacroAnimationParVar.prototype.numeroVersion = function () {
return 2
}
CMacroAnimationParVar.prototype.getClone = function (listeSource, listeCible) {
const ind1 = listeSource.indexOf(this.variableAssociee)
const ind2 = listeSource.indexOf(this.pointLie)
const ind3 = listeSource.indexOf(this.impProto)
return new CMacroAnimationParVar(listeCible,
listeCible.get(ind3, 'CImplementationProto'),
this.estElementFinal, this.couleur, this.xNom, this.yNom, this.decX, this.decY, this.masque,
listeCible.get(ind2, 'CPt'), this.taillePolice, this.effacementFond, this.couleurFond,
this.alignementHorizontal, this.alignementVertical,
this.intitule, this.commentaireMacro, this.animationCyclique, this.frequenceAnimationMacro,
this.nombrePointsPourAnimation, this.dureeAnimation, listeCible.get(ind1, 'CVariableBornee'),
this.inverserSens, this.retourDepart, this.unCycle, this.fixed)
}
CMacroAnimationParVar.prototype.depDe = function (p) {
if (this.elementTestePourDependDe === p) return this.dependDeElementTeste
return this.memDep(CMacro.prototype.depDe.call(this, p) || this.variableAssociee.depDe(p))
}
CMacroAnimationParVar.prototype.dependDePourBoucle = function (p) {
return CMacro.prototype.dependDePourBoucle.call(this, p) || this.variableAssociee.dependDePourBoucle(p)
}
CMacroAnimationParVar.prototype.typeAnimation = function () {
return CMacro.animationParTimer
}
CMacroAnimationParVar.prototype.frequenceAnimation = function () {
return this.frequenceAnimationMacro
}
CMacroAnimationParVar.prototype.arretParClic = function () {
return (this.dureeAnimation === 0)
}
CMacroAnimationParVar.prototype.metAJour = function () {
CMacro.prototype.metAJour.call(this)
this.etablitListesInternes()
}
CMacroAnimationParVar.prototype.etablitListesInternes = function () {
this.listeDep.retireTout()
this.listeDep.ajouteObjetsDependantsSauf(this.variableAssociee, this.listeProprietaire, this)
}
CMacroAnimationParVar.prototype.executionPossible = function () {
return true // La variable associée existe toujours
}
/**
* Lance l'exécution de la macro via un timer et une fonction de callBack.
* @param {SVGElement} svg Le svg de la figure.
* @param {Dimf} dimf Les dimensions du svg
* @param {Color} couleurFond La couleur de fonc de la figure.
* @returns {void}
*/
CMacroAnimationParVar.prototype.execute = function (svg, dimf, couleurFond) {
this.valeurInitiale = this.variableAssociee.valeurActuelle
this.valeurMini = this.variableAssociee.valeurMini
this.valeurMaxi = this.variableAssociee.valeurMaxi
this.pas = (this.valeurMaxi - this.valeurMini) / (this.nombrePointsPourAnimation - 1)
if (this.inverserSens) this.pas = -this.pas
this.valeur = this.unCycle ? (this.inverserSens ? this.valeurMaxi : this.valeurMini) : this.valeurInitiale
this.valeur -= this.pas
// this.dt = new Date();
const timeDebut = Date.now()
if (this.dureeAnimation !== 0) this.timeFin = timeDebut + this.dureeAnimation * 100 // La durée est en dixièmes de secondes
this.executionEnCours = true
const t = this
this.timer = setInterval(function () { CMacroAnimationParVar.executePourTimer.call(t, svg, dimf, couleurFond) },
this.frequenceAnimationMacro)
}
// Modifié version 5.5.9 en utilisant zero11 au lieu de zero 13 car sinon certaines animations avec un seul cycle ne s'arrêtaient pas
/**
* Fonction de callBack appelée par un timer dans execute()
* @param {SVGElement} svg Le svg de la figure.
* @param {Dimf} dimf Les dimensions du svg
* @param {Color} couleurFond La couleur de fond de la figure.
* @returns {void}
*/
CMacroAnimationParVar.executePourTimer = function (svg, dimf, couleurFond) {
if (!this.executionEnCours) return
this.valeur = this.valeur + this.pas
if (zero11(this.valeur - this.valeurMaxi)) this.valeur = this.valeurMaxi
else
if (zero11(this.valeur - this.valeurMini)) this.valeur = this.valeurMini
if (this.animationCyclique) {
if (this.inverserSens) {
if (this.valeur < this.valeurMini) this.valeur = this.valeurMaxi
} else if (this.valeur > this.valeurMaxi) this.valeur = this.valeurMini
} else {
if (this.valeur > this.valeurMaxi) {
this.pas = -this.pas
this.valeur = this.valeurMaxi
} else {
if (this.valeur < this.valeurMini) {
this.pas = -this.pas
this.valeur = this.valeurMini
}
}
}
this.variableAssociee.donneValeur(this.valeur)
this.listeDep.positionne(false, dimf)
// Ligne suivante modifié version 6.4.8 (ajout du dernier paramètre)
this.listeDep.update(svg, couleurFond, true, true)
const time = Date.now() // Raccourci pour (new Date()).getTime()
if (this.unCycle) {
if (this.inverserSens) {
if (zero11(this.valeur - this.valeurMini) || (this.valeur < this.valeurMini)) this.termineAction(svg, dimf, couleurFond)
} else if (zero11(this.valeur - this.valeurMaxi) || (this.valeur > this.valeurMaxi)) this.termineAction(svg, dimf, couleurFond)
} else if ((this.dureeAnimation !== 0) && (time > this.timeFin)) this.termineAction(svg, dimf, couleurFond)
}
/**
* Fonction appelée à la fin de l'animation.
* @param {SVGElement} svg Le svg de la figure.
* @param {Dimf} dimf Les dimensions du svg
* @param {Color} couleurFond La couleur de fonc de la figure.
* @returns {void}
*/
CMacroAnimationParVar.prototype.termineAction = function (svg, dimf, couleurFond) {
clearInterval(this.timer)
this.executionEnCours = false
if (this.retourDepart) this.variableAssociee.donneValeur(this.valeurInitiale)
else this.variableAssociee.donneValeur(this.inverserSens ? this.valeurMini : this.valeurMaxi)
this.listeDep.positionne(false, dimf)
// Ligne suivante modifié version 6.4.8 (ajout du dernier paramètre)
this.listeDep.update(svg, couleurFond, true, true)
this.passageMacroSuiv(svg, dimf, couleurFond)
}
CMacroAnimationParVar.prototype.read = function (inps, list) {
CMacro.prototype.read.call(this, inps, list)
this.animationCyclique = inps.readBoolean()
this.frequenceAnimationMacro = inps.readInt()
this.nombrePointsPourAnimation = inps.readInt()
this.dureeAnimation = inps.readInt()
const ind1 = inps.readInt()
this.variableAssociee = list.get(ind1, 'CVariable')
if (this.nVersion < 2) {
this.inverserSens = false
this.retourDepart = true
this.unCycle = false
} else {
this.inverserSens = inps.readBoolean()
this.retourDepart = inps.readBoolean()
this.unCycle = inps.readBoolean()
}
if (list.className !== 'CPrototype') this.listeDep = new CListeObjets(this.listeProprietaire)
}
CMacroAnimationParVar.prototype.write = function (oups, list) {
CMacro.prototype.write.call(this, oups, list)
oups.writeBoolean(this.animationCyclique)
oups.writeInt(this.frequenceAnimationMacro)
oups.writeInt(this.nombrePointsPourAnimation)
oups.writeInt(this.dureeAnimation)
const ind1 = list.indexOf(this.variableAssociee)
oups.writeInt(ind1)
oups.writeBoolean(this.inverserSens)
oups.writeBoolean(this.retourDepart)
oups.writeBoolean(this.unCycle)
}