Css.tsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import { Form, Switch, Button, Popover, Select } from 'antd';
  2. import hljs from 'highlight.js/lib/core';
  3. import { useEffect, useState } from 'react';
  4. import { ChromePicker } from 'react-color';
  5. import styled from 'styled-components';
  6. import shallow from 'zustand/shallow';
  7. import { rgbToString } from './Output';
  8. import { SectionTitle } from './SectionTitle';
  9. import SliderInput from './SliderInput';
  10. import { useInputStore } from '~/components/store';
  11. export const CssControls = () => {
  12. const [setCssProps, filterProps] = useInputStore(
  13. (state) => [state.setCssProps, state.filterProps],
  14. shallow
  15. );
  16. const { brightness, contrast } = filterProps;
  17. const [angle, setAngle] = useState(112);
  18. const [posX, setPosX] = useState(50);
  19. const [posY, setPosY] = useState(50);
  20. const [showTransparency, setShowTransparency] = useState(true);
  21. const [gradientType, setGradientType] = useState('linear');
  22. const [color1, setColor1] = useState({ r: 0, g: 0, b: 255, a: 1 });
  23. const [color2, setColor2] = useState({ r: 0, g: 0, b: 255, a: 0 });
  24. useEffect(() => {
  25. setCssProps({
  26. gradientType,
  27. color1: color1,
  28. color2: color2,
  29. angle,
  30. showTransparency,
  31. posX,
  32. posY,
  33. });
  34. }, [
  35. setCssProps,
  36. showTransparency,
  37. contrast,
  38. brightness,
  39. angle,
  40. gradientType,
  41. color1,
  42. color2,
  43. posX,
  44. posY,
  45. ]);
  46. const gradientFirstParam =
  47. gradientType === 'linear'
  48. ? `${angle}deg`
  49. : gradientType === 'radial'
  50. ? `circle at ${posX}% ${posY}%`
  51. : `from ${angle}deg at ${posX}% ${posY}%`;
  52. const gradientCss = `/* css gradient: second layer */
  53. {
  54. width: 250px;
  55. height: 250px;
  56. background: ${gradientType}-gradient(${gradientFirstParam}, ${rgbToString(color1)}, ${rgbToString(
  57. color2
  58. )})${showTransparency ? ', url(/checkers.png)' : ''};
  59. /* filter: contrast(${contrast}%) brightness(${brightness}%); */
  60. }`;
  61. return (
  62. <div>
  63. <SectionTitle title="2. CSS Gradient" />
  64. <pre className="hljs">
  65. <code
  66. dangerouslySetInnerHTML={{
  67. __html: hljs.highlight(gradientCss, { language: 'css' }).value,
  68. }}
  69. />
  70. </pre>
  71. <Form>
  72. <GradientControls>
  73. <div>
  74. <Form.Item label="Gradient type">
  75. <Select
  76. value={gradientType}
  77. onChange={(v) => setGradientType(v)}
  78. style={{ width: 120 }}
  79. >
  80. <Select.Option value="linear">linear</Select.Option>
  81. <Select.Option value="radial">radial</Select.Option>
  82. <Select.Option value="conic">conic</Select.Option>
  83. </Select>
  84. </Form.Item>
  85. </div>
  86. <ColorPick>
  87. <Popover
  88. placement="bottom"
  89. style={{ padding: 0 }}
  90. content={<ChromePicker color={color1} onChange={(c) => setColor1(c.rgb)} />}
  91. trigger="click"
  92. >
  93. <Button>Color 1</Button>
  94. </Popover>
  95. </ColorPick>
  96. <ColorPick>
  97. <Popover
  98. placement="bottom"
  99. content={<ChromePicker color={color2} onChange={(c) => setColor2(c.rgb)} />}
  100. trigger="click"
  101. >
  102. <Button>Color 2</Button>
  103. </Popover>
  104. </ColorPick>
  105. </GradientControls>
  106. {['linear', 'conic'].includes(gradientType) && (
  107. <SliderInput
  108. label="angle"
  109. name="angle"
  110. min={0}
  111. max={360}
  112. tipFormatter={(v) => `${v}°`}
  113. onChange={(val: number) => setAngle(val)}
  114. value={typeof angle === 'number' ? angle : 0}
  115. />
  116. )}
  117. {['radial', 'conic'].includes(gradientType) && (
  118. <>
  119. <SliderInput
  120. label="position X"
  121. name="position X"
  122. min={-50}
  123. max={150}
  124. onChange={(val: number) => setPosX(val)}
  125. value={typeof posX === 'number' ? posX : 0}
  126. />
  127. <SliderInput
  128. label="position Y"
  129. name="position Y"
  130. min={-50}
  131. max={150}
  132. onChange={(val: number) => setPosY(val)}
  133. value={typeof posY === 'number' ? posY : 0}
  134. />
  135. </>
  136. )}
  137. <Form.Item label="Show checkered">
  138. <Switch
  139. size="small"
  140. checked={showTransparency}
  141. onChange={(e) => setShowTransparency(e)}
  142. />
  143. </Form.Item>
  144. </Form>
  145. </div>
  146. );
  147. };
  148. const GradientControls = styled.div`
  149. display: flex;
  150. `;
  151. const ColorPick = styled.div`
  152. margin-left: 15px;
  153. `;