fcad-core-dragon 2.0.0-beta.0 → 2.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/{.eslintrc.js → .eslintrc.cjs} +13 -18
  2. package/README.md +1 -1
  3. package/bk.scss +117 -0
  4. package/package.json +22 -40
  5. package/src/$locales/en.json +57 -19
  6. package/src/$locales/fr.json +66 -28
  7. package/src/components/AppBase.vue +790 -376
  8. package/src/components/AppBaseButton.vue +33 -5
  9. package/src/components/AppBaseErrorDisplay.vue +62 -25
  10. package/src/components/AppBaseModule.vue +831 -754
  11. package/src/components/AppBasePage.vue +60 -74
  12. package/src/components/AppCompAudio.vue +266 -0
  13. package/src/components/AppCompBranchButtons.vue +79 -89
  14. package/src/components/AppCompButtonProgress.vue +35 -61
  15. package/src/components/AppCompCarousel.vue +160 -249
  16. package/src/components/AppCompInputCheckBox.vue +9 -3
  17. package/src/components/AppCompInputDropdown.vue +2 -4
  18. package/src/components/AppCompInputRadio.vue +8 -15
  19. package/src/components/AppCompInputTextTable.vue +15 -12
  20. package/src/components/AppCompInputTextToFillDropdown.vue +16 -14
  21. package/src/components/AppCompInputTextToFillText.vue +2 -2
  22. package/src/components/AppCompJauge.vue +14 -3
  23. package/src/components/AppCompMenu.vue +284 -85
  24. package/src/components/AppCompMenuItem.vue +67 -92
  25. package/src/components/AppCompNavigation.vue +945 -0
  26. package/src/components/AppCompNoteCall.vue +141 -0
  27. package/src/components/AppCompNoteCredit.vue +267 -0
  28. package/src/components/AppCompPlayBar.vue +1122 -1391
  29. package/src/components/AppCompPlayBarProgress.vue +73 -0
  30. package/src/components/AppCompPopUp.vue +195 -135
  31. package/src/components/AppCompPopover.vue +27 -0
  32. package/src/components/AppCompQuiz.vue +90 -113
  33. package/src/components/AppCompQuizRecall.vue +277 -0
  34. package/src/components/AppCompSVG.vue +335 -0
  35. package/src/components/AppCompSettingsMenu.vue +7 -8
  36. package/src/components/AppCompTableOfContent.vue +264 -88
  37. package/src/components/AppCompTranscript.vue +19 -0
  38. package/src/components/AppCompVideoPlayer.vue +380 -0
  39. package/src/components/BaseModule.vue +37 -114
  40. package/src/main.js +130 -85
  41. package/src/mixins/$mediaMixins.js +827 -0
  42. package/src/mixins/$pageMixins.js +149 -115
  43. package/src/mixins/$quizMixins.js +12 -26
  44. package/src/mixins/timerMixin.js +39 -16
  45. package/src/module/store.js +218 -78
  46. package/src/module/xapi/ADL.js +90 -53
  47. package/src/module/xapi/Crypto/Hasher.js +8 -8
  48. package/src/module/xapi/Crypto/WordArray.js +6 -6
  49. package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +4 -4
  50. package/src/module/xapi/Crypto/algorithms/C_algo.js +14 -18
  51. package/src/module/xapi/Crypto/algorithms/HMAC.js +1 -1
  52. package/src/module/xapi/Crypto/algorithms/SHA1.js +1 -1
  53. package/src/module/xapi/Crypto/encoders/Base.js +7 -7
  54. package/src/module/xapi/Crypto/encoders/Base64.js +3 -3
  55. package/src/module/xapi/Crypto/encoders/Hex.js +4 -3
  56. package/src/module/xapi/Crypto/encoders/Latin1.js +3 -3
  57. package/src/module/xapi/Crypto/encoders/Utf8.js +3 -3
  58. package/src/module/xapi/Statement/index.js +1 -1
  59. package/src/module/xapi/launch.js +10 -10
  60. package/src/module/xapi/utils.js +17 -17
  61. package/src/module/xapi/wrapper.js +127 -54
  62. package/src/module/xapi/xapiStatement.js +29 -29
  63. package/src/plugins/gsap.js +4 -1
  64. package/src/plugins/helper.js +58 -24
  65. package/src/plugins/i18n.js +23 -10
  66. package/src/plugins/idb.js +1 -0
  67. package/src/plugins/scorm.js +14 -14
  68. package/src/public/index.html +1 -1
  69. package/src/router/index.js +40 -0
  70. package/src/router/routes.js +317 -0
  71. package/src/shared/generalfuncs.js +91 -9
  72. package/src/shared/validators.js +959 -0
  73. package/.prettierrc.js +0 -5
  74. package/babel.config.js +0 -3
  75. package/src/components/AppBaseDragChoice.vue +0 -91
  76. package/src/components/AppBaseDropZone.vue +0 -112
  77. package/src/components/AppCompDragAndDrop.vue +0 -339
  78. package/src/components/AppCompInputAssociation.vue +0 -332
  79. package/src/components/AppCompMediaPlayer.vue +0 -365
  80. package/src/components/AppCompNavigationFull.vue +0 -1791
  81. package/src/components/AppCompToolTip.vue +0 -94
  82. package/src/plugins/timeManager.js +0 -77
  83. package/src/routes.js +0 -734
  84. package/vue.config.js +0 -83
