123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- import { defineComponent, Ref, ref } from 'vue'
- import { Button, Cell, CellGroup, Col, Dialog, Divider, NoticeBar, Radio, RadioGroup, Row, Switch, Toast, Field } from 'vant'
- import InfoIcon from './info.svg'
- import iconDown from './icons/down.svg'
- import iconTv from './icons/tv.png'
- import iconYijian from './icons/yijian.png'
- import styles from './index.module.less'
- import evastyles from '../evaluating/index.module.less'
- import detailState from '/src/pages/detail/state'
- import SettingState from '/src/pages/detail/setting-state'
- import runtime from '/src/pages/detail/runtime'
- import iconTitle from '../evaluating/icons/title.svg'
- import iconCancel from '../evaluating/icons/cancel.svg'
- import iconConfirm from '../evaluating/icons/confirm.svg'
- import { show as helperShow } from '../helper'
- // import { settingPopup, suggestPopup, openSuggestPopup } from '../../buttons'
- import { svgtopng, additionalTitle } from '/src/subpages/colexiu/helpers/index'
- import { promisefiyPostMessage } from '/src/helpers/native-message'
- import Popups from '..'
- import Feedback from '../feedback'
- import { useReload } from '../../uses'
- export const suggestPopup: Ref<any> = ref(null)
- export const confirmShow: Ref<boolean> = ref(false)
- export const switchProps = {
- 'active-color': '#2dc7aa',
- 'inactive-color': '#CCCCCC',
- size: '20px',
- }
- /** 生成水印 */
- const addWatermark = (svg: SVGAElement, text: string, w: number, h: number) => {
- const lastg = svg.querySelector('g')
- const g = document.createElementNS('http://www.w3.org/2000/svg', 'g')
- g.setAttribute('transform', `rotate(-30)`)
- // g.setAttribute('fill', 'rgba(0,0,0,.3)')
- const mw = Math.max(w, h)
- const ww = 600
- const wh = 500
- const xnum = Math.floor((mw * 2) / ww) + 1
- const ynum = Math.floor((mw * 2) / wh) + 1
- const createEl = (x: number, y: number) => {
- const textNS = document.createElementNS('http://www.w3.org/2000/svg', 'text')
- textNS.textContent = text
- textNS.setAttribute('fill', 'rgba(0,0,0,.3)')
- // textNS.setAttribute('transform', 'rotate(-30)')
- textNS.setAttribute('font-size', '55')
- textNS.setAttribute('text-anchor', 'middle')
- textNS.setAttribute('y', '' + y)
- textNS.setAttribute('x', '' + x)
- return textNS
- }
- for (let i = 0; i < ynum; i++) {
- for (let j = 0; j < xnum; j++) {
- g.appendChild(createEl((j - 1) * ww, (i - 1) * wh))
- }
- }
- lastg?.insertAdjacentElement('afterend', g)
- // lastg?.insertAdjacentHTML('beforeend', `<g><text X="50" y="150" fill="rgba(0,0,0,.3)" transform="rotate(-30)" font-size="55">酷乐秀</text></g>`)
- }
- export default defineComponent({
- name: 'ColexiuSettingSett',
- setup() {
- const download = async () => {
- Toast.loading({
- message: '正在生成图片...',
- duration: 0,
- })
- try {
- if (runtime.osmd) {
- const svgNode = document.querySelector('#osmdSvgPage1')!
- const rectData: any = svgNode.getBoundingClientRect()
- let backend = {
- ctx: {
- svg: svgNode,
- width: rectData.width,
- height: rectData.height,
- },
- }
- if (Array.isArray(runtime.osmd?.Drawer?.Backends)) {
- backend = runtime.osmd.Drawer.Backends[0]
- }
- const { width, height } = (backend as any).ctx
- console.log('🚀 ~ width', backend)
- const cw = width
- const ch = height
- const svg: SVGAElement = (backend as any).ctx.svg.cloneNode(true)
- const firstg = svg.querySelector('g')
- // 前面插入一个空白的矩形背景
- firstg?.insertAdjacentHTML(
- 'beforebegin',
- `<rect x="0" y="0" width="${cw * 2}" height="${ch * 2}" fill="#fff"/>`
- )
- // addWatermark(svg, '酷乐秀', cw, ch)
- const cont = new XMLSerializer().serializeToString(svg)
- const png = await svgtopng(cont, cw, ch)
- const titlePng = await additionalTitle(detailState.activeDetail?.musicSheetName, png as string)
- const res = await promisefiyPostMessage({
- api: 'savePicture',
- content: {
- base64: titlePng,
- },
- })
- if (res?.content?.status === 'success') {
- Toast.success('保存成功')
- } else {
- Toast.fail('保存失败')
- }
- }
- } catch (error) {
- Toast.fail('保存失败')
- }
- }
- // 自定义每行小节数量
- const confirmCustomNum = () => {
- let customNoduleInfo = JSON.parse(localStorage.getItem('customNoduleInfo')) || []
- const matchIdx = customNoduleInfo.findIndex((n: any) => n.id === detailState.activeDetail?.examSongId)
- if (matchIdx > -1) {
- customNoduleInfo[matchIdx].customNum = Number(SettingState.sett.customNoduleNum)
- } else {
- customNoduleInfo.push({
- id: detailState.activeDetail?.examSongId,
- customNum: Number(SettingState.sett.customNoduleNum)
- })
- }
- localStorage.setItem('customNoduleInfo', JSON.stringify(customNoduleInfo))
- useReload()
- }
- return () => {
- return (
- <>
- <div>
- <NoticeBar
- class={styles.noticebar}
- left-icon={InfoIcon}
- background="#FFF6E8"
- color="var(--van-primary-color)"
- text="全局设置会更改所有乐谱练习及评测"
- />
- <div class={styles.groupBox} style={{ height: 'auto' }}>
- <Cell center border={false} title="护眼模式">
- <Switch v-model={SettingState.sett.eyeProtection} {...switchProps}></Switch>
- </Cell>
- {/** 大雅金唐曲目自定义小节数 */}
- {
- detailState.isDaYaCategory &&
- <>
- <Cell center border={false} title="自定义每行小节数">
- <Switch v-model={SettingState.sett.openCustomNodule} {...switchProps}></Switch>
- </Cell>
- {
- <div class={styles.columnItem}>
- <Cell center border={false} title="每行小节数">
- <Field
- type="number"
- disabled={!SettingState.sett.openCustomNodule}
- value={SettingState.sett.customNoduleNum}
- v-model={SettingState.sett.customNoduleNum}
- inputAlign="right"
- maxlength={2}
- formatter={(value) => value.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
- />
- </Cell>
- <div class={styles.columnBtn} onClick={confirmCustomNum}>确认</div>
- </div>
- }
- </>
- }
- <Divider />
- {/* <Cell center border={false} title="乐谱大小">
- <div style={{ display: 'flex' }}>
- <RadioGroup
- iconSize={20}
- class={styles.radioGroup}
- v-model={SettingState.sett.scoreSize}
- onChange={(val) => {
- confirmShow.value = true
- // MusicSheetRef.value?.setRender?.()
- // SettingState.sett.scoreSize = val
- }}
- >
- <Radio name={'small'}>小</Radio>
- <Radio name={'middle'}>中</Radio>
- <Radio name={'large'}>大</Radio>
- </RadioGroup>
- </div>
- </Cell> */}
- {/* <Cell border={false} title="开启节拍器">
- <Switch v-model={SettingState.sett.fingering}>off</Switch>
- </Cell> */}
- </div>
- <div class={styles.btnsbar}>
- {/* <div class={styles.btn} onClick={download}>
- <img class={styles.iconBtn} src={iconTv} />
- 下载曲谱
- </div> */}
- <div class={styles.btn} onClick={() => (helperShow.value = true)}>
- <img class={styles.iconBtn} src={iconTv} />
- 投屏帮助
- </div>
- <div
- class={styles.btn}
- onClick={() => {
- suggestPopup.value?.onShow()
- }}
- >
- <img class={styles.iconBtn} src={iconYijian} />
- 意见反馈
- </div>
- </div>
- </div>
- <Popups
- ref={suggestPopup}
- overlay={false}
- style={{
- borderRadius: '8px',
- }}
- >
- <Feedback />
- </Popups>
- <Dialog.Component
- teleport="body"
- class={evastyles.confirm}
- style={{
- overflow: 'initial',
- }}
- vSlots={{
- title: () => <img class={evastyles.iconTitle} src={iconTitle} />,
- footer: () => (
- <div class={evastyles.footer}>
- <img src={iconCancel} onClick={() => (confirmShow.value = false)} />
- <img src={iconConfirm} onClick={useReload} />
- </div>
- ),
- }}
- v-model:show={confirmShow.value}
- message={'设置成功,是否立即重新加载?'}
- />
- </>
- )
- }
- },
- })
|