七夕爱上女孩表白文字和鼠标特效

代码语言:html

所属分类:表白

代码描述:七夕爱上女孩表白文字和鼠标特效

代码标签: 表白 文字 鼠标 特效

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

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">

<link href="https://fonts.googleapis.com/css2?family=Amatic+SC:wght@700&display=swap" rel="stylesheet">
<style>
*, *::before, *::after{
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html, body{
  display: block;
  position: relative;
  width: 100%;
  height: 100%;
}

canvas{
  background: repeating-linear-gradient(
    45deg,
    #2374C6,
    #2374C6 50px,
    #FFDD22 50px,
    #FFDD22 100px /* determines size */
  );
  display: block;
  cursor: crosshair;
  font-family: 'Amatic SC', cursive;
}
</style>

</head>
<body translate="no">
<canvas></canvas>

<script>
!function (universe) {



  const GLOBAL_DEFAULTS = {

    background: null,
    padding: 0,
    fontSize: 50,
    lineHeight: 100,
    lineWidth: 2,
    fontFamily: 'sans-serif',
    weight: 'normal',
    baseline: 'middle',
    pointerRadius: 10,
    textAlign: 'center',
    verticalAlignment: 'top',
    strokeStyle: 'red',
    fillStyle: 'black',
    compositeOperation: 'source-over',
    horizontalAlignment: 'left' };




  class Util {

    static getWidest(strings, { fontSize, fontFamily } = {}) {

      let $canvas = document.createElement('canvas').getContext('2d');

      $canvas.font = `${fontSize}px ${fontFamily}`;

      let widest = $canvas.measureText(strings[0]).width;

      for (let i = 1; i < strings.length; i++) {
        if ($canvas.measureText(strings[i]).width > widest) widest = $canvas.measureText(strings[i]).width;
      }

      $canvas = null;

      return widest;

    }

    static getStringWidth(string, { fontSize, fontFamily } = {}) {

      let $canvas = document.createElement('canvas').getContext('2d');

      $canvas.font = `${fontSize}px ${fontFamily}`;

      let width = $canvas.measureText(string).width;

      $canvas = null;

      return width;

    }

    static pickRandom(choice) {
      return choice[~~(Math.random() * choice.length)];
    }

    static randomInRange(min, max) {
      return Math.random() * (max - min) + min;
    }}




  class Component {

    constructor() {
      this.props = {}; //will hold flags and values to be shared with this component's children  (e.g. mouse coordinates)
    }

    setProps(prop, value) {this.props[prop] = value;}

    getProp(prop) {return this.props[prop];}

    onUpdate(method) {this.update = method.bind(this);}

    onRender(method) {this.render = method.bind(this);}

    onMount(method) {this.mount = method.bind(this);}}




  class BoundedComponent extends Component {

    constructor(width, height, { position = { x: 0, y: 0 }, padding = GLOBAL_DEFAULTS.padding, verticalAlignment = GLOBAL_DEFAULTS.verticalAlignment, horizontalAlignment = GLOBAL_DEFAULTS.horizontalAlignment } = {}) {
      super();
      this.width = width;
      this.height = height;
      this.position = position;
      this.renderingPosition = { x: null, y: null }; //will be calculated when the component is mounted in the scene
      this.padding = padding;
      this.verticalAlignment = verticalAlignment;
      this.horizontalAlignment = horizontalAlignment;
    }

    createSpaceProps(bounds) {

      const innerBounds = { x: null, y: null, w: null, h: null };
      const renderingPosition = { x: null, y: null };

      switch (this.verticalAlignment) {

        case 'top':
          innerBounds.y = bounds.y + this.padding;
          renderingPosition.y = bounds.y;
          break;

        case 'middle':
          innerBounds.y = bounds.y + bounds.h / 2 - this.height / 2 + this.padding;
          renderingPosition.y = bounds.y + bounds.h / 2 - this.height / 2;
          break;

        case 'bottom':
          innerBounds.y = bounds.y + bounds.h - this.height + this.padding;
          renderingPosition.y = bounds.y + bounds.h - this.height;}



      switch (this.horizontalAlignment) {

        case 'left':
          innerBounds.x = bounds.x + this.padding;
          renderingPosition.x = bounds.x;
          break;

        case 'center':
          innerBounds.x = bounds.x + bounds.w / 2 - this.width / 2 + this.padding;
          renderingPosition.x = bounds.x + bounds.w / 2 - this.width / 2;
          break;

        case 'right':
          innerBounds.x = bounds.x + bounds.w - this.width + this.padding;
          renderingPosition.x = bounds.x + bounds.w - this.width;}



      innerBounds.w = this.width - this.padding * 2;
      innerBounds.h = this.height - this.padding * 2;

      innerBounds.x += this.position.x;
      innerBounds.y += this.position.y;

      renderingPosition.x += this.position.x;
      renderingPosition.y += this.position.y;

      return { innerBounds, renderingPosition };

    }

    drawMyOutline() {//for debugging
      const $ = this.getProp('sceneContext');
      $.save();
      $.strokeStyle = 'red';
      $.setLineDash([5, 10]);
      $.lineWidth = 3;
      $.strokeRect(this.innerBounds.x, this.innerBounds.y, this.innerBounds.w, this.innerBounds.h);
      $.restore();
    }

    setBounds(outerBounds = this.getParentProp('innerBounds')) {

      const spaceProps = this.createSpaceProps(outerBounds);

      this.innerBounds = spaceProps.innerBounds;
      this.renderingPosition = spaceProps.renderingPosition;

      this.setProps('innerBounds', this.innerBounds);

    }}




  class TextNode extends BoundedComponent {

    constructor(string, lineHeight, { position = { x: 0, y: 0 }, lineWidth = 0, fillStyle = GLOBAL_DEFAULTS.fillStyle, strokeStyle = GLOBAL_DEFAULTS.strokeStyle, padding = GLOBAL_DEFAULTS.padding, fontSize = GLOBAL_DEFAULTS.fontSize, fontFamily = GLOBAL_DEFAULTS.fontFamily, weight = GLOBAL_DEFAULTS.weight, verticalAlignment = GLOBAL_DEFAULTS.verticalAlignment, horizontalAlignment = GLOBAL_DEFAULTS.horizontalAlignment } = {}) {

      const width = Util.getStringWidth(string, { fontSize, fontFamily });

      super(width, lineHeight, { position, padding, verticalAlignment, horizontalAlignment });

      this.string = string;
      this.contextProps = { fontSize, fontFamily, weight, fillStyle, lineWidth, strokeStyle };

    }

    createSpaceProps(bounds) {

      const innerBounds = { x: null, y: null, w: null, h: null };
      const renderingPosition = { x: null, y: null };

      switch (this.verticalAlignment) {

        case 'top':
          innerBounds.y = bounds.y + this.padding;
          renderingPosition.y = bounds.y + this.height / 2;
          break;

        case 'middle':
          innerBounds.y = bounds.y + bounds.h / 2 - this.height / 2 + this.padding;
          renderingPosition.y = bounds.y + bounds.h / 2;
          break;

        case 'bottom':
          innerBounds.y = bounds.y + bounds.h - this.height + this.padding;
          renderingPosition.y = bounds.y + bounds.h - this.height / 2;}



      switch (this.horizontalAlignment) {

        case 'left':
          innerBounds.x = bounds.x + this.padding;
          renderingPosition.x = bounds.x + this.width / 2;
          break;

        case 'center':
          innerBounds.x = bounds.x + bounds.w / 2 - this.width / 2 + this.padding;
          renderingPosition.x = bounds.x + bounds.w / 2;
          break;

        case 'right':
          innerBounds.x = bounds.x + bounds.w - this.width + this.padding;
          renderingPosition.x = bounds.x + bounds.w - this.width / 2;}



      innerBounds.w = this.width - this.padding * 2;
      innerBounds.h = this.height - this.padding * 2;

      innerBounds.x += this.position.x;
      innerBounds.y += this.position.y;

      renderingPosition.x += this.position.x;
      renderingPosition.y += this.position.y;

      return { innerBounds, renderingPosition };

    }

    update() {} //kinda like an abstract method

    render() {} //same ^^^
  }



  class Container extends BoundedComponent {

    constructor(width, height, { position = { x: 0, y: 0 }, padding = GLOBAL_DEFAULTS.padding, verticalAlignment = GLOBAL_DEFAULTS.verticalAlignment, horizontalAlignment = GLOBAL_DEFAULTS.horizontalAlignment } = {}) {

      super(width, height, { position, padding, verticalAlignment, horizontalAlignment });
      this.components = [];

    }

    update() {} //again similar thing to an abstract method

    updateComponents() {
      for (let i = 0; i < this.components.length; i++) {
        const component = this.components[i];
        if (!component.getProp('pointer')) {component.setProps('pointer', this.getProp('pointer'));}
        component.update();
        if (component instanceof BoundedComponent) {component.setBounds();}
        if (component.components && component.components.length) {component.updateComponents();}
      }
    }

    applyContextProps({ lineWidth = GLOBAL_DEFAULTS.lineWidth, compositeOperation = GLOBAL_DEFAULTS.compositeOperation, strokeStyle = GLOBAL_DEFAULTS.strokeStyle, fillStyle = GLOBAL_DEFAULTS.fillStyle, fontSize = GLOBAL_DEFAULTS.fontSize, fontFamily = GLOBAL_DEFAULTS.fontFamily, weight = GLOBAL_DEFAULTS.weight } = {}) {
      const $ = this.getProp('sceneContext');
      $.save();
      $.strokeStyle = strokeStyle;
      $.fillStyle = fillStyle;
      $.lineWidth = lineWidth;
      $.globalCompositeOperation = compositeOperation;
      $.font = `${weight} ${fontSize}px ${fontFamily}`;
    }

    render() {} //yep, again...

    restoreSceneContext() {
      const $ = this.getProp('sceneContext');
      $.restore();
    }

    renderComponents() {
      for (let i = 0; i < this.components.length; i++) {
        const component = this.components[i];
        if (component.contextProps) {this.applyContextProps(component.contextProps);}
        component.render();
        if (component.contextProps) {this.restoreSceneContext();}
        if (component.components && component.components.length) {component.renderComponents();}
      }
    }

    addComponent(component) {

      component.setParentProp = this.setProps.bind(this);
      component.getParentProp = this.getProp.bind(this);

      if (!component.getProp('pointer')) {component.setProps('pointer', this.getProp('pointer'));}
      if (!component.getProp('sceneContext')) {component.setProps('sceneContext', this.getProp('sceneContext'));}

      if (component instanceof BoundedComponent) {component.setBounds();}

      if (component.mount) component.mount();

      this.components.push(component);

    }

    addMulti(components) {
      for (let i = 0; i < components.length; i++) {
        this.addComponent(components[i]);
      }
    }}




  class Scene extends Container {

    constructor(canvas, { pointer = null, padding = GLOBAL_DEFAULTS.padding, background = GLOBAL_DEFAULTS.background } = {}) {

      super(canvas.width, canvas.height, { padding });

      //set up the rendering canvas and it's context
      this.canvas = canvas;
      this.context = this.setBaseContext(canvas);

      //this will be passed down to other sub-components of the view
      if (pointer instanceof Pointer) this.pointer = this.initilisePointer(pointer);

      this.background = background;

     .........完整代码请登录后点击上方下载按钮下载查看

网友评论0