@@ -1,332 +0,0 @@
1
- <template>
2
- <div class="input-box">
3
- <div style="display:flex">
4
- <div
5
- v-for="singleAssociationZone in inputData.zone_depots"
6
- :key="singleAssociationZone.id"
7
- :class="
8
- `associationlist-${singleAssociationZone.id} ` +
9
- classInput(singleAssociationZone.id)
10
- "
11
- >
12
- <label
13
- :for="`${inputDataId}_${singleAssociationZone.id}`"
14
- v-html="singleAssociationZone.contenu.alt"
15
- ></label>
16
- <div
17
- :class="
18
- quizClickedZone == singleAssociationZone.id
19
- ? 'quizZoneActive'
20
- : 'quizZone'
21
- "
22
- @click="activateChoice(singleAssociationZone.id)"
23
- >
24
- <!--zone is img-->
25
- <div
26
- v-if="singleAssociationZone.contenu.type == 'img'"
27
- class="quizZoneIsImg"
28
- >
29
- <img
30
- :src="singleAssociationZone.contenu.affichage"
31
- :alt="singleAssociationZone.contenu.alt"
32
- />
33
- </div>
34
- <!--zone is text-->
35
- <div
36
- v-if="singleAssociationZone.contenu.type == 'str'"
37
- class="quizZoneIsText"
38
- >
39
- <p v-html="singleAssociationZone.contenu.affichage"></p>
40
- </div>
41
- <!--selected item-->
42
- <!---selected is img--->
43
- <div
44
- v-if="
45
- quizAssociation[singleAssociationZone.id] &&
46
- quizAssociation[singleAssociationZone.id] !== '' &&
47
- inputData.choix_deplaceable[
48
- quizAssociation[singleAssociationZone.id]
49
- ].contenu.type == 'img'
50
- "
51
- class="quizZoneWithImg"
52
- >
53
- <img
54
- :src="
55
- inputData.choix_deplaceable[
56
- quizAssociation[singleAssociationZone.id]
57
- ].contenu.affichage
58
- "
59
- :alt="
60
- inputData.choix_deplaceable[
61
- quizAssociation[singleAssociationZone.id]
62
- ].contenu.alt
63
- "
64
- />
65
- </div>
66
- <!---selected is text--->
67
- <div
68
- v-if="
69
- quizAssociation[singleAssociationZone.id] &&
70
- quizAssociation[singleAssociationZone.id] !== '' &&
71
- inputData.choix_deplaceable[
72
- quizAssociation[singleAssociationZone.id]
73
- ].contenu.type == 'str'
74
- "
75
- class="quizZoneWithText"
76
- >
77
- <p
78
- v-html="
79
- inputData.choix_deplaceable[
80
- quizAssociation[singleAssociationZone.id]
81
- ].contenu.affichage
82
- "
83
- ></p>
84
- </div>
85
- </div>
86
- </div>
87
- </div>
88
- <!--choices-->
89
- <div
90
- style="display:flex"
91
- :class="quizClickedZone ? 'parentQuizChoicesActive' : 'parentQuizChoices'"
92
- >
93
- <div
94
- v-for="singleAssociationChoice in inputData.choix_deplaceable"
95
- :key="singleAssociationChoice.id"
96
- :class="`associationlist-${singleAssociationChoice.id}`"
97
- >
98
- <label
99
- :for="`${inputDataId}_${singleAssociationChoice.id}`"
100
- v-html="singleAssociationChoice.contenu.alt"
101
- ></label>
102
- <div
103
- class="quizAssociationChoice"
104
- @click="assignValueToZone(singleAssociationChoice.id)"
105
- >
106
- <!---is img--->
107
- <div
108
- v-if="singleAssociationChoice.contenu.type == 'img'"
109
- class="quizChoiceWithImg"
110
- >
111
- <img
112
- :src="singleAssociationChoice.contenu.affichage"
113
- :alt="singleAssociationChoice.contenu.alt"
114
- />
115
- </div>
116
- <!---is text--->
117
- <div
118
- v-if="singleAssociationChoice.contenu.type == 'str'"
119
- class="quizChoiceWithText"
120
- >
121
- <p v-html="singleAssociationChoice.contenu.affichage"></p>
122
- </div>
123
- </div>
124
- </div>
125
- </div>
126
- </div>
127
- </template>
128
- <script>
129
- import $extendsQuiz from '../mixins/$quizMixins'
130
- export default {
131
- mixins: [$extendsQuiz],
132
-
133
- props: {
134
- inputType: {
135
- type: String,
136
- default: ''
137
- },
138
- inputDataId: {
139
- type: String,
140
- default: ''
141
- },
142
- inputData: {
143
- type: Object,
144
- default: () => {}
145
- },
146
- quizCompleted: {
147
- type: Boolean,
148
- default: false
149
- },
150
- solution: {
151
- type: Object,
152
- default: () => []
153
- },
154
- showSolution: {
155
- type: Boolean,
156
- default: false
157
- },
158
- shuffleAnswers: {
159
- type: Boolean,
160
- default: false
161
- },
162
- quizAssociation: {
163
- type: Object,
164
- default: () => {}
165
- }, //use to pass the value of the input
166
- quizSubmit: {
167
- type: Boolean,
168
- default: false
169
- } //use to call a submit
170
- },
171
-
172
- data() {
173
- return {
174
- quizClickedZone: '', //for the id of the last clicked zone to assign the choice
175
- quizAssociationValue: [] //not using quizAssociation because quizAssociation is a prop
176
- }
177
- },
178
-
179
- computed: {
180
- /**
181
- * @description
182
- *
183
- quizZoneContent(zoneId) {
184
- //check if zone is filled
185
- if (zoneId == false) {
186
- // check if zone has image
187
-
188
- }
189
- return zoneId
190
- }*/
191
- },
192
-
193
- watch: {
194
- /**
195
- * @description to pass value to AppCompQuiz
196
- * @fires input-change to AppCompQuiz.vue
197
- */
198
- quizAssociationValue(newValue) {
199
- this.$emit('input-change', newValue)
200
- },
201
-
202
- /**
203
- * @description to pass the value from AppCompQuiz
204
- */
205
- quizAssociation(newValue) {
206
- this.quizAssociationValue = newValue
207
- }
208
- },
209
-
210
- mounted() {
211
- let associatedChoices = []
212
- for (let i = 0; i < this.inputData.length; i++) {
213
- let singleAssociation
214
- if (this.shuffleAnswers) {
215
- singleAssociation = this.inputData[i]
216
- //@todo shuffle
217
- singleAssociation.option = this.shuffleArray(singleAssociation.option)
218
- } else {
219
- singleAssociation = this.inputData[i]
220
- }
221
- }
222
- if (this.quizAssociation.length == 0) {
223
- this.quizAssociationValue = associatedChoices
224
- } else {
225
- this.quizAssociationValue = this.quizAssociation
226
- }
227
- },
228
-
229
- methods: {
230
- /**
231
- * @description check if a values exists in a array
232
- * @param {Array} array
233
- * @param value
234
- * @returns {Boolean}
235
- */
236
- containsValue(array, value) {
237
- return array.includes(value)
238
- },
239
-
240
- /**
241
- * @description shuffles an array used to randomized the option order if shuffleAnswers is true
242
- * @param {Array} array
243
- * @returns {Array}
244
- * @todo redo shuffle
245
- */
246
- shuffleArray(array) {
247
- let newArray = []
248
- let newArray2 = []
249
-
250
- for (let i = 0; i < array.length; i++) {
251
- const element = array[i]
252
- //todo remove null values
253
- newArray.push(element)
254
- }
255
- while (newArray.length > 0) {
256
- let pos = Math.floor(newArray.length * Math.random())
257
- newArray2.push(newArray[pos])
258
- newArray.splice(pos, 1)
259
- }
260
- return newArray2
261
- },
262
-
263
- /**
264
- * @description activates choices to assign to that zone
265
- * @param {String} zoneId
266
- */
267
- activateChoice(zoneId) {
268
- if (this.quizClickedZone == zoneId) {
269
- this.quizClickedZone = ''
270
- } else {
271
- this.quizClickedZone = zoneId
272
- }
273
- },
274
-
275
- /**
276
- * @description remove current uses of value and assign value to quiz
277
- * @param {String} choiceId
278
- */
279
- assignValueToZone(choiceId) {
280
- if (this.quizClickedZone !== '' && choiceId !== '') {
281
- //remove current uses of value
282
- for (const singleKey in this.quizAssociationValue) {
283
- if (
284
- Object.hasOwnProperty.call(this.quizAssociationValue, singleKey)
285
- ) {
286
- const element = this.quizAssociationValue[singleKey]
287
- if (element == choiceId) {
288
- this.$set(this.quizAssociationValue, singleKey, '')
289
- }
290
- }
291
- }
292
- /*
293
- let listKeys = Object.keys(this.quizAssociationValue)
294
- for (let index = 0; index < listKeys.length; index++) {
295
- if (this.quizAssociationValue[listKeys[index]] == choiceId) {
296
- this.$set(this.quizAssociationValue, listKeys[index], '')
297
- }
298
- }*/
299
- //assing value
300
- this.$set(this.quizAssociationValue, this.quizClickedZone, choiceId)
301
- //deactivate choices
302
- this.quizClickedZone = ''
303
- }
304
- }
305
- }
306
- }
307
- </script>
308
- <style scoped>
309
- .quizZone,
310
- .quizZoneActive {
311
- height: 300px;
312
- width: 300px;
313
- border: solid 1px;
314
- }
315
-
316
- .quizZone {
317
- border-color: black;
318
- }
319
- .quizZoneActive {
320
- border-color: red;
321
- }
322
-
323
- .parentQuizChoicesActive {
324
- background: yellow;
325
- }
326
-
327
- .quizAssociationChoice {
328
- height: 300px;
329
- width: 300px;
330
- border: solid black 1px;
331
- }
332
- </style>
@@ -1,365 +0,0 @@
1
- <!--
2
- @ Description: This component is used to display media element (video/audio and Gsap timelined animation )
3
- @ What it does: The component create the HTMLMediaElement tag( video/audio) from data provided by user.
4
- Once the HTMLMediaElement tag is created, the component save the HTMLMediaElement to store and
5
- make it available to all other component that will need id
6
- -->
7
-
8
- <template>
9
- <div
10
- v-if="mData"
11
- id="contain-media-player"
12
- class="app-media-player"
13
- :class="[{ FS: fullScreen }, animationType, CCBrowser]"
14
- :style="{ height: [fsHeigh] }"
15
- >
16
- <!------------------video section --------------------------->
17
- <video
18
- v-if="media && media.mType === 'video'"
19
- id="video"
20
- ref="video"
21
- tabindex="0"
22
- class="m-video"
23
- :poster="media.mPoster"
24
- @loadedmetadata="updateMediaData($event)"
25
- @load="() => {}"
26
- @error="() => {}"
27
- >
28
- <!-- <source
29
- v-for="(aMedia, index) in media.mSources"
30
- :key="index"
31
- :src="`${aMedia.src}`"
32
- :type="`${media.mType}/${aMedia.type}`"
33
- /> -->
34
- <source
35
- v-for="(aMedia, index) in media.mSources"
36
- :key="index"
37
- :src="`${aMedia.src}`"
38
- :type="`${media.mType}/${aMedia.type}`"
39
- />
40
- <track
41
- v-if="media.mSubtitle"
42
- :src="media.mSubtitle.src"
43
- :srclang="media.mSubtitle.srclang"
44
- :label="media.mSubtitle.label"
45
- />
46
- </video>
47
- <!------------------ audio section --------------------------->
48
- <video
49
- v-if="media && media.mType === 'audio'"
50
- ref="audio"
51
- tabindex="0"
52
- class="m-audio"
53
- :poster="media.mPoster"
54
- @loadedmetadata="updateMediaData($event)"
55
- >
56
- <source
57
- v-for="(aMedia, index) in media.mSources"
58
- :key="index"
59
- :src="`${aMedia.src}`"
60
- :type="`${media.mType}/${aMedia.type}`"
61
- />
62
- <track
63
- v-if="media.mSubtitle"
64
- :src="media.mSubtitle.src"
65
- :srclang="media.mSubtitle.srcLang"
66
- :label="media.mSubtitle.label"
67
- />
68
- </video>
69
- <!------------------animation section --------------------------->
70
- <div
71
- v-if="media && hasAnimation"
72
- id="anim-box"
73
- class="anim-canvas"
74
- :class="[animationType]"
75
- >
76
- <slot ref="animScene" name="drawingCanvas">
77
- You have an animation to create
78
- </slot>
79
- </div>
80
- <portal-target name="playbar-portal"></portal-target>
81
- </div>
82
- </template>
83
-
84
- <script>
85
- import { mapGetters } from 'vuex'
86
-
87
- export default {
88
- props: {
89
- mData: {
90
- type: Object,
91
- required: true
92
- },
93
- fullScreen: {
94
- type: Boolean,
95
- default: true
96
- },
97
- custom: {
98
- type: Boolean,
99
- default: false
100
- }
101
- },
102
-
103
- data() {
104
- return {
105
- media: null,
106
- timeline: null,
107
- subtitleMenuButtons: [],
108
- subtitlesMenu: null,
109
- randKey: `kid_${Math.floor(Math.random() * 1001)}`,
110
- fsHeigh: null,
111
- isMedia: false
112
- }
113
- },
114
- computed: {
115
- ...mapGetters(['hasMediaElOrTimeline', 'getCurrentBrowser']),
116
- setTimeout() {
117
- return window.setTimeout
118
- },
119
-
120
- hasAnimation() {
121
- if (
122
- this.mData &&
123
- (this.mData.animation || this.mData.type === 'pg_animation')
124
- ) {
125
- return true
126
- } else return false
127
- },
128
- animationType() {
129
- let type = null
130
- if (this.mData) {
131
- if (this.mData.type === 'pg_animation') {
132
- type = 'animationOnly'
133
- }
134
- if (this.mData.type === 'pg_media') {
135
- if (this.mData.mediaData.mType === 'audio') {
136
- type = 'audioAnimation'
137
- } else if (this.mData.mediaData.mType === 'video') {
138
- type = 'videoAnimation'
139
- }
140
- }
141
- }
142
- return type
143
- },
144
- CCBrowser() {
145
- let browser = this.getCurrentBrowser
146
-
147
- if (browser === 'Safari') {
148
- return 'safari'
149
- } else {
150
- return 'chrome'
151
- }
152
- }
153
- },
154
- watch: {
155
- media(val, oldVal) {
156
- let mElement = this.$refs[this.media.mType]
157
- if (oldVal === null && val !== oldVal) {
158
- //this.$store.dispatch('updateAppStatus', 'loading')
159
- //this.$store.dispatch('updateCurrentMediaElement', mElement)
160
- //this.fecthFromServer(this.media.mSources)
161
- // for (let m of this.media.mSources) {
162
- // this.checkRessource(m.src)
163
- // }
164
- }
165
-
166
- /* Handeling media subtitles
167
- * if there is any subtitle, create the subtitle menu
168
- */
169
- if (mElement && mElement.textTracks) {
170
- this.subtitlesMenu = []
171
- for (let i = 0; i < mElement.textTracks.length; i++) {
172
- this.subtitlesMenu.push({
173
- id: `subtitle-${mElement.textTracks[i].language}`,
174
- lang: mElement.textTracks[i].language,
175
- label: mElement.textTracks[i].label
176
- })
177
- }
178
- }
179
- },
180
-
181
- mData: {
182
- immediate: true,
183
- handler() {
184
- if (this.mData && this.mData.type == 'pg_media') {
185
- this.media = {
186
- mType: this.mData.mediaData.mType,
187
- mSources: [...this.mData.mediaData.mSources],
188
- mPoster: this.mData.mediaData.mPoster || '',
189
- mSubtitle: this.mData.mediaData.mSubtitle || null,
190
- mTranscript: this.mData.mediaData.mTranscript || null
191
- }
192
- }
193
- // Its an animation
194
- else if (this.mData && this.mData.type == 'pg_animation') {
195
- this.media = this.mData.animation
196
- }
197
- }
198
- }
199
- },
200
- mounted() {
201
- if (this.fullScreen) {
202
- this.fsHeigh = ` ${window.innerHeight - 55}px`
203
- } else {
204
- this.fsHeigh = `100%`
205
- }
206
-
207
- this.$bus.$emit('videoFullScreen', this.fullScreen)
208
- if (this.media) {
209
- window.addEventListener('resize', this.caclWindowHeight)
210
- }
211
- },
212
-
213
- beforeDestroy() {
214
- this.$bus.$emit('videoFullScreen', false)
215
- window.removeEventListener('resize', this.caclWindowHeight)
216
- },
217
- methods: {
218
- hideSutitle() {
219
- return
220
- },
221
- showSubtitle() {
222
- return
223
- },
224
-
225
- /**
226
- * @description select available= subtitle for title for a media
227
- * @param {htmlElement} e
228
- */
229
- selectSubtitle(e) {
230
- let mElement = document.querySelector(
231
- `.app-media-player> ${this.media.mType}`
232
- )
233
- let subtitlesOption = this.$el.querySelectorAll('.subtitles-menu> a')
234
-
235
- //set all the subitle options as inactive
236
- for (let i = 0; i < subtitlesOption.length; i++) {
237
- subtitlesOption[i].setAttribute('data-state', 'inactive')
238
- subtitlesOption[i].className = 'sub_inactive'
239
- }
240
-
241
- for (let i = 0; i < mElement.textTracks.length; i++) {
242
- // For the 'subtitles-off' button, the first condition will never match so all will subtitles be turned off
243
- if (mElement.textTracks[i].language == e.target.lang) {
244
- mElement.textTracks[i].mode = 'showing'
245
- e.target.setAttribute('data-state', 'active')
246
- e.target.className = 'sub_active'
247
- } else {
248
- mElement.textTracks[i].mode = 'hidden'
249
- e.target.setAttribute('data-state', 'active')
250
- e.target.className = 'sub_active'
251
- }
252
- }
253
- },
254
-
255
- /**
256
- * @description update the information for the mediaElement in the store
257
- * @param {htmlElement} e
258
- * @fires update-page to AppBaseModule.vue
259
- */
260
- updateMediaData(e) {
261
- //dispatch loading status of for this component
262
- this.$bus.$emit('set-comp-status', 'AppCompMediaPlayer', 'loading')
263
-
264
- this.$store
265
- .dispatch('updateCurrentMediaElement', e.target)
266
- .then(() => {
267
- this.$bus.$emit('update-page')
268
- if (this.mData.timeline) {
269
- //Set the length (total duration) of the timeline to the duration of the media
270
- //Note: using totalDuration() or duration() will not work to define the duration to the length of the media.
271
- this.mData.timeline.set({}, {}, e.target.duration)
272
- }
273
- })
274
- .then(() =>
275
- this.$bus.$emit('set-comp-status', 'AppCompMediaPlayer', 'ready')
276
- )
277
- },
278
- caclWindowHeight() {
279
- document.getElementById(
280
- 'contain-media-player'
281
- ).style.height = `${window.innerHeight - 55}px`
282
- },
283
- // TODO: Checking that the media ressource exist/is available
284
- // true: create set the ressource src
285
- // false: disable play button, show on screen message media not available to user
286
- //
287
- async checkRessource(url) {
288
- this.axios
289
- .get(url, { responseType: 'blob' })
290
- .then((res) => {
291
- res
292
- })
293
- .catch((err) => {
294
- err
295
- })
296
- }
297
- }
298
- }
299
- </script>
300
- <style lang="scss">
301
- $widthVideo: 100%;
302
- $widthAudioAnimation: 100%;
303
-
304
- %animation {
305
- position: absolute;
306
- top: 0;
307
- left: 0;
308
- width: $widthVideo;
309
- height: 100%;
310
- z-index: 1;
311
- overflow: hidden;
312
- }
313
-
314
- .app-media-player {
315
- position: relative;
316
- overflow: hidden;
317
-
318
- &.AudioAnimation {
319
- width: $widthAudioAnimation;
320
- .anim-canvas {
321
- @extend %animation;
322
- }
323
- }
324
-
325
- &.FS,
326
- &.animationOnly {
327
- width: 100%;
328
- position: absolute;
329
- top: 0;
330
- left: 0;
331
-
332
- video {
333
- min-width: 100% !important;
334
- min-height: 100% !important;
335
- position: absolute !important;
336
- top: 50% !important;
337
- left: 50% !important;
338
- transform: translate(-50%, -50%) !important;
339
- z-index: 9;
340
- }
341
-
342
- .anim-canvas {
343
- @extend %animation;
344
- }
345
- }
346
-
347
- &.FS,
348
- &.AudioAnimation {
349
- width: 100%;
350
- position: absolute;
351
- top: 0;
352
- left: 0;
353
-
354
- .anim-canvas {
355
- @extend %animation;
356
- }
357
- }
358
- }
359
-
360
- video {
361
- &:focus-visible {
362
- outline-color: transparent;
363
- }
364
- }
365
- </style>