muaz-khan/Canvas-Designer
muaz-khan/Canvas-Designer là dự án JavaScript với 411 sao trong nhóm Image Tools. Collaborative, extendable, JavaScript Canvas2D drawing tool, supports dozens of builtin tools, as well as generates JavaScript code for 2D animations.
Tóm tắt dựng từ metadata GitHub của chính dự án — chưa có bài review TopGit. Trang sẽ tự động cập nhật khi bài review đầy đủ được xuất bản.
TopGit viết bài đầy đủ cho repo có nhiều sao nhất và được yêu cầu nhiều nhất. Trang này là snapshot trong thời gian chờ — xem README gốc ở tab READ ME.
Snapshot
Cộng tác viên hàng đầu
Xem cộng tác viên hàng đầu
Canvas Designer / API Referencee
Demo: https://www.webrtc-experiment.com/Canvas-Designer/
Advance Demo: demos/dashboard/
Multiple designers demo: https://www.webrtc-experiment.com/Canvas-Designer/multiple.html
YouTube video:
- https://www.youtube.com/watch?v=pvAj5l_v3cM

"Collaborative" Canvas Designer i.e. Canvas-Drawing tool allows you draw bezier/quadratic curves, rectangles, circles and lines. You can also set strokes, back/forth colors and much more. You can draw using pencils, erase drawing, type texts etc. You can easily add your own tools.
You can check all releases here:
- https://github.com/muaz-khan/Canvas-Designer/releases
The specialty of this drawing-tool is that, it generates Canvas2D code for you; so simply draw and get the code! That code can be used in any javascript Canvas2D application.
You can submit issues here:
- https://github.com/muaz-khan/Canvas-Designer/issues
Also, you can collaborate your drawing with up to 15 users; and everything is synced from all users. So, if you draw a line and your friend-A draws quadratic curve and friend-B draws rectangle then everything will be synced among all users!
Youtube Videos
- https://www.youtube.com/watch?v=oSSwMlBu8SY
Gif images:
- https://www.webrtc-experiment.com/images/Canvas-Designer.gif
Built-in tools
You can use designer.setSelected or designer.setTools for below tools.
line--- to draw straight linespencil--- to write/draw shapesdragSingle--- to drag/ove and especially resize last selected shapedragMultiple--- to drag/move all shapeseraser--- to erase/clear specific portion of shapesrectangle--- to draw rectanglesarc--- to draw circlesbezier--- to draw bezier curvesquadratic--- to draw quadratic curvestext--- to write texts on single or multiple lines, select font families/sizes and moreimage--- add external imagesarrow--- draw arrow linesmarker--- draw markerslineWidth--- set line widthcolorsPicker--- background and foreground colors pickerextraOptions--- extra options eg. lineCap, lineJoin, globalAlpha, globalCompositeOperation etc.pdf--- to import PDFcode--- to enable/disable code viewundo--- undo recent shapes
The correct name for dragSingle should be: drag-move-resize last-selected-shape.
The correct name for dragMultiple should be: drag-move all-shapes.
Upcoming tools
- Allow users to add video-streams or screen-streams or existing-webm-mp4-videos
- Resize all shapes at once (currently you can resize last selected shape only)
Features
-
Draw single or multiple shapes of any kind (according to toolbox)
-
Drag/resize/adjust all the shapes in any possible direction
-
Rectangles and images can be resized in 4-directions
Red transparent small circles helps you understand how to resize.
-
Undo drawings using
ctrl+zkeys (undo all shapes, undo last 10 or specific shapes, undo range of shapes or undo last shape) -
Drag/move single or all the shapes without affecting any single coordinate
More importantly, you can use unlimited designers on a single page. Each will have its own surface and its own tools.
Chinese, Arabic, other languages
You can install following chrome extension for multi-language input tools:
- https://chrome.google.com/webstore/detail/google-input-tools/mclkkofklkfljcocdinagocijmpgbhab?hl=en
Now type your own language text in any <input> box or anywhere, and simply copy that text.
Now click T tool icon from the tool-box and press ctrl+v to paste your own language's text.
To repeat it:
- Type your own language texts anywhere and make sure to copy to clipboard using
ctrl+v - Then click
Ticon, and then pressctrl+vto paste your copied text
You can paste any text: English, Arabic, Chinese etc.
How to Use
-
Download/link
canvas-designer-widget.jsfrom this github repository. -
Set
designer.widgetHtmlURLanddesigner.widgetJsURLin your HTML file. -
Use this command to append widget in your HTML page:
var designer = new CanvasDesigner();designer.appendTo(document.body);
<!-- 1st step -->
<script src="https://www.webrtc-experiment.com/Canvas-Designer/canvas-designer-widget.js"></script>
<!-- 2nd step -->
<script>
var designer = new CanvasDesigner();
// both links are mandatory
// widget.html will internally use widget.js
designer.widgetHtmlURL = 'https://www.webrtc-experiment.com/Canvas-Designer/widget.html'; // you can place this file anywhere
designer.widgetJsURL = 'https://www.webrtc-experiment.com/Canvas-Designer/widget.js'; // you can place this file anywhere
</script>
<!-- 3rd i.e. last step -->
<script>
// <iframe> will be appended to "document.body"
designer.appendTo(document.body || document.documentElement);
</script>
Complete Usage
var designer = new CanvasDesigner();
websocket.onmessage = function(event) {
designer.syncData( JSON.parse(event.data) );
};
designer.addSyncListener(function(data) {
websocket.send(JSON.stringify(data));
});
designer.setSelected('pencil');
designer.setTools({
pencil: true,
text: true
});
designer.appendTo(document.documentElement);
It is having designer.destroy() method as well.
Use WebRTC!
webrtc.onmessage = function(event) {
designer.syncData( event.data );
};
designer.addSyncListener(function(data) {
webrtc.send(data);
});
Use Socket.io
socket.on('message', function(data) {
designer.syncData( data );
});
designer.addSyncListener(function(data) {
socket.emit('message', data);
});
API Reference
widgetHtmlURL
You can place widget.html file anywhere on your site.
designer.widgetHtmlURL = '/html-files/widget.html';
By default widget.html is placed in the same directory of index.html.
// here is default value
designer.widgetHtmlURL = 'widget.html';
Remember, widget.html is loaded using <iframe>.
widgetJsURL
Note: This file is internally used by
widget.html.
You can place widget.html file anywhere on your site.
designer.widgetJsURL = '/js-files/widget.min.js';
By default widget.min.js is placed in the same directory of index.html.
// here is default value
designer.widgetJsURL = 'widget.min.js';
Remember, widget.js is loaded using <iframe>.
syncData
Pass array-of-points that are shared by remote users using socket.io or websockets or XMPP or WebRTC.
designer.syncData(arrayOfPoints);
An example to pass custom data on Canvas-Designer:
var x = 0;
var y = 0;
var width = designer.iframe.clientWidth;
var height = designer.iframe.clientHeight;
var image = 'https://www.webrtc-experiment.com/images/RTCMultiConnection-STUN-TURN-usage.png';
var points = [
['image', [image, x, y, width, height, 1], ['2', '#6c96c8', 'rgba(0,0,0,0)', '1', 'source-over', 'round', 'round', '15px "Arial"']]
];
designer.syncData({
startIndex: 0,
points: points
});
clearCanvas
Remove and clear all drawings from the canvas:
designer.clearCanvas();
renderStream
Call this method internally to fix video rendering issues.
designer.renderStream();
addSyncListener
This callback is invoked as soon as something new is drawn. An array-of-points is passed over this function. That array MUST be shared with remote users for collaboration.
designer.addSyncListener(function(data) {
designer.send(JSON.stringify(data));
});
setSelected
This method allows you select specific tools.
- See list of all tools
designer.setSelected('rectangle');
setTools
This method allows you choose between tools that should be displayed in the tools-panel.
- See list of all tools
designer.setTools({
line: true,
arrow: true,
pencil: true,
marker: true,
dragSingle: true,
dragMultiple: true,
eraser: true,
rectangle: true,
arc: true,
bezier: true,
quadratic: true,
text: true,
image: true,
pdf: true,
zoom: true,
lineWidth: true,
colorsPicker: true,
extraOptions: true,
code: true,
undo: true
});
icons
You can force/set your own tool-icons:
designer.icons = {
line: '/icons/line.png',
arrow: '/icons/arrow.png',
pencil: '/icons/pencil.png',
dragSingle: '/icons/dragSingle.png',
dragMultiple: '/icons/dragMultiple.png',
eraser: '/icons/eraser.png',
rectangle: '/icons/rectangle.png',
arc: '/icons/arc.png',
bezier: '/icons/bezier.png',
quadratic: '/icons/quadratic.png',
text: '/icons/text.png',
image: '/icons/image.png',
pdf: '/icons/pdf.png',
pdf_next: '/icons/pdf-next.png',
pdf_prev: '/icons/pdf-prev.png',
marker: '/icons/marker.png',
zoom: '/icons/zoom.png',
lineWidth: '/icons/lineWidth.png',
colorsPicker: '/icons/colorsPicker.png',
extraOptions: '/icons/extraOptions.png',
code: '/icons/code.png'
};
You can set like this as well:
designer.icons.line = '/icons/line.png';
Default values are NULL to force icons from /dev/data-dris.js.
appendTo
CanvasDesigner is a widget; that widget should be appended to a DOM object. This method allows you pass <body> or any other HTMLDOMElement.
designer.appendTo(document.body || document.documentElement);
// or
designer.appendTo(document.body || document.documentElement, function() {
alert('iframe load callback');
});
The correct name for appendTo is: append-iframe to target HTML-DOM-element
destroy
If you want to remove the widget from your HTMLDOMElement.
designer.destroy();
iframe
You can access designer iframe as following:
designer.iframe.style.border = '5px solid red';
window.open(designer.iframe.src);
designer.iframe will be null/undefined until you call appendTo. So always use this code-block:
if(!designer.iframe) {
designer.appendTo(document.body);
}
designer.iframe.style.border = '5px solid red';
toDataURL
Get data-URL of your drawings!
designer.toDataURL('image/png', function(dataURL) {
window.open(dataURL);
});
sync
You can manually sync drawings by invoking designer.sync method:
designer.sync();
Here is a real usecase:
webrtcDataChannel.onopen = function() {
if(designer.pointsLength > 0) {
// you seems having data to be synced with new user!
designer.sync();
}
};
captureStream
Get MediaStream object and share in realtime using RTCPeerConnection.addStream API.
<script src="dev/webrtc-handler.js"></script>
<script>
designer.captureStream(function(stream) {
var url = URL.createObjectURL(stream);
videoPreview.src = url;
rtcPeerConnection.addStream(stream);
rtcPeerConnection.createOffer(success, failure, params);
});
</script>
pointsLength
Each shape is considered as a point. This value allows you check number of shapes that are already drawn on the canvas-designer.
(function looper() {
document.getElementById('number-of-shapes').inenrHTML = designer.pointsLength;
setTimeout(looper, 1000);
})();
Or a real usage:
websocket.onopen = function() {
if(designer.pointsLength > 0) {
// you seems having data to be synced with existing users!
designer.sync();
}
};
undo
You can either undo drawings by pressing ctrl+z on windows and command+z on Mac; however you can undo using designer.undo method as well:
designer.undo(); // undo last shape
designer.undo(-1); // undo last shape
// undo shape from specific index
designer.undo(0);
// undo all shapes
designer.undo('all');
// undo last 10 shapes
designer.undo({
numberOfLastShapes: 10
})
// to remove all occurrences of a specific shape
designer.undo('pencil');
designer.undo('arrow');
designer.undo('rect');
designer.pointsLength shows number of shapes; and designer.undo accepts shape-index as well.
Add New Tools
First Step
Open widget.html and add your new tool-icon HTML.
<div id="tool-box" class="tool-box"> <!-- search for this div; and include your HTML inside this div -->
<canvas id="yourNewToolIcon" width="40" height="40"></canvas> <!-- here is your icon-HTML -->
</div>
Second Step
Open decorator.js and decorate your new HTML icon.
var tools = {
yourNewToolIcon: true // add this line to make sure index.html can use it
};
Search for decorateLine method, and append following snippet quickly after that method:
function decorateYourNewToolIcon() {
var context = getContext('yourNewToolIcon');
context.fillStyle = 'Gray';
context.font = '9px Verdana';
context.fillText('New', 16, 12);
bindEvent(context, 'YourNewToolIconSelected');
}
if (tools.yourNewToolIcon === true) {
decorateYourNewToolIcon();
} else document.getElementById('yourNewToolIcon').style.display = 'none';
Third Step
Open common.js and add selection-states for your new tool-icon (i.e. whether your new tool icon is selected or not):
var is = {
isYourNewToolIconSelected: false, // add this line
set: function (shape) {
var cache = this;
cache.isYourNewToolIconSelected = false; // add this line as well.
// ..... don't modify anything else
cache['is' + shape] = true;
}
};
You merely need to set isYourNewToolIconSelected:true also cache.isYourNewToolIconSelected=false.
Fourth Step
Create new file in the dev directory. Name this file as yourNewToolIcon-handler.js.
This file MUST look like this:
var yourNewToolIconHandler = {
ismousedown: false,
mousedown: function(e) {
this.ismousedown = true;
},
mouseup: function(e) {
this.ismousedown = false;
},
mousemove: function(e) {
if(this.ismousedown) { ... }
}
};
You can check other *-handler.js from dev directory to get the idea how exactly it works.
Now open Gruntfile.js#L43 and add link to your new file: dev/events-handler.js.
Now compile all your changes using grunt.
Fifth Step
Open events-handler.js and make sure that your above yourNewToolIconHandler object is called for mouse up/down/move events.
addEvent(canvas, isTouch ? 'touchstart' : 'mousedown', function (e) {
// you merely need to add this line at the end of this method
else if (is.isYourNewToolIconSelected) yourNewToolIconHandler.mousedown(e);
});
addEvent(document, isTouch ? 'touchend' : 'mouseup', function (e) {
// you merely need to add this line at the end of this method
else if (is.isYourNewToolIconSelected) yourNewToolIconHandler.mouseup(e);
});
addEvent(canvas, isTouch ? 'touchmove' : 'mousemove', function (e) {
// you merely need to add this line at the end of this method
else if (is.isYourNewToolIconSelected) yourNewToolIconHandler.mousemove(e);
});
First of all, we are checking whether your tool-icon is selected or not: is.isYourNewToolIconSelected
Then we are calling yourNewToolIconHandler dot mousedown/mouseup/mousemove events respectively.
Sixth Step
Open draw-helper.js. Make sure that your new tool-icon can be drawn on the <canvas> surface.
yourNewToolIcon: function(context, point, options) {
context.beginPath();
context.moveTo(point[0], point[1]);
context.whateverYouWantToDoHere(point[2], point[3]);
this.handleOptions(context, options);
}
Usually point[0] is x coordinates; point[1] is y coordinates; point[2] is width and point[3] is height.
Different shapes can handle these points differently.
There is NO-limit for point[index]. You can add as many points as you want.
Complex shapes can add 10 or 20 points.
Seventh Step
Open drag-helper.js and make sure that your new shape can be dragged/resized/move.
Search for p[0] === 'line' and add similar code-blocks for your shape (new-tool-icon) as well.
Eighth Step
Open common.js and make sure that your new shape (tool-icon) is printed on the <textarea> as well.
This allows end-users to copy your shape's code and use anywhere on their own web-pages.
Open common.js file; there is a function updateTextArea inside the "common" object – which is aimed to output into textarea element.
You don't have to change updateTextArea. For simplicity purpose, code is separated in different functions/properties that you've to edit:
forLoopabsoluteNOTShortenedrelativeShortenedrelativeNOTShortened
Search for p[0] === 'line' and add similar code-blocks for your shape (new-tool-icon) as well.
For more information
- https://www.webrtc-experiment.com/Canvas-Designer/Help/#contribute
Shortcut Keys
ctrl+t (to display text-fonts box)
ctrl+z (to undo last-single shape)
ctrl+a (to select all shapes)
ctrl+c (copy last-selected shape)
ctrl+v (paste last-copied shape)
ctrl+mousedown allows you quickly copy/paste all shapes. (i.e. ctrl button + mouse down)
Signaling Server
- https://github.com/muaz-khan/RTCMultiConnection-Server
Contributors
- Muaz Khan
- Oleg Aliullov
Please make pull-request to update this list.
License
Canvas Designer is released under MIT license . Copyright (c) Muaz Khan.
Repo liên quan
JavaScript 3D Library.
Simple HTML5 Charts using the <canvas> tag
The HTML5 Creation Engine: Create beautiful digital content with the fastest, most flexible 2D WebGL renderer.
a 2D rigid body physics engine for the web ▲● ■
Trả lời nhanh
Đọc thêm về muaz-khan/Canvas-Designer ở đâu?
Trang TopGit này là một snapshot — tab "Readme" hiển thị nguyên văn README của repo (đã bỏ link, giữ ảnh). Repo GitHub ở github.com/muaz-khan/Canvas-Designer là nguồn chính thức.
muaz-khan/Canvas-Designer có những chủ đề gì?
GitHub topics của muaz-khan/Canvas-Designer: "canvas", "canvas-designer", "javascript", "rtcmulticonnection", "tool", "webrtc". TopGit xếp repo vào nhóm Image Tools.
muaz-khan/Canvas-Designer có phải mã nguồn mở không?
Có — muaz-khan/Canvas-Designer phát hành theo license MIT, nghĩa là mã nguồn mở để đọc, fork và (tùy license) tái sử dụng. Mã: github.com/muaz-khan/Canvas-Designer.
muaz-khan/Canvas-Designer có trang demo không?
Dự án có trang chủ ở https://www.webrtc-experiment.com/Canvas-Designer/. Tab "Readme" ở trang này thường có ảnh chụp và hướng dẫn bắt đầu nhanh.
muaz-khan/Canvas-Designer còn đang phát triển không?
Commit gần nhất trên muaz-khan/Canvas-Designer là 5.6 năm trước (theo timestamp GitHub). Repo có 177 fork — một chỉ báo về mức độ quan tâm của cộng đồng.
muaz-khan/Canvas-Designer dùng license gì?
muaz-khan/Canvas-Designer phát hành theo license MIT. Nên mở file LICENSE trên GitHub để xác nhận — license metadata đôi khi lệch với thực tế dự án.
Đọc đầy đủ README ở tab phía trên.