react实现一个css边框图片生成器效果代码

代码语言:html

所属分类:布局界面

代码描述:react实现一个css边框图片生成器效果代码,可自己上传图片生成一个边框图片。

代码标签: css 边框 图片 成器 效果

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开


<!DOCTYPE html>
<html lang="en" >

<head>

  <meta charset="UTF-8">

  <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/babel.min.js"></script>
  
<style>
@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap");
:root {
  --base-space: 8px;
  --color-body: #101820;
  --color-accent: #f9ea00;
  --color-main: #fafafa;
}

*,
*::after,
*::before {
  box-sizing: border-box;
}

body {
  background-color: var(--color-main);
  color: var(--color-body);
  margin: 0;
  padding: calc(var(--base-space) * 2);
  font-family: "Montserrat", sans-serif;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-size: calc(var(--base-space) * 2);
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
}

p {
  margin-top: 0;
}

.display-block {
  display: block;
}

.txt-weight-bold {
  font-weight: 700;
}

.txt-size-2 {
  font-size: calc(var(--base-space) * 2);
}

.txt-size-3 {
  font-size: calc(var(--base-space) * 3);
}

.margin-bottom-1 {
  margin-bottom: var(--base-space);
}

.margin-bottom-2 {
  margin-bottom: calc(var(--base-space) * 2);
}

.margin-bottom-3 {
  margin-bottom: calc(var(--base-space) * 3);
}

.margin-bottom-4 {
  margin-bottom: calc(var(--base-space) * 3);
}

h1,
h2 {
  margin-bottom: 0.35em;
}

h1 {
  font-size: calc(var(--base-space) * 6);
  font-weight: 700;
}

h2 {
  font-size: calc(var(--base-space) * 4);
  font-weight: 700;
}

h3 {
  font-size: calc(var(--base-space) * 2);
  font-weight: 700;
}

code {
  background-color: var(--color-main);
  display: block;
  padding: calc(var(--base-space) * 2);
  white-space: normal;
}

.App {
  background-color: white;
  box-shadow: 0px 3px 20px 0px rgba(0, 0, 0, 0.15);
  border-radius: calc(var(--base-space) * 2);
  margin: 0 auto;
  padding: calc(var(--base-space) * 4);
  display: flex;
  flex-wrap: wrap;
  gap: calc(var(--base-space) * 4);
}

.App__title {
  text-align: center;
  flex: 0 0 100%;
}

.App__column {
  flex: 1 1 45%;
}

.Section {
  margin-bottom: calc(var(--base-space) * 5);
}

.HandlersWrapper {
  position: relative;
  display: table;
}

.DemoList {
  display: flex;
  gap: calc(var(--base-space) * 2);
}

.DemoList__button {
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  background: none;
  border: none;
  padding: 0;
}

.DemoList__item {
  flex: 0 1 80px;
}

.DemoList__thumbnail {
  display: block;
  width: 100%;
}

.DemoText {
  font-size: 2em;
  text-align: center;
  padding: 0.25em;
}
</style>



</head>

<body>
  <div id="app"></div>

  
      <script  type="module">
import React, {
useEffect,
useRef,
useState } from
"https://cdn.skypack.dev/react";
import ReactDOM from "https://cdn.skypack.dev/react-dom";
import { Rnd } from "https://cdn.skypack.dev/react-rnd";

const getImageFromInput = function (input) {
  if (!input) return;

  return new Promise((resolve, reject) => {
    const file = new FileReader();
    const img = new Image();

    file.onloadend = fileData => {
      img.onload = () => {
        resolve(img);
      };

      img.src = fileData.target.result;
    };

    img.onerror = reject;
    file.onerror = reject;
    file.readAsDataURL(input);
  });
};

const HANDLER_STYLE = {
  display: "flex",
  alignItems: "center",
  justifyContent: "center",
  background: "rgba(0,0,0,0.3)",
  border: "solid 1px black",
  opacity: 0.7 };


