Skip to content

Commit

Permalink
feat: add toCanvas and toImgSrc
Browse files Browse the repository at this point in the history
  • Loading branch information
robertrosman committed May 8, 2024
1 parent 4051a1d commit 3e4f623
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 15 deletions.
19 changes: 18 additions & 1 deletion src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,31 @@
import { ref } from 'vue';
import VueDraw from './components/VueDraw.vue'
import type { Settings, Crop } from './types'
import { toCanvas } from './utils/toCanvas';
import { toImgSrc } from './utils/toImgSrc';
const settings = ref<Settings>()
const crop = ref<Crop>()
const canvasRef = ref()
const imgSrc = ref<string>()
const vueDrawRef = ref()
function onCrop(crop: Crop | undefined) {
console.log(crop)
}
async function save() {
imgSrc.value = await toImgSrc(vueDrawRef.value.svgRef, crop.value)
toCanvas(vueDrawRef.value.svgRef, canvasRef, crop.value)
}
</script>

<template>
<vue-draw class="vue-draw" @crop="onCrop"></vue-draw>
<vue-draw ref="vueDrawRef" v-model:crop="crop" class="vue-draw" @crop="onCrop"></vue-draw>
<button @click="save">Save</button>
<canvas ref="canvasRef"></canvas>
<img v-if="imgSrc" :src="imgSrc" />
</template>

<style scoped>
Expand Down
9 changes: 0 additions & 9 deletions src/components/SvgShape.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,3 @@ const props = defineProps<{
<line v-if="shape.type === 'arrow'" :x1="shape.x1" :y1="shape.y1" :x2="shape.x2" :y2="shape.y2"
:stroke="shape.color" :stroke-width="shape.thickness" :marker-end="`url(#${getArrowId(shape)})`" />
</template>

<style scoped>
rect,
line {
stroke-linecap: round;
stroke-linejoin: round;
fill-opacity: 0;
}
</style>
24 changes: 19 additions & 5 deletions src/components/VueDraw.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import SvgShape from './SvgShape.vue';
const emit = defineEmits<{
(e: 'crop', crop: Crop | undefined): void
}>()
const settings = defineModel<Settings>("settings", {
default: () => ({
tool: "line",
Expand All @@ -23,6 +24,12 @@ const crop = defineModel<Crop>("crop", { default: undefined })
const container = ref()
const svgRef = ref()
const activeShape = ref<Shape | undefined>()
defineExpose({
svgRef,
container
})
function updateActiveShape() {
if (settings.value.tool === 'rectangle') {
activeShape.value = {
Expand Down Expand Up @@ -130,6 +137,18 @@ const arrowMarkers = computed(() =>
<polygon points="0,5 1.7,2.5 0,0 5,2.5" :fill="marker.color"></polygon>
</marker>
</defs>
<svg:style>
rect,
line {
stroke-linecap: round;
stroke-linejoin: round;
fill-opacity: 0;
}
.overlay {
opacity: 0.7;
fill: #020202;
}
</svg:style>
</svg>
<div class="toolbar">
<button @click="setTool('crop')">Crop</button>
Expand All @@ -153,11 +172,6 @@ svg {
z-index: 100;
}
.overlay {
opacity: 0.7;
fill: #020202;
}
.toolbar {
position: absolute;
}
Expand Down
22 changes: 22 additions & 0 deletions src/utils/toCanvas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { Crop } from "@/types";
import { unref, type MaybeRef } from "vue";
import { toImgSrc } from "./toImgSrc";

// Inspired by https://jsfiddle.net/Wijmo5/h2L3gw88/
export function toCanvas(svg: MaybeRef<SVGGraphicsElement>, canvas: MaybeRef<HTMLCanvasElement>, crop?: Crop) {
const image64 = toImgSrc(svg)

// set it as the source of the img element
const img = new Image()
img.onload = () => {
// draw the image onto the canvas
const unreffedCanvas = unref(canvas)
unreffedCanvas.height = crop?.height ?? Number(unref(svg).getAttribute('height'))
unreffedCanvas.width = crop?.width ?? Number(unref(svg).getAttribute('width'))
unreffedCanvas.getContext('2d')?.drawImage(img,
crop?.x ?? 0, crop?.y ?? 0, unreffedCanvas.width, unreffedCanvas.height,
0, 0, unreffedCanvas.width, unreffedCanvas.height
);
}
img.src = image64;
}
14 changes: 14 additions & 0 deletions src/utils/toImgSrc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { unref, type MaybeRef } from "vue";

// Inspired by https://jsfiddle.net/Wijmo5/h2L3gw88/
export function toImgSrc(svg: MaybeRef<SVGElement>) {
// get svg data
const xml = new XMLSerializer().serializeToString(unref(svg));

// make it base64
const svg64 = btoa(xml);
const b64Start = 'data:image/svg+xml;base64,';

// prepend a "header"
return b64Start + svg64;
}

0 comments on commit 3e4f623

Please sign in to comment.