그림 셰이프

그림 셰이프는 그림을 표시할 수 있는 셰이프입니다. 자르고 조정할 수 있으며 다른 셰이프와 함께 그림을 그룹화하거나 연결할 수 있습니다.

설명
app.jsx
app-func.jsx
app-class.jsx
index.html
styles.css

다음 샘플은 그림 셰이프를 추가하는 방법을 보여 줍니다.

    // When adding a picture, the picture's source can be a base64 image or url.
    var picture = sheet.shapes.addPictureShape("pic1", "./test.png", 100, 100, 200, 200);

다음 예시는 그림의 투명도를 변경하는 방법을 보여 줍니다.

    // Set the transparency of the picture to 0.5
    picture.pictureFormat({ transparency: 0.5 });

다음 예시는 그림을 자르는 방법을 보여 줍니다.

    picture.pictureFormat({
        crop: {
            left: 0.15, // The left 15% of the image will be cropped
            right: 0.15, // The right 15% of the image will be cropped
            top: 0.2, // The top 20% of the image will be cropped
            bottom: 0.2 // The bottom 20% of the image will be cropped
        }
    });

다음 예시는 그림의 밝기 및 대비를 설정하는 방법을 보여 줍니다.

    // Set the brightness and contrast of the picture
    picture.pictureFormat({ brightness: 0.4, contrast: -0.4 });

다음 예시는 그림을 다시 칠하는 방법을 보여 줍니다.

    // Set the grayscale effect
    picture.pictureFormat({ grayscale: true });

    // Set blackAndWhite effect
    // Pixels with brightness greater than or equal to 0.5 are white, otherwise black
    picture.pictureFormat({ blackAndWhite: 0.5 });

    // Set the duotone effect
    picture.pictureFormat({ duotone: { color1: 'black', color2: 'red' } });

다음 예시는 그림의 기하 도형 유형을 변경하는 방법을 보여 줍니다.

    // Change the geometry type of the picture to oval
    picture.geometryType(GC.Spread.Sheets.Shapes.AutoShapeType.oval);

    // Change the geometry type of the picture to roundedRectangle
    picture.geometryType(GC.Spread.Sheets.Shapes.AutoShapeType.roundedRectangle)

다음 예시는 그림의 테두리를 설정하는 방법을 보여 줍니다.

    var style = picture.style();
    style.line.color = 'red';
    style.line.lineStyle = GC.Spread.Sheets.Shapes.PresetLineDashStyle.dashDot;
    style.line.width = 4;
    style.line.capType = GC.Spread.Sheets.Shapes.LineCapStyle.square;
    style.line.joinType = GC.Spread.Sheets.Shapes.LineJoinStyle.miter;
    picture.style(style);

그림의 일부가 투명하면 그림의 배경색을 설정할 수 있습니다.

    let style = picture.style();
    style.fill = { type: GC.Spread.Sheets.Shapes.ShapeFillType.solid, color: 'blue' };
    picture.style(style);
