fcad-core-dragon 2.0.1 → 2.0.2-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 (90) hide show
  1. package/.editorconfig +33 -33
  2. package/.eslintignore +29 -29
  3. package/.eslintrc.cjs +81 -81
  4. package/CHANGELOG +17 -1
  5. package/bk.scss +117 -117
  6. package/package.json +1 -1
  7. package/src/$locales/en.json +18 -4
  8. package/src/$locales/fr.json +17 -3
  9. package/src/assets/data/onboardingMessages.json +47 -47
  10. package/src/components/AppBase.vue +36 -341
  11. package/src/components/AppBaseErrorDisplay.vue +438 -438
  12. package/src/components/AppBaseFlipCard.vue +84 -84
  13. package/src/components/AppBaseModule.vue +16 -21
  14. package/src/components/AppBasePage.vue +45 -14
  15. package/src/components/AppBasePopover.vue +41 -41
  16. package/src/components/AppBaseSkeleton.vue +45 -0
  17. package/src/components/AppCompAudio.vue +12 -3
  18. package/src/components/AppCompButtonProgress.vue +13 -2
  19. package/src/components/AppCompCarousel.vue +12 -4
  20. package/src/components/AppCompInputCheckBoxNx.vue +324 -0
  21. package/src/components/AppCompInputDropdownNx.vue +295 -0
  22. package/src/components/AppCompInputRadioNx.vue +264 -0
  23. package/src/components/AppCompInputTextNx.vue +148 -0
  24. package/src/components/AppCompInputTextTableNx.vue +198 -0
  25. package/src/components/AppCompInputTextToFillDropdownNx.vue +291 -0
  26. package/src/components/AppCompInputTextToFillNx.vue +277 -0
  27. package/src/components/AppCompJauge.vue +11 -4
  28. package/src/components/AppCompMenu.vue +7 -14
  29. package/src/components/AppCompMenuItem.vue +7 -5
  30. package/src/components/AppCompNavigation.vue +21 -21
  31. package/src/components/AppCompNoteCall.vue +1 -0
  32. package/src/components/AppCompNoteCredit.vue +2 -1
  33. package/src/components/AppCompPlayBarNext.vue +94 -41
  34. package/src/components/AppCompPlayBarProgress.vue +82 -82
  35. package/src/components/AppCompPopUpNext.vue +6 -6
  36. package/src/components/AppCompQuiz.vue +500 -0
  37. package/src/components/AppCompQuizRecall.vue +113 -66
  38. package/src/components/AppCompSettingsMenu.vue +172 -172
  39. package/src/components/AppCompTableOfContent.vue +39 -10
  40. package/src/components/AppCompVideoPlayer.vue +1 -1
  41. package/src/components/AppCompViewDisplay.vue +6 -6
  42. package/src/composables/useQuiz.js +62 -179
  43. package/src/directives/nvdaFix.js +53 -0
  44. package/src/externalComps/ModuleView.vue +22 -22
  45. package/src/externalComps/SummaryView.vue +91 -91
  46. package/src/main.js +227 -30
  47. package/src/mixins/$mediaMixins.js +1 -11
  48. package/src/module/stores/appStore.js +29 -11
  49. package/src/module/xapi/Crypto/Hasher.js +241 -241
  50. package/src/module/xapi/Crypto/WordArray.js +278 -278
  51. package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +103 -103
  52. package/src/module/xapi/Crypto/algorithms/C_algo.js +315 -315
  53. package/src/module/xapi/Crypto/algorithms/HMAC.js +9 -9
  54. package/src/module/xapi/Crypto/algorithms/SHA1.js +9 -9
  55. package/src/module/xapi/Crypto/encoders/Base.js +105 -105
  56. package/src/module/xapi/Crypto/encoders/Base64.js +99 -99
  57. package/src/module/xapi/Crypto/encoders/Hex.js +61 -61
  58. package/src/module/xapi/Crypto/encoders/Latin1.js +61 -61
  59. package/src/module/xapi/Crypto/encoders/Utf8.js +45 -45
  60. package/src/module/xapi/Crypto/index.js +53 -53
  61. package/src/module/xapi/Statement/activity.js +47 -47
  62. package/src/module/xapi/Statement/agent.js +55 -55
  63. package/src/module/xapi/Statement/group.js +26 -26
  64. package/src/module/xapi/Statement/index.js +259 -259
  65. package/src/module/xapi/Statement/statement.js +253 -253
  66. package/src/module/xapi/Statement/statementRef.js +23 -23
  67. package/src/module/xapi/Statement/substatement.js +22 -22
  68. package/src/module/xapi/Statement/verb.js +36 -36
  69. package/src/module/xapi/activitytypes.js +17 -17
  70. package/src/module/xapi/utils.js +167 -167
  71. package/src/module/xapi/verbs.js +294 -294
  72. package/src/module/xapi/xapiStatement.js +444 -444
  73. package/src/plugins/bus.js +8 -8
  74. package/src/plugins/gsap.js +14 -14
  75. package/src/plugins/i18n.js +44 -44
  76. package/src/plugins/idb.js +1 -1
  77. package/src/plugins/save.js +37 -37
  78. package/src/plugins/scorm.js +287 -287
  79. package/src/plugins/xapi.js +11 -11
  80. package/src/public/index.html +33 -33
  81. package/src/shared/generalfuncs.js +134 -0
  82. package/src/shared/validators.js +308 -234
  83. package/src/components/AppCompInputCheckBoxNext.vue +0 -205
  84. package/src/components/AppCompInputDropdownNext.vue +0 -201
  85. package/src/components/AppCompInputRadioNext.vue +0 -158
  86. package/src/components/AppCompInputTextNext.vue +0 -124
  87. package/src/components/AppCompInputTextTableNext.vue +0 -142
  88. package/src/components/AppCompInputTextToFillDropdownNext.vue +0 -238
  89. package/src/components/AppCompInputTextToFillNext.vue +0 -171
  90. package/src/components/AppCompQuizNext.vue +0 -2908
