# Plan Annotations

This example will show you how to create a plugin that use the annotation API to create, edit and delete annotations on a PDF plan.

The plugin will be a button that you can click to add an annotation anywhere on a plan. Once the annotation is added you can drag & drop it to change its position. You can also delete it by double clicking it.

# Demo

# Setup

First lets setup a viewer with a simple configuration and register a custom plugin:

// file: main.js
import makeBIMDataViewer from "@bimdata/viewer";
import PlanAnnotationsPlugin from "./plan-annotations-plugin.js";

const viewer = makeBIMDataViewer({
  api: {
    // ...
  },
});

viewer.registerPlugin(PlanAnnotationsPlugin);

viewer.mount("#app", "plan");

# Create the plugin definition

Next, we'll define our plugin configuration:

// file: plan-annotations-plugin.js
import PlanAnnotationsPluginComponent from "./PlanAnnotationsPlugin.js";

export default {
  name: "planAnnotations",
  component: PlanAnnotationsPluginComponent,
  addToWindows: ["plan"],
  button: {
    position: "right",
    keepOpen: true,
    tooltip: "Annotations",
    icon: {
      component: "BIMDataIconLocation",
      options: { size: "m" },
    },
  },
};

# Create plugin components

Then we'll create the plugin component that will hold the logic:

// file: PdfAnnotationsPlugin.js
import PlanAnnotation from "./PlanAnnotation.vue";

export default {
  render() {
    return null;
  },
  onOpen() {
    const state = this.$viewer.state;
    const context = this.$viewer.localContext;

    // Register an annotation callback to perform the desired action on click
    context.startAnnotationMode(({ x, y }) => {

      // Create a synchronized annotation in the state
      state.addAnnotation({
        component: PlanAnnotation,
        x,
        y,
        z: 0,
      });

      // Unregister the callback when finished
      context.stopAnnotationMode();

      this.$close();
    });
  },
};

Finally we'll add the component that will materialize the PDF annotation on the plan:

// file: PlanAnnotation.js
export default {
  template: `
    <div
      class="plan-annotation"
      @dblclick="remove"
    >
      {{ annotation.id }}
    </div>
  `,
  props: {
    // An `annotation` prop is passed to your component
    // so we can interact directly with the annotation object
    annotation: Object,
  },
  methods: {
    remove() {
      // `this.$viewer` is also accessible in your annotation component
      this.$viewer.state.removeAnnotation(this.annotation);
    },
  },
};

You can also add the following rules to your page stylesheet:

.plan-annotation {
  /* This is a trick to place the marker under the cursor */
  transform: translate(-50%, -50%);

  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid var(--color-primary);
  background-color: var(--color-high);
  font-weight: bold;

  display: flex;
  justify-content: center;
  align-items: center;

  user-select: none;
  cursor: grab;
}

Notice the use of BIMData css variables (opens new window) like --color-primary. It allows to stay in sync with the global theme and to track colors that may have been changed when the viewer was initialized.