const Handler = function ({
  position,
  size,
  onPositionChange,
  onSizeChange,
  style = {},
  children })
{
  const handlePositionChange = (e, d) => {
    if (onPositionChange)
    onPositionChange({ x: Math.round(d.x), y: Math.round(d.y) });
  };

  const handleSizeChange = (e, direction, ref, delta, position) => {
    if (onSizeChange)
    onSizeChange({
      ...position,
      // keeping it all numbers for consistency
      width: Math.round(parseInt(ref.style.width)),
      height: Math.round(parseInt(ref.style.height)) });

  };

  return /*#__PURE__*/(
    React.createElement(Rnd, {
      style: { ...HANDLER_STYLE, ...style },
      bounds: "parent",
      size: { width: size.width, height: size.height },
      position: { x: position.x, y: position.y },
      onDragStop: handlePositionChange,
      onResizeStop: handleSizeChange },

    children));


};

// I am using the colors from MDN's docs
// https://developer.mozilla.org/en-US/docs/Web/CSS/border-image-slice
// Easier to debug things
const REGIONS_COLORS = [
"#E6F2F9",
"#C7DDA8",
"#FFFCAB",
"#FCE5C9",
"#D7D7D7",
"#D7D7D7",
"#D7D7D7",
"#D7D7D7"];


const DEMO_IMAGES = [
"//repo.bfw.wiki/bfwrepo/images/beijing/pencil-1302150_960_720.png",
"//repo.bfw.wiki/bfwrepo/images/beijing/angular-156626_960_720.png",

"//repo.bfw.wiki/bfwrepo/images/beijing/art-deco-frame-4940087_960_720.png",
"//repo.bfw.wiki/bfwrepo/images/beijing/frame-5890068_960_720.png",
"//repo.bfw.wiki/bfwrepo/images/beijing/frame-5537777_960_720.png"];


// Using regular english names instead of region numbers
// helped visualize and build a mental model
const TOP_LEFT = 0;
const TOP_RIGHT = 1;
const BOTTOM_RIGHT = 2;
const BOTTOM_LEFT = 3;
const TOP_MIDDLE = 4;
const MIDDLE_RIGHT = 5;
const BOTTOM_MIDDLE = 6;
const MIDDLE_LEFT = 7;