@@ -11,19 +11,21 @@
11
11
  <div v-if="error" id="sidebar-submenu" :class="{ isOpen: isOpened }">
12
12
  <focus-trap :active="isOpened">
13
13
  <div ref="target">
14
+ <!-- <div class="submenu-header"> -->
14
15
  <app-base-button
15
16
  id="close-toc"
16
17
  class="btn-ghost"
17
18
  :title="$t('button.closePopUp')"
18
19
  @click="onCloseWidget('toc')"
19
20
  >
20
- <svg>
21
+ <svg aria-hidden="true" focusable="false">
21
22
  <use href="#close-square-icon" />
22
23
  </svg>
23
24
  </app-base-button>
25
+ <!-- </div> -->
24
26
 
25
- <p class="t-act" v-html="title"></p>
26
-
27
+ <!-- <div class="submenu-content"> -->
28
+ <p class="t-act" v-html="`${title}`"></p>
27
29
  <div class="box-prog-act">
28
30
  <p>
29
31
  {{ $t('text.activity_progress') }}
@@ -46,19 +48,20 @@
46
48
  <p class="anchor-t" v-html="anchor.title"></p>
47
49
  <p class="state">
48
50
  <span class="box-text">
49
- <svg>
51
+ <svg aria-hidden="true" focusable="false">
50
52
  <use href="#check-toc" />
51
53
  </svg>
52
54
  {{ $t('text.complete') }}
53
55
  </span>
54
56
  </p>
55
57
  </div>
56
- <svg>
58
+ <svg aria-hidden="true" focusable="false">
57
59
  <use href="#chevronD-icon" />
58
60
  </svg>
59
61
  </div>
60
62
  </RouterLink>
61
63
  </div>
64
+ <!-- </div> -->
62
65
  </div>
63
66
  </focus-trap>
64
67
  </div>