다음 샘플은 그림 셰이프를 추가하는 방법을 보여 줍니다. 다음 예시는 그림의 투명도를 변경하는 방법을 보여 줍니다. 다음 예시는 그림을 자르는 방법을 보여 줍니다. 다음 예시는 그림의 밝기 및 대비를 설정하는 방법을 보여 줍니다. 다음 예시는 그림을 다시 칠하는 방법을 보여 줍니다. 다음 예시는 그림의 기하 도형 유형을 변경하는 방법을 보여 줍니다. 다음 예시는 그림의 테두리를 설정하는 방법을 보여 줍니다. 그림의 일부가 투명하면 그림의 배경색을 설정할 수 있습니다.
import * as React from 'react'; import * as ReactDOM from 'react-dom'; import './styles.css'; import { AppFunc } from './app-func'; // import { App } from './app-class'; // 1. Functional Component sample ReactDOM.render(<AppFunc />, document.getElementById('app')); // 2. Class Component sample // ReactDOM.render(<App />, document.getElementById('app'));
import * as React from 'react'; import GC from '@mescius/spread-sheets'; import "@mescius/spread-sheets-shapes"; import { SpreadSheets } from "@mescius/spread-sheets-react"; import '@mescius/spread-sheets-resources-ko'; GC.Spread.Common.CultureManager.culture("ko-kr"); let spread = null; let sheet = null; export function AppFunc() { const [pictureShapeOption, setPictureShapeOption] = React.useState({ active: false, isShow: false, geometryType: 1, crop: { left: 0, right: 0, top: 0, bottom: 0 }, transparency: 0, brightness: 0, contrast: 0, recolorType: 'none', blackAndWhite: 0.5, duotoneColor1: '#000000', duotoneColor2: '#FF0000', backgroundColor: '', borderColor: '', borderWidth: -1 }); const initSpread = (currSpread) => { spread = currSpread; sheet = spread.getActiveSheet(); sheet.bind(GC.Spread.Sheets.Events.ShapeSelectionChanged, shapeSelectionChangedHandler); addDefaultShape(); } const addDefaultShape = () => { var splogoImg = "data:image/png;base64,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"; var foodImg = "data:image/jpeg;base64,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"; var pic1 = sheet.shapes.addPictureShape('pic1', splogoImg, 80, 80, 150, 150); var pic2 = sheet.shapes.addPictureShape('pic2', splogoImg, 310, 80, 150, 150); var pic3 = sheet.shapes.addPictureShape('pic3', splogoImg, 540, 80, 150, 150); var pic4 = sheet.shapes.addPictureShape('pic4', foodImg, 80, 300, 285, 180); var pic5 = sheet.shapes.addPictureShape('pic5', foodImg, 420, 300, 285, 180); pic1.isSelected(true); // set pic2 style var style = pic2.style(); style.fill = { type: 1, color: '#666666' }; pic2.style(style); // set pic3 geometry type pic3.geometryType(GC.Spread.Sheets.Shapes.AutoShapeType.roundedRectangle); // set pic3 style var style = pic3.style(); style.fill = { type: 1, color: '#666666' }; pic3.style(style); // set pic5 duotone effect pic5.pictureFormat({ duotone: { color1: 'black', color2: 'rgb(150, 242, 21)' } }); } const shapeSelectionChangedHandler = () => { var pictures = getSelectedPictures(); var active = pictures.length === 1; if (active) { syncState(pictures[0]); } } const syncState = (pic) => { let geometryType = pic.geometryType(); let format = pic.pictureFormat(); let style = pic.style(); let newState = { ...pictureShapeOption, geometryType, crop: format.crop, transparency: format.transparency, brightness: format.brightness, contrast: format.contrast, recolorType: 'none', isShow: false, active: true }; if (format.grayscale) { newState.recolorType = 'gray-scale'; } else if (format.blackAndWhite !== undefined) { newState.recolorType = 'black-and-white'; newState.blackAndWhite = format.blackAndWhite; } else if (format.duotone) { newState.recolorType = 'duotone'; newState.isShow = true; newState.duotoneColor1 = rgbToHex(format.duotone.color1); newState.duotoneColor2 = rgbToHex(format.duotone.color2); } newState.backgroundColor = rgbToHex(style.fill.color); newState.borderColor = rgbToHex(style.line.color); newState.borderWidth = style.line.width; setPictureShapeOption(newState); } const onImgChange = (e) => { var blob = e.target.files[0]; var fileReader = new FileReader(); fileReader.addEventListener('load', function () { getFirstSelectedPicture().src(fileReader.result); }); fileReader.readAsDataURL(blob); } const onGeometryTypeChange = (e) => { let value = Number(e.target.value); setPictureShapeOption({ ...pictureShapeOption, geometryType: value }); getFirstSelectedPicture().geometryType(value); } const onCropPropChange = (e, propName) => { let value = Number(e.target.value); let crop = JSON.parse(JSON.stringify(pictureShapeOption.crop)); crop[propName] = value; setPictureShapeOption({ ...pictureShapeOption, crop }); let pic = getFirstSelectedPicture(); var format = pic.pictureFormat(); format.crop = crop; pic.pictureFormat(format); } const onPictureFormatChange = (e, propName) => { let value = e.target.value; let numberValue = Number(value); let pic = getFirstSelectedPicture(); var format = pic.pictureFormat(); if (propName === 'transparency') { format.transparency = numberValue; } else if (propName === 'brightness') { format.brightness = numberValue; } else if (propName === 'contrast') { format.contrast = numberValue; } else if (propName === 'recolorType') { clearRecolorAndBrightnessContrast(format); if (value === 'gray-scale') { format.grayscale = true; } else if (value === 'black-and-white') { format.blackAndWhite = pictureShapeOption.blackAndWhite; } else if (value === 'duotone') { format.duotone = { color1: pictureShapeOption.duotoneColor1, color2: pictureShapeOption.duotoneColor2 } } } else if (propName === 'blackAndWhite') { clearRecolorAndBrightnessContrast(format); format.blackAndWhite = numberValue; } else if (propName === 'duotoneColor1') { clearRecolorAndBrightnessContrast(format); format.duotone = { color1: value, color2: pictureShapeOption.duotoneColor2 } } else if (propName === 'duotoneColor2') { clearRecolorAndBrightnessContrast(format); format.duotone = { color1: pictureShapeOption.duotoneColor1, color2: value } } pic.pictureFormat(format); syncState(pic); } const clearRecolorAndBrightnessContrast = (format) => { format.grayscale = false; format.blackAndWhite = undefined; format.duotone = undefined; format.brightness = 0; format.contrast = 0; } const onBackgroundColorChange = (e) => { let value = e.target.value; setPictureShapeOption({ ...pictureShapeOption, backgroundColor: value }); var picture = getFirstSelectedPicture(); var style = picture.style(); style.fill = { type: 1, color: value, transparency: 0 }; picture.style(style); } const onBorderColorChange = (e) => { let value = e.target.value; setPictureShapeOption({ ...pictureShapeOption, borderColor: value }); var picture = getFirstSelectedPicture(); var style = picture.style(); style.line.color = value; picture.style(style); } const onBorderWidthChange = (e) => { let value = Number(e.target.value); setPictureShapeOption({ ...pictureShapeOption, borderWidth: value }); var picture = getFirstSelectedPicture(); var style = picture.style(); style.line.color = pictureShapeOption.borderColor; style.line.width = value; picture.style(style); } const getSelectedPictures = () => { var pictures = []; var shapes = sheet.shapes.all(); for (var i = 0; i < shapes.length; i++) { var shape = shapes[i]; if (shape.isSelected() && shape instanceof GC.Spread.Sheets.Shapes.PictureShape) { pictures.push(shape); } } return pictures; } const rgbToHex = (color) => { let rgb = color.match(/rgb\((\d+),(\d+),(\d+)\)/); if (!rgb || rgb.length < 4) { return '#000000'; } return '#' + rgb.slice(1, 4).map(function (v) { let hex = Number(v).toString(16); return hex.length === 1 ? "0" + hex : hex; }).join(''); } const getFirstSelectedPicture = () => { return getSelectedPictures()[0]; } const tipEl = <div class="options-container">Try selecting a shape.</div>; let duotone; if (pictureShapeOption.isShow) { duotone = <div> <div class="option-row"> <label>Duotone Color1</label><input class="duotone-color1" type="color" value={pictureShapeOption.duotoneColor1} onChange={(e) => onPictureFormatChange(e, 'duotoneColor1')}></input> </div> <div class="option-row"> <label>Duotone Color2</label><input class="duotone-color2" type="color" value={pictureShapeOption.duotoneColor2} onChange={(e) => onPictureFormatChange(e, 'duotoneColor2')}></input> </div> </div> } const picturePropEl = <div class="options-container"> <h3>Picture Format</h3> <div class="option-row"> <label>Image</label><input class="img" type="file" accept="image/*" onChange={onImgChange}></input> </div> <div class="option-row"> <label>Geometry Type</label> <select class="geometry-type" value={pictureShapeOption.geometryType} onChange={onGeometryTypeChange}> <option value="1">rectangle</option> <option value="5">rounded rectangle</option> <option value="9">oval</option> <option value="21">heart</option> <option value="178">cloud</option> </select> </div> <div class="option-row"> <label>Transparency</label><input class="transparency" type="number" min="0" max="1" step="0.01" value={pictureShapeOption.transparency} onChange={(e) => onPictureFormatChange(e, 'transparency')}></input> </div> <div class="divide-line"></div> <details> <summary>Crop</summary> <div class="option-row"> <label>Crop Left</label><input class="crop-left" type="number" max="0.99" step="0.01" value={pictureShapeOption.crop.left} onChange={(e) => onCropPropChange(e, 'left')}></input> </div> <div class="option-row"> <label>Crop Right</label><input class="crop-right" type="number" max="0.99" step="0.01" value={pictureShapeOption.crop.right} onChange={(e) => onCropPropChange(e, 'right')}></input> </div> <div class="option-row"> <label>Crop Top</label><input class="crop-top" type="number" max="0.99" step="0.01" value={pictureShapeOption.crop.top} onChange={(e) => onCropPropChange(e, 'top')}></input> </div> <div class="option-row"> <label>Crop Bottom</label><input class="crop-bottom" type="number" max="0.99" step="0.01" value={pictureShapeOption.crop.bottom} onChange={(e) => onCropPropChange(e, 'bottom')}></input> </div> </details> <div class="divide-line"></div> <details> <summary>Brightness/Contrast</summary> <div class="option-row"> <label>Brightness</label><input class="brightness" type="number" min="-1" max="1" step="0.01" value={pictureShapeOption.brightness} onChange={(e) => onPictureFormatChange(e, 'brightness')}></input> </div> <div class="option-row"> <label>Contrast</label><input class="contrast" type="number" min="-1" max="1" step="0.01" value={pictureShapeOption.contrast} onChange={(e) => onPictureFormatChange(e, 'contrast')}></input> </div> </details> <div class="divide-line"></div> <details> <summary>Recolor</summary> <div class="option-row"> <label>Recolor Type</label> <select class="recolor-type" value={pictureShapeOption.recolorType} onChange={(e) => onPictureFormatChange(e, 'recolorType')}> <option value="none">none</option> <option value="gray-scale">grayscale</option> <option value="black-and-white">blackAndWhite</option> <option value="duotone">duotone</option> </select> </div> <div class="option-row"> <label>BlackAndWhite</label><input class="black-and-white" type="number" min="0" max="1" step="0.05" value={pictureShapeOption.blackAndWhite} onChange={(e) => onPictureFormatChange(e, 'blackAndWhite')}></input> </div> {duotone} </details> <div class="divide-line"></div> <details> <summary>Style</summary> <div class="option-row"> <label>Background Color</label><input class="background-color" type="color" value={pictureShapeOption.backgroundColor} onChange={onBackgroundColorChange}></input> </div> <div class="option-row"> <label>Border Color</label><input class="border-color" type="color" value={pictureShapeOption.borderColor} onChange={onBorderColorChange}></input> </div> <div class="option-row"> <label>Border Width</label><input class="border-width" type="number" min="-1" step="1" value={pictureShapeOption.borderWidth} onChange={onBorderWidthChange}></input> </div> </details> </div>; return ( <div class="sample-tutorial"> <div id="ss" class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => initSpread(spread)}> </SpreadSheets> </div> {pictureShapeOption.active ? picturePropEl : tipEl} </div> ); }
import * as React from 'react'; import GC from '@mescius/spread-sheets'; import "@mescius/spread-sheets-shapes"; import { SpreadSheets } from "@mescius/spread-sheets-react"; import '@mescius/spread-sheets-resources-ko'; GC.Spread.Common.CultureManager.culture("ko-kr"); const Component = React.Component; export class App extends Component { constructor(props) { super(props); this.spread = null; this.state = { active: false, isShow: false, geometryType: 1, crop: { left: 0, right: 0, top: 0, bottom: 0 }, transparency: 0, brightness: 0, contrast: 0, recolorType: 'none', blackAndWhite: 0.5, duotoneColor1: '#000000', duotoneColor2: '#FF0000', backgroundColor: '', borderColor: '', borderWidth: -1 } this.shapeSelectionChangedHandler = this.shapeSelectionChangedHandler.bind(this); this.onImgChange = this.onImgChange.bind(this); this.onGeometryTypeChange = this.onGeometryTypeChange.bind(this); this.onCropPropChange = this.onCropPropChange.bind(this); this.onPictureFormatChange = this.onPictureFormatChange.bind(this); this.onBackgroundColorChange = this.onBackgroundColorChange.bind(this); this.onBorderColorChange = this.onBorderColorChange.bind(this); this.onBorderWidthChange = this.onBorderWidthChange.bind(this); } render() { const tipEl = <div class="options-container">Try selecting a shape.</div>; let duotone; if (this.state.isShow) { duotone = <div> <div class="option-row"> <label>Duotone Color1</label><input class="duotone-color1" type="color" value={this.state.duotoneColor1} onChange={(e) => this.onPictureFormatChange(e, 'duotoneColor1')}></input> </div> <div class="option-row"> <label>Duotone Color2</label><input class="duotone-color2" type="color" value={this.state.duotoneColor2} onChange={(e) => this.onPictureFormatChange(e, 'duotoneColor2')}></input> </div> </div> } const picturePropEl = <div class="options-container"> <h3>Picture Format</h3> <div class="option-row"> <label>Image</label><input class="img" type="file" accept="image/*" onChange={this.onImgChange}></input> </div> <div class="option-row"> <label>Geometry Type</label> <select class="geometry-type" value={this.state.geometryType} onChange={this.onGeometryTypeChange}> <option value="1">rectangle</option> <option value="5">rounded rectangle</option> <option value="9">oval</option> <option value="21">heart</option> <option value="178">cloud</option> </select> </div> <div class="option-row"> <label>Transparency</label><input class="transparency" type="number" min="0" max="1" step="0.01" value={this.state.transparency} onChange={(e) => this.onPictureFormatChange(e, 'transparency')}></input> </div> <div class="divide-line"></div> <details> <summary>Crop</summary> <div class="option-row"> <label>Crop Left</label><input class="crop-left" type="number" max="0.99" step="0.01" value={this.state.crop.left} onChange={(e) => this.onCropPropChange(e, 'left')}></input> </div> <div class="option-row"> <label>Crop Right</label><input class="crop-right" type="number" max="0.99" step="0.01" value={this.state.crop.right} onChange={(e) => this.onCropPropChange(e, 'right')}></input> </div> <div class="option-row"> <label>Crop Top</label><input class="crop-top" type="number" max="0.99" step="0.01" value={this.state.crop.top} onChange={(e) => this.onCropPropChange(e, 'top')}></input> </div> <div class="option-row"> <label>Crop Bottom</label><input class="crop-bottom" type="number" max="0.99" step="0.01" value={this.state.crop.bottom} onChange={(e) => this.onCropPropChange(e, 'bottom')}></input> </div> </details> <div class="divide-line"></div> <details> <summary>Brightness/Contrast</summary> <div class="option-row"> <label>Brightness</label><input class="brightness" type="number" min="-1" max="1" step="0.01" value={this.state.brightness} onChange={(e) => this.onPictureFormatChange(e, 'brightness')}></input> </div> <div class="option-row"> <label>Contrast</label><input class="contrast" type="number" min="-1" max="1" step="0.01" value={this.state.contrast} onChange={(e) => this.onPictureFormatChange(e, 'contrast')}></input> </div> </details> <div class="divide-line"></div> <details> <summary>Recolor</summary> <div class="option-row"> <label>Recolor Type</label> <select class="recolor-type" value={this.state.recolorType} onChange={(e) => this.onPictureFormatChange(e, 'recolorType')}> <option value="none">none</option> <option value="gray-scale">grayscale</option> <option value="black-and-white">blackAndWhite</option> <option value="duotone">duotone</option> </select> </div> <div class="option-row"> <label>BlackAndWhite</label><input class="black-and-white" type="number" min="0" max="1" step="0.05" value={this.state.blackAndWhite} onChange={(e) => this.onPictureFormatChange(e, 'blackAndWhite')}></input> </div> {duotone} </details> <div class="divide-line"></div> <details> <summary>Style</summary> <div class="option-row"> <label>Background Color</label><input class="background-color" type="color" value={this.state.backgroundColor} onChange={this.onBackgroundColorChange}></input> </div> <div class="option-row"> <label>Border Color</label><input class="border-color" type="color" value={this.state.borderColor} onChange={this.onBorderColorChange}></input> </div> <div class="option-row"> <label>Border Width</label><input class="border-width" type="number" min="-1" step="1" value={this.state.borderWidth} onChange={this.onBorderWidthChange}></input> </div> </details> </div>; return ( <div class="sample-tutorial"> <div id="ss" class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => this.initSpread(spread)}> </SpreadSheets> </div> {this.state.active ? picturePropEl : tipEl} </div> ); } initSpread(spread) { this.spread = spread; this.sheet = this.spread.getActiveSheet(); this.sheet.bind(GC.Spread.Sheets.Events.ShapeSelectionChanged, this.shapeSelectionChangedHandler); this.addDefaultShape(); } addDefaultShape() { var sheet = this.sheet; var splogoImg = "data:image/png;base64,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"; var foodImg = "data:image/jpeg;base64,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"; var pic1 = sheet.shapes.addPictureShape('pic1', splogoImg, 80, 80, 150, 150); var pic2 = sheet.shapes.addPictureShape('pic2', splogoImg, 310, 80, 150, 150); var pic3 = sheet.shapes.addPictureShape('pic3', splogoImg, 540, 80, 150, 150); var pic4 = sheet.shapes.addPictureShape('pic4', foodImg, 80, 300, 285, 180); var pic5 = sheet.shapes.addPictureShape('pic5', foodImg, 420, 300, 285, 180); pic1.isSelected(true); // set pic2 style var style = pic2.style(); style.fill = { type: 1, color: '#666666' }; pic2.style(style); // set pic3 geometry type pic3.geometryType(GC.Spread.Sheets.Shapes.AutoShapeType.roundedRectangle); // set pic3 style var style = pic3.style(); style.fill = { type: 1, color: '#666666' }; pic3.style(style); // set pic5 duotone effect pic5.pictureFormat({ duotone: { color1: 'black', color2: 'rgb(150, 242, 21)' } }); } shapeSelectionChangedHandler() { var pictures = this.getSelectedPictures(); var active = pictures.length === 1; this.setState({ active }); if (active) { this.syncState(pictures[0]); } } syncState(pic) { let geometryType = pic.geometryType(); let format = pic.pictureFormat(); let style = pic.style(); let newState = { geometryType, crop: format.crop, transparency: format.transparency, brightness: format.brightness, contrast: format.contrast, recolorType: 'none', isShow: false }; if (format.grayscale) { newState.recolorType = 'gray-scale'; } else if (format.blackAndWhite !== undefined) { newState.recolorType = 'black-and-white'; newState.blackAndWhite = format.blackAndWhite; } else if (format.duotone) { newState.recolorType = 'duotone'; newState.isShow = true; newState.duotoneColor1 = this.rgbToHex(format.duotone.color1); newState.duotoneColor2 = this.rgbToHex(format.duotone.color2); } newState.backgroundColor = this.rgbToHex(style.fill.color); newState.borderColor = this.rgbToHex(style.line.color); newState.borderWidth = style.line.width; this.setState(newState); } onImgChange(e) { var self = this; var blob = e.target.files[0]; var fileReader = new FileReader(); fileReader.addEventListener('load', function () { self.getFirstSelectedPicture().src(fileReader.result); }); fileReader.readAsDataURL(blob); } onGeometryTypeChange(e) { let value = Number(e.target.value); this.setState({ geometryType: value }); this.getFirstSelectedPicture().geometryType(value); } onCropPropChange(e, propName) { let value = Number(e.target.value); let crop = JSON.parse(JSON.stringify(this.state.crop)); crop[propName] = value; this.setState({ crop }); let pic = this.getFirstSelectedPicture(); var format = pic.pictureFormat(); format.crop = crop; pic.pictureFormat(format); } onPictureFormatChange(e, propName) { let value = e.target.value; let numberValue = Number(value); let pic = this.getFirstSelectedPicture(); var format = pic.pictureFormat(); if (propName === 'transparency') { format.transparency = numberValue; } else if (propName === 'brightness') { format.brightness = numberValue; } else if (propName === 'contrast') { format.contrast = numberValue; } else if (propName === 'recolorType') { this.clearRecolorAndBrightnessContrast(format); if (value === 'gray-scale') { format.grayscale = true; } else if (value === 'black-and-white') { format.blackAndWhite = this.state.blackAndWhite; } else if (value === 'duotone') { format.duotone = { color1: this.state.duotoneColor1, color2: this.state.duotoneColor2 } } } else if (propName === 'blackAndWhite') { this.clearRecolorAndBrightnessContrast(format); format.blackAndWhite = numberValue; } else if (propName === 'duotoneColor1') { this.clearRecolorAndBrightnessContrast(format); format.duotone = { color1: value, color2: this.state.duotoneColor2 } } else if (propName === 'duotoneColor2') { this.clearRecolorAndBrightnessContrast(format); format.duotone = { color1: this.state.duotoneColor1, color2: value } } pic.pictureFormat(format); this.syncState(pic); } clearRecolorAndBrightnessContrast(format) { format.grayscale = false; format.blackAndWhite = undefined; format.duotone = undefined; format.brightness = 0; format.contrast = 0; } onBackgroundColorChange(e) { let value = e.target.value; this.setState({ backgroundColor: value }); var picture = this.getFirstSelectedPicture(); var style = picture.style(); style.fill = { type: 1, color: value, transparency: 0 }; picture.style(style); } onBorderColorChange(e) { let value = e.target.value; this.setState({ borderColor: value }); var picture = this.getFirstSelectedPicture(); var style = picture.style(); style.line.color = value; picture.style(style); } onBorderWidthChange(e) { let value = Number(e.target.value); this.setState({ borderWidth: value }); var picture = this.getFirstSelectedPicture(); var style = picture.style(); style.line.color = this.state.borderColor; style.line.width = value; picture.style(style); } getSelectedPictures() { var pictures = []; var shapes = this.sheet.shapes.all(); for (var i = 0; i < shapes.length; i++) { var shape = shapes[i]; if (shape.isSelected() && shape instanceof GC.Spread.Sheets.Shapes.PictureShape) { pictures.push(shape); } } return pictures; } rgbToHex(color) { let rgb = color.match(/rgb\((\d+),(\d+),(\d+)\)/); if (!rgb || rgb.length < 4) { return '#000000'; } return '#' + rgb.slice(1, 4).map(function (v) { let hex = Number(v).toString(16); return hex.length === 1 ? "0" + hex : hex; }).join(''); } getFirstSelectedPicture() { return this.getSelectedPictures()[0]; } }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/ko/react/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <!-- SystemJS --> <script src="$DEMOROOT$/ko/react/node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('$DEMOROOT$/ko/lib/react/license.js').then(function () { System.import('./src/app'); }); </script> </head> <body> <div id="app"></div> </body> </html>
body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } #app { width: 100%; height: 100%; } .sample-tutorial { position: relative; height: 100%; overflow: hidden; } .sample-spreadsheets { width: calc(100% - 300px); height: 100%; overflow: hidden; } .options-container { position: absolute; top: 0px; right: 0px; width: 300px; height: 100%; padding: 12px; box-sizing: border-box; background: #fbfbfb; overflow: auto; } h3 { text-align: center; } .option-row { background: #fbfbfb; position: relative; margin: 12px 0px; } details { margin: 12px 0px; } .option-row input { position: absolute; box-sizing: border-box; right: 20px; width: 126px; height: 26px; } .option-row select { position: absolute; right: 20px; width: 126px; height: 26px; } .divide-line { width: 100%; height: 1px; background: #cbcbcb; margin-top: 10px; margin-bottom: 3px; }
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true, react: true }, meta: { '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-shapes': 'npm:@mescius/spread-sheets-shapes/index.js', '@mescius/spread-sheets-resources-ko': 'npm:@mescius/spread-sheets-resources-ko/index.js', '@mescius/spread-sheets-react': 'npm:@mescius/spread-sheets-react/index.js', '@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js', 'react': 'npm:react/umd/react.production.min.js', 'react-dom': 'npm:react-dom/umd/react-dom.production.min.js', 'css': 'npm:systemjs-plugin-css/css.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', 'systemjs-babel-build':'npm:systemjs-plugin-babel/systemjs-babel-browser.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'jsx' }, "node_modules": { defaultExtension: 'js' }, } }); })(this);