const App = function () {
  const [isDraggingOver, setIsDraggingOver] = useState(false);
  const [handlers, setHandlers] = useState([]);
  const [output, setOutput] = useState();
  const sourceCanvasRef = useRef();
  const outputCanvasRef = useRef();

  const initializeHandlers = (img, cb) => {
    const width = img.naturalWidth;
    const height = img.naturalHeight;

    const canvas = sourceCanvasRef.current;
    const ctx = canvas.getContext("2d");

    // clear first with the current dimensions
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    canvas.width = width;
    canvas.height = height;
    ctx.drawImage(img, 0, 0);

    const halfWidth = width / 2;
    const halfHeight = height / 2;
    const handlerWidth = Math.round(width * 0.25);
    const handlerHeight = Math.round(height * 0.25);
    const halfHandlerWidth = handlerWidth / 2;
    const halfHandlerHeight = handlerHeight / 2;
    const handlerDefaults = {
      width: handlerWidth,
      height: handlerHeight,
      x: 0,
      y: 0 };


    // I am sure there is a smarter way of doing this
    // but this is easier to visualize
    const newHandlers = [];
    newHandlers[TOP_LEFT] = {
      ...handlerDefaults };

    newHandlers[TOP_MIDDLE] = {
      ...handlerDefaults,
      x: halfWidth - halfHandlerWidth };

    newHandlers[TOP_RIGHT] = {
      ...handlerDefaults,
      x: width - handlerWidth };


    newHandlers[MIDDLE_RIGHT] = {
      ...handlerDefaults,
      x: width - handlerWidth,
      y: halfHeight - halfHandlerHeight };

    newHandlers[MIDDLE_LEFT] = {
      ...handlerDefaults,
      y: halfHeight - halfHandlerHeight };


    newHandlers[BOTTOM_LEFT] = {
      ...handlerDefaults,
      y: height - handlerHeight };

    newHandlers[BOTTOM_MIDDLE] = {
      ...handlerDefaults,
      x: halfWidth - halfHandlerWidth,
      y: height - handlerHeight };

    newHandlers[BOTTOM_RIGHT] = {
      ...handlerDefaults,
      x: width - handlerWidth,
      y: height - handlerHeight };


    setHandlers(newHandlers);
    if (cb) cb(newHandlers);
  };

  const readFromInput = async input => {
    if (!input) return;

    const img = await getImageFromInput(input);
    initializeHandlers(img);
  };

  const readFromDemo = (event, cb) => {
    const demoIndex = event.currentTarget.dataset.index;
    const img = new Image();

    img.crossOrigin = "Anonymous";
    img.onload = () => {
      initializeHandlers(img, cb);
    };
    img.onerror = err => {
      console.log(err.message);
    };

    img.src = DEMO_IMAGES[demoIndex];
  };

  // Drag and drop
  const onDrop = event => {
    event.preventDefault();
    event.dataTransfer.dropEffect = "copy";

    readFromInput(event.dataTransfer.files[0]);
    setIsDraggingOver(false);
  };

  const onInputChange = event => {
    readFromInput(event.target.files[0]);
  };

  const onDragOver = event => {
    event.preventDefault();
    event.dataTransfer.dropEffect = "copy";

    setIsDraggingOver(true);
  };

  const handleHandlerChange = (index, value) => {
    let updatedRegions = {};

    updatedRegions[index] = { ...value };

    // there is definitely a smarter way of doing this
    // but this was easier for me to visualize the regions
    // and the changes that each would have to make to one another
    const { width, height } = value;
    if (width || height) {
      if (index === TOP_LEFT) {
        // top sections share same height
        updatedRegions[TOP_RIGHT] = { height };
        // top-left and bottom-left share the same width
        updatedRegions[BOTTOM_LEFT] = { width };

        // middle sections can't be taller/wider than their counterpart regions
        updatedRegions[TOP_MIDDLE] = {
          height: Math.min(handlers[TOP_MIDDLE].height, height) };

        updatedRegions[MIDDLE_LEFT] = {
          width: Math.min(handlers[MIDDLE_LEFT].width, width) };

      } else if (index === TOP_RIGHT) {
        // top sections share same height
        updatedRegions[TOP_LEFT] = { height };
        // top-right and bottom-right share the same width
        updatedRegions[BOTTOM_RIGHT] = { width };

        // middle sections can't be taller/wider than their counterpart regions
        updatedRegions[TOP_MIDDLE] = {
          height: Math.min(handlers[TOP_MIDDLE].height, height) };

        updatedRegions[MIDDLE_RIGHT] = {
          width: Math.min(handlers[MIDDLE_RIGHT].width, width) };

      } else if (index === BOTTOM_LEFT) {
        // bottom-left and top-left share the same width
        updatedRegions[TOP_LEFT] = { width };
        // bottom sections share same height
        updatedRegions[BOTTOM_RIGHT] = { height };

        // middle sections can't be taller/wider than their counterpart regions
        updatedRegions[BOTTOM_MIDDLE] = {
          height: Math.min(handlers[BOTTOM_MIDDLE].height, height) };

        updatedRegions[MIDDLE_LEFT] = {
          width: Math.min(handlers[MIDDLE_LEFT].width, width) };

      } else if (index === BOTTOM_RIGHT) {
        // bottom-right and top-right share the same width
        updatedRegions[TOP_RIGHT] = { width };
        // bottom sections share same height
        updatedRegions[BOTTOM_LEFT] = { height };

        // middle sections can't be taller/wider than their counterpart regions
        updatedRegions[BOTTOM_MIDDLE] = {
          height: Math.min(handlers[BOTTOM_MIDDLE].height, height) };

        updatedRegions[MIDDLE_RIGHT] = {
          width: Math.min(handlers[MIDDLE_RIGHT].width, width) };

      } else if (index === TOP_MIDDLE) {
        // top-middle and bottom-middle share the same width
        updatedRegions[BOTTOM_MIDDLE] = { width };

        // middle sections can't be taller than their regions counterparts
        updatedRegions[index].height = Math.min(
        height,
        handlers[TOP_LEFT].height);

      } else if (index === BOTTOM_MIDDLE) {
        // bottom-middle and top-middle share the same width
        upd.........完整代码请登录后点击上方下载按钮下载查看

网友评论0