@@ -147,8 +150,25 @@ export default {
147
150
  if (activity.charAt(1) == '0' || activity.charAt(1) == 0)
148
151
  nb = activity.substr(2)
149
152
  else nb = activity.substr(1)
150
-
151
- this.title = `${this.$t('text.activity')} ${nb} : ${menuInfo[activity].subTitle}`
153
+ //Format title in the Progress info
154
+ switch (nb) {
155
+ case '0':
156
+ this.title = menuInfo[activity].subTitle
157
+ ? `Introduction : ${menuInfo[activity].subTitle}`
158
+ : `Introduction`
159
+ break
160
+
161
+ case '99':
162
+ this.title = menuInfo[activity].subTitle
163
+ ? `Conclusion : ${menuInfo[activity].subTitle}`
164
+ : `Conclusion`
165
+ break
166
+
167
+ default:
168
+ this.title = menuInfo[activity].subTitle
169
+ ? `${this.$t('text.activity')} ${nb} : ${menuInfo[activity].subTitle}`
170
+ : `${this.$t('text.activity')} ${nb}`
171
+ }
152
172
 
153
173
  //create anchors title and path
154
174
  if (menuInfo[activity] && menuInfo[activity].anchors) {
@@ -308,14 +328,19 @@ export default {
308
328
  transition: left 0.5s ease-in-out;
309
329
 
310
330
  &.isOpen {
311
- display: block;
331
+ display: flex;
332
+ flex-direction: column;
312
333
  }
313
334
 
335
+ // .sidebar-submenu-content {
336
+ // display: flex;
337
+ // flex-direction: column;
338
+ // }
314
339
  #close-toc {
315
340
  position: absolute;
316
341
  right: 24px;
317
342
  margin-bottom: 0;
318
- padding: 11px;
343
+ padding: 12px;
319
344
  width: 48px;
320
345
  height: 48px;
321
346
  display: flex;
@@ -374,7 +399,11 @@ export default {
374
399
  }
375
400
  &[done='true'] {
376
401
  .state {
377
- display: block;
402
+ display: flex;
403
+ align-items: center;
404
+ svg {
405
+ margin-right: 10px;
406
+ }
378
407
  }
379
408
  }
380
409
 
@@ -111,7 +111,7 @@ export default {
111
111
  ...mapState(useAppStore, ['getCurrentBrowser', 'getCurrentPage']),
112
112
  //Return true if the video is loading (to show the loading display)
113
113
  isLoading() {
114
- if (!this.isSet && !this.hasSourceLoadingError) return true
114
+ if (!this.isSet) return true
115
115
  else return false
116
116
  },
117
117
 
@@ -1,6 +1,6 @@
1
- <template>
2
- <router-view />
3
- </template>
4
- <script>
5
- export default {}
6
- </script>
1
+ <template>
2
+ <router-view />
3
+ </template>
4
+ <script>
5
+ export default {}
6
+ </script>
@@ -2,185 +2,8 @@
2
2
 
3
3
  import i18n from '@/i18n' //Must import directly the local from project app because vue-18in does not work in legacy mode with composable
4
4
 
5
- export function useQuiz(quiz) {
6
- const { quizType, solution, showSolution, quizInputType } = quiz
5
+ export function useQuiz() {
7
6
  const { t } = i18n.global
8
-
9
- // /**
10
- // * @param {String} inputId
11
- // * @returns {Array} the class
12
- // */
13
- function classInput(inputId, optSelected = null) {
14
- let theClass = []
15
-
16
- switch (true) {
17
- case ['choix_unique', 'reponse_ouverte'].includes(quizType.value):
18
- if (inputId == quizInputType.value) {
19
- theClass.push('reponseSelectionner')
20
- }
21
- break
22
-
23
- case quizType.value == 'choix_mult':
24
- if (containsValue(quizInputType.value, inputId)) {
25
- theClass.push('reponseSelectionner')
26
- }
27
- }
28
-
29
- if (showSolution.value) {
30
- if (solution.value !== null) {
31
- switch (true) {
32
- case ['choix_unique', 'reponse_ouverte'].includes(quizType.value):
33
- if (inputId == solution.value) {
34
- theClass.push('correct_answer')
35
- } else {
36
- theClass.push('wrong_answer')
37
- }
38
- break
39
-
40
- case quizType.value == 'choix_mult':
41
- if (containsValue(solution.value, inputId)) {
42
- theClass.push('correct_answer')
43
- } else {
44
- theClass.push('wrong_answer')
45
- }
46
- break
47
- case quizType.value == 'dropdown':
48
- if (!optSelected || !optSelected[inputId]) return
49
- if (solution.value[inputId] == optSelected[inputId]) {
50
- theClass.push('correct_answer')
51
- } else {
52
- theClass.push('wrong_answer')
53
- }
54
- break
55
-
56
- case quizType.value == 'texte_troue_select':
57
- if (typeof optSelected[inputId] !== 'undefined') {
58
- if (
59
- Object.values(solution.value[inputId])[0] ==
60
- optSelected[inputId]
61
- ) {
62
- theClass.push('correct_answer')
63
- } else {
64
- theClass.push('wrong_answer')
65
- }
66
- }
67
- break
68
-
69
- case quizType.value == 'texte_tableau':
70
- if (
71
- containsValue(
72
- solution.value[inputId].reponse_value,
73
- optSelected[inputId]
74
- )
75
- ) {
76
- theClass.push('correct_answer')
77
- } else {
78
- theClass.push('wrong_answer')
79
- }
80
- break
81
- case quizType.value == 'texte_troue':
82
- if (typeof optSelected[inputId] !== 'undefined') {
83
- if (
84
- containsValue(
85
- Object.values(solution.value[inputId])[0],
86
- optSelected[inputId]
87
- )
88
- ) {
89
- theClass.push('correct_answer')
90
- } else {
91
- theClass.push('wrong_answer')
92
- }
93
- }
94
- break
95
- }
96
- }
97
- }
98
- return theClass
99
- }
100
-
101
- function messageAccessibility(inputId, optSelected = null) {
102
- let mess = ''
103
- if (showSolution.value) {
104
- if (solution.value !== null) {
105
- switch (true) {
106
- case ['choix_unique', 'reponse_ouverte'].includes(quizType.value):
107
- if (inputId == solution.value) {
108
- mess = `${t('quizState.goodAnswer')}`
109
- } else {
110
- mess = `${t('quizState.badAnswer')}`
111
- }
112
- break
113
-
114
- case quizType.value == 'choix_mult':
115
- if (containsValue(solution.value, inputId)) {
116
- mess = `${t('quizState.goodAnswer')}`
117
- } else {
118
- mess = `${t('quizState.badAnswer')}`
119
- }
120
- break
121
- case quizType.value == 'dropdown':
122
- if (solution[inputId.value] == optSelected[inputId.value]) {
123
- mess = `${t('quizState.goodAnswer')}`
124
- } else {
125
- mess = `${t('quizState.badAnswer')}`
126
- }
127
- break
128
-
129
- case quizType.value == 'texte_troue_select':
130
- if (typeof optSelected[inputId] !== 'undefined') {
131
- if (
132
- Object.values(solution.value[inputId])[0] ==
133
- optSelected[inputId]
134
- ) {
135
- mess = `${t('quizState.goodAnswer')}`
136
- } else {
137
- mess = `${t('quizState.badAnswer')}`
138
- }
139
- }
140
- break
141
-
142
- case quizType.value == 'texte_tableau':
143
- if (
144
- containsValue(
145
- solution.value[inputId].reponse_value,
146
- optSelected[inputId]
147
- )
148
- ) {
149
- mess = `${t('quizState.goodAnswer')}`
150
- } else {
151
- mess = `${t('quizState.badAnswer')}`
152
- }
153
- break
154
- case quizType.value == 'texte_troue':
155
- if (typeof optSelected[inputId] !== 'undefined') {
156
- if (
157
- containsValue(
158
- Object.values(solution.value[inputId])[0],
159
- optSelected[inputId]
160
- )
161
- ) {
162
- mess = `${t('quizState.goodAnswer')}`
163
- } else {
164
- mess = `${t('quizState.badAnswer')}`
165
- }
166
- }
167
- break
168
- }
169
- }
170
- }
171
- return mess
172
- }
173
-
174
- /**
175
- * @description check if a values exists in a array
176
- * @param {Array} array
177
- * @param value
178
- * @returns {Boolean}
179
- */
180
- function containsValue(array, value) {
181
- return array.includes(value)
182
- }
183
-
184
7
  /**
185
8
  * @description shuffles an array used to randomized the option order if shuffleAnswers is true
186
9
  * @param {Array} array
@@ -201,6 +24,66 @@ export function useQuiz(quiz) {
201
24
  }
202
25
  return newArray2
203
26
  }
27
+ /**
28
+ * @description add retro style to the quiz
29
+ * @param {Object} solution - the solution of the quiz
30
+ * @param {Array} reponse - the user response
31
+ * @param {Number} length - the length of the input value
32
+ * @returns {Object|Boolean}
33
+ */
34
+ function addRetroStyle(solution, reponse, length) {
35
+ let classRetro = []
36
+ let mesA11y = []
37
+ if (solution != null) {
38
+ reponse.forEach((el) => {
39
+ if (el.correct == true) {
40
+ classRetro.push('goodAnswer')
41
+ mesA11y.push(`${t('quizState.goodAnswer')}`)
42
+ } else {
43
+ classRetro.push('badAnswer')
44
+ mesA11y.push(`${t('quizState.badAnswer')}`)
45
+ }
46
+ })
47
+ } else {
48
+ classRetro.push('NeutralAnswer')
49
+ mesA11y.push(`${t('quizState.neutralAnswer')}`)
50
+ }
204
51
 
205
- return { containsValue, shuffleArray, classInput, messageAccessibility }
52
+ return { classRetro, mesA11y }
53
+ }
54
+
55
+ /**
56
+ * @description reset the list of validation style of a quiz
57
+ * @param {Array} aList - a list of array to reset
58
+ * @emits hide-retro - event message to hide the retro Message
59
+ * $el- the target quiz,
60
+ * false|true of th event
61
+ * */
62
+ function resetRetroStyle(aList) {
63
+ aList.forEach((a) => {
64
+ if (a && a.length > 0) a.splice(0)
65
+ })
66
+ this.$bus.$emit('hide-retro', this.$el, false)
67
+ }
68
+
69
+ function retroType(solution, reponse) {
70
+ if (solution != null) {
71
+ if (reponse.length == solution.length) {
72
+ let Ag = (i) => i.correct
73
+ if (reponse.every(Ag)) return 'retro_positive'
74
+ else return 'retro_negative'
75
+ } else {
76
+ return 'retro_negative'
77
+ }
78
+ } else {
79
+ return `retro_neutre`
80
+ }
81
+ }
82
+
83
+ return {
84
+ addRetroStyle,
85
+ resetRetroStyle,
86
+ retroType,
87
+ shuffleArray
88
+ }
206
89
  }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @file nvdaFix.js
3
+ * @description Directive to fix NVDA screen reader issues with Vuetify dropdowns.
4
+ * This directive hides the input field from screen readers and provides an aria-live region
5
+ * to announce the selected option.
6
+ *
7
+ * @example
8
+ * <v-select v-nvda-fix="selectedOptionText" ...>
9
+ */
10
+
11
+ export default {
12
+ mounted(el, binding) {
13
+ // 1. Hide Vuetify input by adding aria-hidden="true"
14
+ const input = el.querySelector('input[type="text"]')
15
+ if (input) {
16
+ input.setAttribute('aria-hidden', 'true')
17
+ }
18
+
19
+ // 2. Create/update aria-live for screen reader
20
+ const valueText =
21
+ binding && binding.value ? binding.value : 'choisir une option'
22
+ let liveRegion = el.querySelector('.nvda-live-region')
23
+
24
+ if (!liveRegion) {
25
+ liveRegion = document.createElement('div')
26
+ liveRegion.className = 'nvda-live-region sr-only'
27
+ liveRegion.setAttribute('aria-live', 'polite')
28
+ el.appendChild(liveRegion)
29
+ }
30
+
31
+ liveRegion.textContent = `🍍${valueText}`
32
+ },
33
+ /**
34
+ * @description Directive updated hook to handle changes in the selected option.
35
+ * This updates the aria-live region with the new selected option text.
36
+ * @param {Object} el - The element the directive is bound to.
37
+ * @param {Object} binding - The binding object containing the new value.
38
+ */
39
+ updated(el, binding) {
40
+ // update aria-live when selected option changes
41
+ const valueText = binding.value?.text || ''
42
+ const input = el.querySelector('input[type="text"]')
43
+ const liveRegion = el.querySelector('.nvda-live-region')
44
+
45
+ if (input) {
46
+ input.setAttribute('aria-hidden', 'true')
47
+ }
48
+
49
+ if (liveRegion) {
50
+ liveRegion.textContent = `🍍${valueText}`
51
+ }
52
+ }
53
+ }
@@ -1,22 +1,22 @@
1
- <template>
2
- <app-base-module :module-config="$data" />
3
- </template>
4
-
5
- <script>
6
- export default {
7
- data() {
8
- return {
9
- id: 'module_99',
10
- consigneBehavior: 'onHover', //Controle the behavior of desplaying instruction
11
- bookmarkActive: true, // Controle the use of saved point
12
- allowNavigationToActivity: null
13
-
14
- //main:''// Edit to define the ID of the node that will be main. When skipping to main content in the page.
15
- }
16
- },
17
- created() {
18
- this.allowNavigationToActivity =
19
- this.$helper.getSettingsFromStore('auto_next_activity')
20
- }
21
- }
22
- </script>
1
+ <template>
2
+ <app-base-module :module-config="$data" />
3
+ </template>
4
+
5
+ <script>
6
+ export default {
7
+ data() {
8
+ return {
9
+ id: 'module_99',
10
+ consigneBehavior: 'onHover', //Controle the behavior of desplaying instruction
11
+ bookmarkActive: true, // Controle the use of saved point
12
+ allowNavigationToActivity: null
13
+
14
+ //main:''// Edit to define the ID of the node that will be main. When skipping to main content in the page.
15
+ }
16
+ },
17
+ created() {
18
+ this.allowNavigationToActivity =
19
+ this.$helper.getSettingsFromStore('auto_next_activity')
20
+ }
21
+ }
22
+ </script>
@@ -1,91 +1,91 @@
1
- <template>
2
- <div>
3
- <app-comp-menu></app-comp-menu>
4
- <!-- <h6>normal</h6>
5
- <div class="t normal"></div>
6
- <h6>red</h6>
7
- <div class="t red"></div>
8
- <h6>green</h6>
9
- <div class="t green"></div>
10
- <h6>hue</h6>
11
- <div class="t hue"></div>
12
- <h6>Saturation</h6>
13
- <div class="t saturation"></div>
14
- <h6>desaturation</h6>
15
- <div class="t desaturation"></div>
16
- <h6>lighteness</h6>
17
- <div class="t lighteness"></div>
18
- <h6>darkness</h6>
19
- <div class="t darkness"></div>
20
- <h6>whiteness</h6>
21
- <div class="t whiteness"></div>
22
- <h6>blackness</h6>
23
- <div class="t blackness"></div> -->
24
- </div>
25
- </template>
26
-
27
- <script>
28
- export default {
29
- data() {
30
- return {}
31
- }
32
- }
33
- </script>
34
- <!-- <style lang="scss">
35
- @use 'sass:color';
36
- $color: #f11532;
37
- $color-red: color.change($color, $red: 155);
38
- $color-green: color.change($color, $green: 255);
39
- $color-hue: adjust-hue($color, -30deg);
40
- $color-saturation: color.scale($color, $saturation: 100%);
41
- $color-desaturate: color.scale($color, $saturation: -50%);
42
- $color-lighteness: color.scale($color, $lightness: 50%);
43
- $color-darkness: color.scale($color, $lightness: -50%);
44
- $color-whiteness: color.scale($color, $whiteness: 50%);
45
- $color-blackness: color.scale($color, $blackness: 50%);
46
-
47
- .t {
48
- width: 50px;
49
- height: 50px;
50
-
51
- &.normal {
52
- background: $color;
53
- }
54
-
55
- &.red {
56
- background: $color-red;
57
- }
58
-
59
- &.green {
60
- background: $color-green;
61
- }
62
-
63
- &.hue {
64
- background: $color-hue;
65
- }
66
-
67
- &.saturation {
68
- background: $color-saturation;
69
- }
70
-
71
- &.desaturation {
72
- background: $color-desaturate;
73
- }
74
-
75
- &.lighteness {
76
- background: $color-lighteness;
77
- }
78
-
79
- &.darkness {
80
- background: $color-darkness;
81
- }
82
-
83
- &.whiteness {
84
- background: $color-whiteness;
85
- }
86
-
87
- &.blackness {
88
- background: $color-blackness;
89
- }
90
- }
91
- </style> -->
1
+ <template>
2
+ <div>
3
+ <app-comp-menu></app-comp-menu>
4
+ <!-- <h6>normal</h6>
5
+ <div class="t normal"></div>
6
+ <h6>red</h6>
7
+ <div class="t red"></div>
8
+ <h6>green</h6>
9
+ <div class="t green"></div>
10
+ <h6>hue</h6>
11
+ <div class="t hue"></div>
12
+ <h6>Saturation</h6>
13
+ <div class="t saturation"></div>
14
+ <h6>desaturation</h6>
15
+ <div class="t desaturation"></div>
16
+ <h6>lighteness</h6>
17
+ <div class="t lighteness"></div>
18
+ <h6>darkness</h6>
19
+ <div class="t darkness"></div>
20
+ <h6>whiteness</h6>
21
+ <div class="t whiteness"></div>
22
+ <h6>blackness</h6>
23
+ <div class="t blackness"></div> -->
24
+ </div>
25
+ </template>
26
+
27
+ <script>
28
+ export default {
29
+ data() {
30
+ return {}
31
+ }
32
+ }
33
+ </script>
34
+ <!-- <style lang="scss">
35
+ @use 'sass:color';
36
+ $color: #f11532;
37
+ $color-red: color.change($color, $red: 155);
38
+ $color-green: color.change($color, $green: 255);
39
+ $color-hue: adjust-hue($color, -30deg);
40
+ $color-saturation: color.scale($color, $saturation: 100%);
41
+ $color-desaturate: color.scale($color, $saturation: -50%);
42
+ $color-lighteness: color.scale($color, $lightness: 50%);
43
+ $color-darkness: color.scale($color, $lightness: -50%);
44
+ $color-whiteness: color.scale($color, $whiteness: 50%);
45
+ $color-blackness: color.scale($color, $blackness: 50%);
46
+
47
+ .t {
48
+ width: 50px;
49
+ height: 50px;
50
+
51
+ &.normal {
52
+ background: $color;
53
+ }
54
+
55
+ &.red {
56
+ background: $color-red;
57
+ }
58
+
59
+ &.green {
60
+ background: $color-green;
61
+ }
62
+
63
+ &.hue {
64
+ background: $color-hue;
65
+ }
66
+
67
+ &.saturation {
68
+ background: $color-saturation;
69
+ }
70
+
71
+ &.desaturation {
72
+ background: $color-desaturate;
73
+ }
74
+
75
+ &.lighteness {
76
+ background: $color-lighteness;
77
+ }
78
+
79
+ &.darkness {
80
+ background: $color-darkness;
81
+ }
82
+
83
+ &.whiteness {
84
+ background: $color-whiteness;
85
+ }
86
+
87
+ &.blackness {
88
+ background: $color-blackness;
89
+ }
90
+ }
91
+ </style> -->