-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
277 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
src/components/Creator/LeftPanel/StylesPanel/Filter/Filter.module.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
.singleFilter { | ||
border-bottom: 1px solid #ccc; | ||
} | ||
|
||
.icon { | ||
width: 30px; | ||
height: 30px; | ||
align-self: flex-end; | ||
cursor: pointer; | ||
|
||
&:hover { | ||
color: #f00; | ||
} | ||
} |
161 changes: 161 additions & 0 deletions
161
src/components/Creator/LeftPanel/StylesPanel/Filter/Filter.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
import styles from "@/components/Creator/LeftPanel/StylesPanel/StylesPanel.module.scss"; | ||
import filterStyles from './Filter.module.scss' | ||
import {Option, Select} from "@/components/construction/Select"; | ||
import {useEffect, useState} from "react"; | ||
import {getInheritedStyleWith} from "@/helpers/block-styles"; | ||
import {useSelector} from "react-redux"; | ||
import {Units} from "@/types/units"; | ||
import FilterSingle from "@/components/Creator/LeftPanel/StylesPanel/Filter/FilterSingle/FilterSingle"; | ||
import FilterDropShadow from "@/components/Creator/LeftPanel/StylesPanel/Filter/FilterDropShadow/FilterDropShadow"; | ||
import classNames from "@/helpers/classNames"; | ||
import Icon from "@/components/construction/Icon/Icon"; | ||
|
||
interface Props { | ||
onChange: (value: string | null, property: string) => void | ||
} | ||
|
||
type SelectedFilter = [id: string, value: any]; | ||
const filterDefaultUnits: [name: string, unit: Units][] = [ | ||
['blur', 'px'], | ||
['brightness', '%'], | ||
['contrast', '%'], | ||
['grayscale', '%'], | ||
['hue-rotate', 'deg'], | ||
['invert', '%'], | ||
['opacity', '%'], | ||
['saturate', '%'], | ||
['sepia', '%'], | ||
]; | ||
const allFiltersNames: [id: string, name: string][] = [ | ||
['blur', 'Rozmycie'], | ||
['brightness', 'Jasność'], | ||
['contrast', 'Kontrast'], | ||
['drop-shadow', 'Cień'], | ||
['grayscale', 'Skala szarości'], | ||
['hue-rotate', 'Obracanie odcienia'], | ||
['invert', 'Odwrócenie kolorów'], | ||
['opacity', 'Nieprzezroczystość'], | ||
['saturate', 'Saturacja'], | ||
['sepia', 'Sepia'], | ||
]; | ||
const filtersDefaultValues: [id: string, value: any][] = [ | ||
['blur', 0], | ||
['brightness', 100], | ||
['contrast', 100], | ||
['drop-shadow', ['0px', '0px', '0px', '#000']], | ||
['grayscale', 0], | ||
['hue-rotate', 0], | ||
['invert', 0], | ||
['opacity', 100], | ||
['saturate', 0], | ||
['sepia', 0], | ||
]; | ||
export default function (props: Props) { | ||
const selectedBlock = useSelector((state: any) => state.structure.selectedBlock); | ||
const rwd = useSelector((state: any) => state.structure.rwdMode); | ||
const styleState = useSelector((state: any) => state.structure.styleState); | ||
const [filter, seFilter] = useState(''); | ||
const [selectedFilters, setSelectedFilters] = useState<SelectedFilter[]>([]); | ||
|
||
const changed = value => { | ||
value = addFilterUnits(value); | ||
props.onChange( | ||
value.map(([id, value]: SelectedFilter) => `${id}(${value})`).join(' '), | ||
'filter' | ||
) | ||
} | ||
const addFilterUnits = value => { | ||
return [...value].map(([id, val]) => { | ||
if(id === 'drop-shadow' ){ | ||
return [id, val.map((v,index)=>{ | ||
if(index===3){ | ||
return v; | ||
} | ||
return `${parseInt(v)}px` | ||
}).join(' ')] | ||
} | ||
const [, unit] = filterDefaultUnits.find(([f_id, _unit]) => f_id === id)! | ||
return [id, `${val}${unit}`] | ||
}); | ||
} | ||
const mapFiltersToArray = (value: string): SelectedFilter[] => { | ||
const filtersArr = value.match(/[\w-]+\([\w.,%\s]+[\(]{1}[\w.,%\s]+[\)]{1}\)|[\w-]+\([\w.,%\s\#]+\)/gm) ?? []; | ||
const getFilterVal = name => filtersArr.find(filterName => filterName.startsWith(name)) | ||
.trim().replace(`${name}(`, '').replace(/\)$/, ''); | ||
const filters: SelectedFilter[] = []; | ||
|
||
filtersArr.forEach(filter => { | ||
const [name] = filter.split('('); | ||
|
||
if (name.includes('drop-shadow')) { | ||
const dropShadow = getFilterVal('drop-shadow'); | ||
const [hShadow, vShadow, blur, color] = dropShadow.match(/\S+\([\d\s,\.]+\)|[\w\#]+/gm); | ||
filters.push([name, [parseInt(hShadow), parseInt(vShadow), parseInt(blur), color]]); | ||
} else { | ||
filters.push([name, parseInt(getFilterVal(name))]); | ||
} | ||
}); | ||
|
||
return filters; | ||
} | ||
|
||
useEffect(() => { | ||
const style = getInheritedStyleWith( | ||
selectedBlock.styles, | ||
rwd, styleState, | ||
['filter'], | ||
) as any; | ||
seFilter(style.filter || ''); | ||
setSelectedFilters(mapFiltersToArray(style.filter || '')); | ||
}, [selectedBlock, rwd, styleState]) | ||
|
||
const addFilter = (filterId: string) => { | ||
const [, defaultValue] = filtersDefaultValues.find(([id, _]) => id === filterId); | ||
const newFilter: SelectedFilter = [filterId, defaultValue]; | ||
setSelectedFilters([...selectedFilters, newFilter]); | ||
changed([...selectedFilters, newFilter]); | ||
} | ||
const removeFilter = index => { | ||
selectedFilters.splice(index, 1); | ||
setSelectedFilters([...selectedFilters]); | ||
changed([...selectedFilters]); | ||
} | ||
const getFiltersList = () => { | ||
return selectedFilters.map(([id, val], index) => { | ||
return <div className={classNames([styles.stylesFormRow, filterStyles.singleFilter])} key={id}> | ||
{id === 'drop-shadow' | ||
? <FilterDropShadow value={val} onChange={e => changedFilter(id, e)}/> | ||
: <FilterSingle filterId={id} value={+val} onChange={e => changedFilter(id, e)}/> | ||
} | ||
<Icon type="material" name="close" onClick={e => removeFilter(index)} className={filterStyles.icon}/> | ||
</div> | ||
} | ||
) | ||
} | ||
const isFilterChosen = (id: string): boolean => { | ||
return selectedFilters.some(([filterId, _]) => id === filterId) | ||
} | ||
|
||
const changedFilter = (id: string, val: any) => { | ||
const index = selectedFilters.findIndex(([filterId, _]) => id === filterId) | ||
selectedFilters[index] = [id, val]; | ||
setSelectedFilters([...selectedFilters]); | ||
changed([...selectedFilters]); | ||
} | ||
|
||
return ( | ||
<div className={styles.stylesFormGroup}> | ||
<div className={styles.stylesFormRow}> | ||
<Select onChange={addFilter} label="Dodaj filtr"> | ||
<Option value="" selected={true}>Wybierz</Option> | ||
{allFiltersNames.map(([id, name]) => | ||
<Option key={id} value={id} disabled={isFilterChosen(id)}>{name}</Option> | ||
)} | ||
</Select> | ||
</div> | ||
|
||
{getFiltersList()} | ||
|
||
</div> | ||
) | ||
} |
39 changes: 39 additions & 0 deletions
39
src/components/Creator/LeftPanel/StylesPanel/Filter/FilterDropShadow/FilterDropShadow.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import styles from "@/components/Creator/LeftPanel/StylesPanel/StylesPanel.module.scss"; | ||
import InputWithUnits from "@/components/construction/InputWithUnits/InputWithUnits"; | ||
import ColorPicker from "@/components/construction/ColorPicker/ColorPicker"; | ||
import {useState} from "react"; | ||
|
||
type ValueType = [x: number, y: number, blur: number, color: string]; | ||
|
||
interface Props { | ||
value: ValueType; | ||
onChange: (value: ValueType) => void; | ||
|
||
} | ||
|
||
export default function (props: Props) { | ||
const [value,setValue] =useState(props.value); | ||
const onChange = (v, index) => { | ||
const val = value; | ||
val[index] = v; | ||
setValue(val) | ||
props.onChange(val); | ||
} | ||
|
||
return ( | ||
<div className={styles.stylesFormColumn}> | ||
<div className={styles.stylesFormField}> | ||
<InputWithUnits units={['px']} value={value[0]} max={20} min={-20} type="number" | ||
label="Przesunięcie w osi X" onChange={e => onChange(e, 0)}/> | ||
<InputWithUnits units={['px']} value={value[1]} max={20} min={-20} type="number" | ||
label="Przesunięcie w osi Y" onChange={e => onChange(e, 1)}/> | ||
</div> | ||
<div className={styles.stylesFormField}> | ||
<InputWithUnits units={['px']} value={value[2]} max={20} min={0} type="number" label="Rozmycie" | ||
onChange={e => onChange(e, 2)}/> | ||
<ColorPicker value={value[3]} onChange={e => onChange(e, 3)}/> | ||
</div> | ||
</div> | ||
) | ||
|
||
} |
53 changes: 53 additions & 0 deletions
53
src/components/Creator/LeftPanel/StylesPanel/Filter/FilterSingle/FilterSingle.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import {Units} from "@/types/units"; | ||
import styles from "@/components/Creator/LeftPanel/StylesPanel/StylesPanel.module.scss"; | ||
import Slider from "@/components/construction/Slider/Slider"; | ||
import {useEffect, useState} from "react"; | ||
|
||
interface Props { | ||
value: number; | ||
filterId: string; | ||
onChange: (value: number) => void; | ||
} | ||
|
||
type FilterDefaults = [id: string, name: string, unit: Units, min: number, max: number]; | ||
export default function (props: Props) { | ||
const [filterDefaults, setFilterDefaults] = useState<{ min: number, max: number }>(null); | ||
const [label, setLabel] = useState<string>(null); | ||
const [unit, setUnit] = useState<Units>(null); | ||
const displayValFn = val => `${val}${unit}`; | ||
|
||
const filters: FilterDefaults[] = [ | ||
['blur', 'Rozmycie', 'px', 0, 100], | ||
['brightness', 'Jasność', '%', 0, 200], | ||
['contrast', 'Kontrast', '%', 0, 200], | ||
['grayscale', 'Skala szarości', '%', 0, 100], | ||
['hue-rotate', 'Obracanie odcienia', 'deg', 0, 360], | ||
['invert', 'Odwrócenie kolorów', '%', 0, 100], | ||
['opacity', 'Nieprzezroczystość', '%', 0, 100], | ||
['saturate', 'Saturacja', '%', 0, 100], | ||
['sepia', 'Sepia', '%', 0, 100], | ||
]; | ||
|
||
const getSingleFilterDefaults = (filterId: string): FilterDefaults => { | ||
return filters.find(([id, ..._]) => id === filterId) | ||
} | ||
|
||
useEffect(() => { | ||
const [, _name, _unit, min, max] = getSingleFilterDefaults(props.filterId); | ||
setLabel(_name); | ||
setUnit(_unit); | ||
setFilterDefaults({min, max}); | ||
}, [props.filterId]) | ||
|
||
return ( | ||
<div className={styles.stylesFormField}> | ||
{filterDefaults ? <Slider label={label} | ||
displayValueFn={displayValFn} | ||
min={filterDefaults?.min} | ||
max={filterDefaults?.max} | ||
onChange={props.onChange} | ||
value={props.value}/> : ''} | ||
</div> | ||
) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters