Spaces:
Build error
Build error
File size: 3,688 Bytes
838b286 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
<script lang="ts">
import PxBrush from 'px-brush';
import { onMount } from 'svelte';
import type { Brush } from '../types';
import { selectedBrush, selectedImageBlob, currentCanvas } from '$lib/store';
let canvas: HTMLCanvasElement;
let brush: HTMLCanvasElement;
let brushCtx: CanvasRenderingContext2D;
let ctx: CanvasRenderingContext2D;
let pxBrush: PxBrush;
let startPosition: { x: number; y: number } = { x: 0, y: 0 };
$: {
if (brushCtx && $selectedBrush) {
setBrush($selectedBrush);
brush.style.top = `${10 + $selectedBrush.size / 2}px`;
brush.style.left = `${10 + $selectedBrush.size / 2}px`;
}
}
$: {
if ($selectedImageBlob) {
drawImage(ctx, $selectedImageBlob);
}
}
onMount(() => {
ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
brushCtx = brush.getContext('2d') as CanvasRenderingContext2D;
window.devicePixelRatio = 1;
pxBrush = new PxBrush(canvas);
$currentCanvas = canvas;
clearCanvas(ctx);
});
const drawImage = (ctx: CanvasRenderingContext2D, blob: Blob) => {
const img = new Image();
img.onload = function () {
ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height);
};
img.src = URL.createObjectURL(blob);
};
let mouseDown: boolean = false;
function pointerEnter() {
// brush.hidden = false;
}
function pointerOut() {
brush.style.top = `${10 + $selectedBrush.size / 2}px`;
brush.style.left = `${10 + $selectedBrush.size / 2}px`;
mouseDown = false;
}
function pointerDown(e: MouseEvent) {
mouseDown = true;
startPosition = getPosition(canvas, e);
pxBrush.draw({
from: startPosition,
to: startPosition,
size: $selectedBrush.size,
color: $selectedBrush.color
});
}
function pointerMove(e: MouseEvent) {
const position = getPosition(canvas, e);
brush.style.top = `${position.y}px`;
brush.style.left = `${position.x}px`;
if (!mouseDown) {
return;
}
pxBrush.draw({
from: startPosition,
to: position,
size: $selectedBrush.size,
color: $selectedBrush.color
});
startPosition = position;
}
function getPosition(canvas: HTMLCanvasElement, event: MouseEvent) {
const rect = canvas.getBoundingClientRect();
return {
x: event.clientX - rect.left,
y: event.clientY - rect.top
};
}
function setBrush(sBrush: Brush) {
const { size, color } = sBrush;
brush.width = size;
brush.height = size;
// brushCtx.clearRect(0, 0, brush.width, brush.height);
// brushCtx.beginPath();
brushCtx.fillStyle = color;
brushCtx.arc(size / 2, size / 2, size / 2, 0, 2 * Math.PI);
brushCtx.fill();
}
function clearCanvas(ctx: CanvasRenderingContext2D) {
ctx.fillStyle = '000';
ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.fill();
}
</script>
<div class="inline-block relative overflow-clip">
<canvas
bind:this={canvas}
class="canvas"
width="256"
height="512"
on:touchmove={(e) => e.preventDefault()}
on:pointerenter={pointerEnter}
on:pointerup={pointerOut}
on:pointerleave={pointerOut}
on:pointercancel={pointerOut}
on:pointerout={pointerOut}
on:pointermove={pointerMove}
on:pointerdown={pointerDown}
/>
<canvas bind:this={brush} class="brush" width="10" height="10" />
<span class="label">{$selectedBrush?.label} </span>
</div>
<style lang="postcss" scoped>
.canvas {
@apply box-border z-0 border dark:border-gray-300 border-gray-500 aspect-[256/512];
}
.brush {
@apply z-10 absolute pointer-events-none -translate-x-1/2 -translate-y-1/2;
}
.label {
@apply px-2 text-base z-20 absolute top-0 left-0 pointer-events-none text-white select-none;
color: white;
font-weight: bolder;
-webkit-text-stroke: 1px black;
-webkit-text-fill-color: white;
}
</style>
|