ajax_canvas_field 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b6473159e106c84c7d22f88082f09673881e75ba
4
+ data.tar.gz: 19c2ded0fa28248bad6827bd640ad08d3d1b45ba
5
+ SHA512:
6
+ metadata.gz: 7a1804d70527ba1bab761106cbcf05b240d70909bba0b8a181b40c64ec39d30e4f131c86039ea899e019facac4fac3460f476c64cc51636d0ac06f722f250f78
7
+ data.tar.gz: 8a1b0af731180d5698822a7ed7321a8ed92fefa640ecafffd8abf1508dde7b3115355e5592f6a64dadcc2c64f0c36b357cc2af016fa0580b4a8f10f409688b30
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ajax_canvas_field.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # AjaxCanvasField
2
+
3
+
4
+ ## Installation
5
+
6
+ Add this line to your application's Gemfile:
7
+
8
+ ```ruby
9
+ gem 'ajax_canvas_field'
10
+ ```
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install ajax_canvas_field
19
+
20
+ ## Usage
21
+ There are three tasks you can execute.
22
+
23
+ ### ATTENTION: Use at your own risk! Back your shit up, before using this!
24
+ Each will ask you for the file
25
+ If this gem is installed inside a Rails-Application you just have to written
26
+ e.g.:
27
+ ```
28
+ 'en' -> for en.yml
29
+ 'de' -> for de.yml
30
+ ...
31
+ ```
32
+ One will be the master-file (this one will not be changed)
33
+ and
34
+ One will be the slave-file (this one will be changed)
35
+
36
+ #### Script 1: Interactive
37
+ ```bash
38
+ rake lit:interactive
39
+ ```
40
+ This script will ask you for the missing value.
41
+ It will find every difference and will ask you to fill every hole... yeah.
42
+ After everything is filled out it will merge the data back into your File.
43
+
44
+ #### Script 2: Recent
45
+ ```bash
46
+ rake lit:recent
47
+ ```
48
+ REQUIRED: Connection to Git
49
+ This script will ask you for the missing value.
50
+ It will find everything you changed in your master-file since you last pushed commit.
51
+ After everything is filled out it will merge the data back into your File.
52
+
53
+ #### Script 3: Cleanup (Deletes something!)
54
+ ```bash
55
+ rake lit:cleanup
56
+ ```
57
+ This script will find every key/value inside your slave-file that isn´t present in your master-file.
58
+ And it will be deleted!!!!
59
+
60
+ #### Sometimes the Rake tasks aren't working
61
+ In this case you can use the Rails-Console and the Class -LostInTranslation-.
62
+
63
+ ```bash
64
+ rails c
65
+ ```
66
+ ```
67
+ LostInTranslation.interactive
68
+ or
69
+ LostInTranslation.recent
70
+ or
71
+ LostInTranslation.cleanup
72
+ ```
73
+
74
+ #### Yet to come
75
+ I am planning on an integration of Translation APIs.
76
+
77
+ ## Contributing
78
+
79
+ Bug reports and pull requests are welcome on GitHub at https://github.com/datyv/lost_in_translation. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
80
+
81
+
82
+ ## License
83
+
84
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'ajax_canvas_field/rails/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'ajax_canvas_field'
9
+ spec.version = AjaxCanvasField::Rails::VERSION
10
+ spec.authors = ['datyv']
11
+ spec.email = ['yvesgoizet@gmail.com']
12
+
13
+ spec.summary = 'HTML5 CanvasField Support'
14
+ spec.description = 'Add a CanvasField to point out errors in three different colors'
15
+ spec.homepage = 'https://github.com/Datyv/ajax_canvas_field'
16
+ spec.license = 'MIT'
17
+
18
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
19
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
20
+ if spec.respond_to?(:metadata)
21
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
22
+ else
23
+ raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.'
24
+ end
25
+
26
+ spec.files = `git ls-files -z`.split("\x0")
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = %w[app lib]
29
+
30
+ spec.add_development_dependency 'bundler', '~> 1.15'
31
+ spec.add_development_dependency 'rake', '~> 10.0'
32
+ end
Binary file
Binary file
Binary file
@@ -0,0 +1,192 @@
1
+ document.addEventListener('DOMContentLoaded', function(){
2
+ var canvas = document.getElementById('canvas_field');
3
+ var data_fields = document.getElementsByClassName('canvas_data_field');
4
+ if (canvas) {
5
+ if (data_fields.length == 0) {
6
+ console.log('No Data Field found. Please add canvas_data_field in your code!');
7
+ document.getElementsByClassName('canvas_table')[0].style.display = 'none';
8
+ canvas.style.display = 'none';
9
+ } else {
10
+ canvas.width = canvas.dataset.width;
11
+ canvas.height = canvas.dataset.height;
12
+ var context = canvas.getContext('2d'),
13
+ url = canvas.dataset.url,
14
+ param = canvas.dataset.strongParam,
15
+ token = canvas.dataset.token,
16
+ points = [];
17
+
18
+ function refreshAll(e) {
19
+ points = [];
20
+ initCircles();
21
+ }
22
+
23
+ function initCircles() {
24
+ var data_field = document.getElementsByClassName('active canvas_data_field')[0].dataset;
25
+ var initialData = JSON.parse(data_field.initialData);
26
+ for (i = 0; i < initialData.length; i++) {
27
+ var point = buildCircle(initialData[i][1], initialData[i][2], initialData[i][3]);
28
+ point.database_id = initialData[i][0];
29
+ points.push(point);
30
+ }
31
+ redrawAllCircles();
32
+ }
33
+
34
+ function isPixelCollision(e) {
35
+ e.preventDefault();
36
+
37
+ if (e.type == "contextmenu") return;
38
+
39
+ var r = canvas.getBoundingClientRect(),
40
+ x = e.clientX - r.left,
41
+ y = e.clientY - r.top,
42
+ removed = false,
43
+ i;
44
+
45
+ for (i = points.length - 1; i >= 0; --i) {
46
+ if (context.isPointInPath(points[i], x, y, 'nonzero')) {
47
+ deleteAjax(i);
48
+ removed = true;
49
+ }
50
+ }
51
+
52
+ if (removed == false) {
53
+ createAjax(x, y, e);
54
+ }
55
+ }
56
+
57
+ function buildCircle(x, y, e) {
58
+ var c = new Path2D(),
59
+ offset = 3.5;
60
+
61
+ c.arc(x - offset, y - offset, 7, 0, Math.PI * 2);
62
+ c.color = (typeof e === 'string') ? e : chooseColor(e)
63
+ c.x = x;
64
+ c.y = y;
65
+ return c;
66
+ }
67
+
68
+ function chooseColor(e) {
69
+ if (e === null) return '#ff0000';
70
+ switch (e.which) {
71
+ case 1:
72
+ return canvas.dataset.leftColor;
73
+ case 2:
74
+ return canvas.dataset.middleColor;
75
+ case 3:
76
+ return canvas.dataset.rightColor;
77
+ }
78
+ }
79
+
80
+ function chooseButton(e) {
81
+ if (e === null) return null;
82
+ switch (e.which) {
83
+ case 1:
84
+ return 'left';
85
+ case 2:
86
+ return 'middle';
87
+ case 3:
88
+ return 'right';
89
+ }
90
+ }
91
+
92
+ function deleteAjax(i) {
93
+ var id = points[i].database_id;
94
+ $.ajax({
95
+ type: 'DELETE',
96
+ url: url + '/' + id,
97
+ headers: {
98
+ 'Authorization': 'Token token=' + token
99
+ },
100
+ dataType: "json",
101
+ success: function(data) {
102
+ removeCircle(i, data);
103
+ },
104
+ error: function(data) {
105
+ alert('No connection to Server');
106
+ }
107
+ });
108
+ }
109
+
110
+ function removeCircle(i, data) {
111
+ points.splice(i, 1);
112
+ redrawAllCircles();
113
+ }
114
+
115
+ function createAjax(x, y, e) {
116
+ post_data = collectPostData(x, y, e);
117
+ $.ajax({
118
+ type: 'POST',
119
+ url: url,
120
+ headers: {
121
+ 'Authorization': 'Token token=' + token
122
+ },
123
+ data: post_data,
124
+ dataType: "json",
125
+ success: function(data) {
126
+ addCircle(x, y, data, e);
127
+ },
128
+ error: function(data) {
129
+ alert('No connection to Server');
130
+ }
131
+ });
132
+ }
133
+
134
+ function collectPostData(x, y, e) {
135
+ var params = {};
136
+ var data_field = document.getElementsByClassName('active canvas_data_field')[0].dataset;
137
+ var additionalData = JSON.parse(data_field.additionalData);
138
+ params[param] = {
139
+ x_value: x,
140
+ y_value: y,
141
+ button: chooseButton(e)
142
+ };
143
+ for (var attrname in additionalData) {
144
+ params[param][attrname] = additionalData[attrname];
145
+ }
146
+ return params;
147
+ }
148
+
149
+ function addCircle(x, y, data, e) {
150
+ new_point = buildCircle(x, y, e);
151
+ new_point['database_id'] = data.id;
152
+ points.push(new_point);
153
+ redrawAllCircles();
154
+ }
155
+
156
+ function redrawAllCircles() {
157
+ var tmpData = [];
158
+ context.clearRect(0, 0, canvas.width, canvas.height);
159
+ for (i = 0; i < points.length; i++) {
160
+ context.fillStyle = points[i].color;
161
+ context.fill(points[i], 'nonzero');
162
+ context.stroke(points[i], 'nonzero');
163
+
164
+ tmpData.push([points[i].database_id, points[i].x, points[i].y, points[i].color]);
165
+ }
166
+ document.getElementsByClassName('active canvas_data_field')[0].dataset.initialData = JSON.stringify(tmpData);
167
+ }
168
+
169
+ canvas.addEventListener('click', isPixelCollision, false);
170
+ canvas.addEventListener('auxclick', isPixelCollision, false);
171
+ canvas.addEventListener('contextmenu', isPixelCollision, false);
172
+ initCircles();
173
+
174
+ var tableRows = document.getElementsByClassName('request_row');
175
+ var markRequestRow = function() {
176
+ for (var i = 0; i < tableRows.length; i++) {
177
+ tableRows[i].classList.remove('active');
178
+ }
179
+ for (var i = 0; i < data_fields.length; i++) {
180
+ data_fields[i].classList.remove('active');
181
+ }
182
+ this.classList.add('active');
183
+ this.getElementsByClassName('canvas_data_field')[0].classList.add('active');
184
+ refreshAll();
185
+ };
186
+
187
+ for (var i = 0; i < tableRows.length; i++) {
188
+ tableRows[i].addEventListener('click', markRequestRow, false);
189
+ }
190
+ }
191
+ }
192
+ }, false);
@@ -0,0 +1,42 @@
1
+ var canvases = document.getElementsByClassName('canvas_field');
2
+ if (canvases) {
3
+ for (o = 0; o < canvases.length; o++) {
4
+ var canvas = canvases[o];
5
+ canvas.width = canvas.dataset.width;
6
+ canvas.height = canvas.dataset.height;
7
+ var context = canvas.getContext('2d');
8
+ var points = [];
9
+
10
+ function initCircles() {
11
+ var initialData = JSON.parse(canvas.dataset.initialData);
12
+ for (i = 0; i < initialData.length; i++) {
13
+ var point = buildCircle(initialData[i][1], initialData[i][2], initialData[i][3]);
14
+ point.database_id = initialData[i][0];
15
+ points.push(point);
16
+ }
17
+ redrawAllCircles();
18
+ }
19
+
20
+ function buildCircle(x, y, e) {
21
+ var c = new Path2D(),
22
+ offset = 3.5;
23
+
24
+ c.arc(x - offset, y - offset, 7, 0, Math.PI * 2);
25
+ c.color = (typeof e === 'string') ? e : '#ff0000'
26
+ c.x = x;
27
+ c.y = y;
28
+ return c;
29
+ }
30
+
31
+ function redrawAllCircles() {
32
+ context.clearRect(0, 0, canvas.width, canvas.height);
33
+ for (i = 0; i < points.length; i++) {
34
+ context.fillStyle = points[i].color;
35
+ context.fill(points[i], 'nonzero');
36
+ context.stroke(points[i], 'nonzero');
37
+ }
38
+ }
39
+
40
+ initCircles();
41
+ }
42
+ }
@@ -0,0 +1,24 @@
1
+ #canvas_field {
2
+ border: 1px groove lightgrey;
3
+ }
4
+
5
+ .canvas_field {
6
+ border: 1px groove lightgrey;
7
+ }
8
+
9
+ .canvas_data_field {
10
+ display: none;
11
+ }
12
+
13
+ .canvas_legend_sub {
14
+ height: 30px;
15
+ font-weight: 600;
16
+ padding-top: 9px;
17
+ text-align: center;
18
+ }
19
+
20
+ tr.active {
21
+ -webkit-box-shadow: 0px 0px 25px -2px #967474 inset;
22
+ -moz-box-shadow: 0px 0px 25px -2px #967474 inset;
23
+ box-shadow: 0px 0px 25px -2px #967474 inset;
24
+ }
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CanvasFieldHelper
4
+ def canvas_field(options = {})
5
+ url = '/'
6
+ url += options[:namespace].to_s + '/' if options[:namespace]
7
+ url += options[:controller] || 'canvas_fields'
8
+
9
+ background_url = options[:background_url].blank? ? '' : "url(#{options[:background_url]})"
10
+ background = "background: #fff #{background_url} no-repeat center top"
11
+ failure_message = 'Your browser does not support the canvas element.'
12
+
13
+ content_tag :canvas, failure_message, id: :canvas_field, data: collect_data(url, options), style: background
14
+ end
15
+
16
+ def canvas_data_field(active = false, options = {})
17
+ klass = active ? 'active' : ''
18
+ data = { additional_data: options[:additional_data].to_json,
19
+ initial_data: options[:initial_data].to_json,
20
+ content: options[:content] || '' }
21
+ content_tag(:span, '', class: "#{klass} canvas_data_field", data: data)
22
+ end
23
+
24
+ def canvas_legend_field(options = {})
25
+ locals = {
26
+ left_text: options[:left_text] || '',
27
+ middle_text: options[:middle_text] || '',
28
+ right_text: options[:right_text] || '',
29
+ left_color: options[:left_color] || '#ff0000',
30
+ middle_color: options[:middle_color] || '#00ff00',
31
+ right_color: options[:right_color] || '#0000ff',
32
+ no_icon: options[:no_icon] || false,
33
+ no_header: options[:no_header] || false
34
+ }
35
+ render partial: 'ajax_canvas_field/canvas_legend', locals: locals
36
+ end
37
+
38
+ def ro_canvas_field(options = {})
39
+ background_url = options[:background_url].blank? ? '' : "url(#{options[:background_url]})"
40
+ background = "background: #fff #{background_url} no-repeat center top"
41
+ failure_message = 'Your browser does not support the canvas element.'
42
+
43
+ content_tag :canvas, failure_message, data: collect_ro_data(options), style: background, class: 'canvas_field'
44
+ end
45
+
46
+ private
47
+
48
+ def collect_data(url, options)
49
+ { url: url,
50
+ strong_param: options[:param] || options[:controller]&.singularize || 'canvas_field',
51
+ token: options[:token],
52
+ width: options[:width] || AjaxCanvasField.config[:default_width],
53
+ height: options[:height] || AjaxCanvasField.config[:default_height],
54
+ left_color: options[:left_color] || '#ff0000',
55
+ middle_color: options[:middle_color] || '#00ff00',
56
+ right_color: options[:right_color] || '#0000ff' }
57
+ end
58
+
59
+ def collect_ro_data(options)
60
+ { width: options[:width] || AjaxCanvasField.config[:default_width],
61
+ height: options[:height] || AjaxCanvasField.config[:default_height],
62
+ left_color: options[:left_color] || '#ff0000',
63
+ middle_color: options[:middle_color] || '#00ff00',
64
+ right_color: options[:right_color] || '#0000ff',
65
+ initial_data: options[:initial_data].to_json }
66
+ end
67
+ end
@@ -0,0 +1,21 @@
1
+ %table
2
+ - unless no_header
3
+ %thead
4
+ %tr
5
+ %th.canvas_legend_sub Linke Maustaste
6
+ %th.canvas_legend_sub Mittlere Maustaste
7
+ %th.canvas_legend_sub Rechte Maustaste
8
+ %tbody
9
+ - unless no_icon
10
+ %tr
11
+ %td.canvas_legend_sub= image_tag('mouse_left.png', size: '50x50')
12
+ %td.canvas_legend_sub= image_tag('mouse_middle.png', size: '50x50')
13
+ %td.canvas_legend_sub= image_tag('mouse_right.png', size: '50x50')
14
+ %tr
15
+ %td.canvas_legend_sub= left_text
16
+ %td.canvas_legend_sub= middle_text
17
+ %td.canvas_legend_sub= right_text
18
+ %tr
19
+ %td.canvas_legend_sub{ style: "background-color: #{left_color}" }
20
+ %td.canvas_legend_sub{ style: "background-color: #{middle_color}" }
21
+ %td.canvas_legend_sub{ style: "background-color: #{right_color}" }
Binary file
Binary file
Binary file
@@ -0,0 +1,192 @@
1
+ document.addEventListener('DOMContentLoaded', function(){
2
+ var canvas = document.getElementById('canvas_field');
3
+ var data_fields = document.getElementsByClassName('canvas_data_field');
4
+ if (canvas) {
5
+ if (data_fields.length == 0) {
6
+ console.log('No Data Field found. Please add canvas_data_field in your code!');
7
+ document.getElementsByClassName('canvas_table')[0].style.display = 'none';
8
+ canvas.style.display = 'none';
9
+ } else {
10
+ canvas.width = canvas.dataset.width;
11
+ canvas.height = canvas.dataset.height;
12
+ var context = canvas.getContext('2d'),
13
+ url = canvas.dataset.url,
14
+ param = canvas.dataset.strongParam,
15
+ token = canvas.dataset.token,
16
+ points = [];
17
+
18
+ function refreshAll(e) {
19
+ points = [];
20
+ initCircles();
21
+ }
22
+
23
+ function initCircles() {
24
+ var data_field = document.getElementsByClassName('active canvas_data_field')[0].dataset;
25
+ var initialData = JSON.parse(data_field.initialData);
26
+ for (i = 0; i < initialData.length; i++) {
27
+ var point = buildCircle(initialData[i][1], initialData[i][2], initialData[i][3]);
28
+ point.database_id = initialData[i][0];
29
+ points.push(point);
30
+ }
31
+ redrawAllCircles();
32
+ }
33
+
34
+ function isPixelCollision(e) {
35
+ e.preventDefault();
36
+
37
+ if (e.type == "contextmenu") return;
38
+
39
+ var r = canvas.getBoundingClientRect(),
40
+ x = e.clientX - r.left,
41
+ y = e.clientY - r.top,
42
+ removed = false,
43
+ i;
44
+
45
+ for (i = points.length - 1; i >= 0; --i) {
46
+ if (context.isPointInPath(points[i], x, y, 'nonzero')) {
47
+ deleteAjax(i);
48
+ removed = true;
49
+ }
50
+ }
51
+
52
+ if (removed == false) {
53
+ createAjax(x, y, e);
54
+ }
55
+ }
56
+
57
+ function buildCircle(x, y, e) {
58
+ var c = new Path2D(),
59
+ offset = 3.5;
60
+
61
+ c.arc(x - offset, y - offset, 7, 0, Math.PI * 2);
62
+ c.color = (typeof e === 'string') ? e : chooseColor(e)
63
+ c.x = x;
64
+ c.y = y;
65
+ return c;
66
+ }
67
+
68
+ function chooseColor(e) {
69
+ if (e === null) return '#ff0000';
70
+ switch (e.which) {
71
+ case 1:
72
+ return canvas.dataset.leftColor;
73
+ case 2:
74
+ return canvas.dataset.middleColor;
75
+ case 3:
76
+ return canvas.dataset.rightColor;
77
+ }
78
+ }
79
+
80
+ function chooseButton(e) {
81
+ if (e === null) return null;
82
+ switch (e.which) {
83
+ case 1:
84
+ return 'left';
85
+ case 2:
86
+ return 'middle';
87
+ case 3:
88
+ return 'right';
89
+ }
90
+ }
91
+
92
+ function deleteAjax(i) {
93
+ var id = points[i].database_id;
94
+ $.ajax({
95
+ type: 'DELETE',
96
+ url: url + '/' + id,
97
+ headers: {
98
+ 'Authorization': 'Token token=' + token
99
+ },
100
+ dataType: "json",
101
+ success: function(data) {
102
+ removeCircle(i, data);
103
+ },
104
+ error: function(data) {
105
+ alert('No connection to Server');
106
+ }
107
+ });
108
+ }
109
+
110
+ function removeCircle(i, data) {
111
+ points.splice(i, 1);
112
+ redrawAllCircles();
113
+ }
114
+
115
+ function createAjax(x, y, e) {
116
+ post_data = collectPostData(x, y, e);
117
+ $.ajax({
118
+ type: 'POST',
119
+ url: url,
120
+ headers: {
121
+ 'Authorization': 'Token token=' + token
122
+ },
123
+ data: post_data,
124
+ dataType: "json",
125
+ success: function(data) {
126
+ addCircle(x, y, data, e);
127
+ },
128
+ error: function(data) {
129
+ alert('No connection to Server');
130
+ }
131
+ });
132
+ }
133
+
134
+ function collectPostData(x, y, e) {
135
+ var params = {};
136
+ var data_field = document.getElementsByClassName('active canvas_data_field')[0].dataset;
137
+ var additionalData = JSON.parse(data_field.additionalData);
138
+ params[param] = {
139
+ x_value: x,
140
+ y_value: y,
141
+ button: chooseButton(e)
142
+ };
143
+ for (var attrname in additionalData) {
144
+ params[param][attrname] = additionalData[attrname];
145
+ }
146
+ return params;
147
+ }
148
+
149
+ function addCircle(x, y, data, e) {
150
+ new_point = buildCircle(x, y, e);
151
+ new_point['database_id'] = data.id;
152
+ points.push(new_point);
153
+ redrawAllCircles();
154
+ }
155
+
156
+ function redrawAllCircles() {
157
+ var tmpData = [];
158
+ context.clearRect(0, 0, canvas.width, canvas.height);
159
+ for (i = 0; i < points.length; i++) {
160
+ context.fillStyle = points[i].color;
161
+ context.fill(points[i], 'nonzero');
162
+ context.stroke(points[i], 'nonzero');
163
+
164
+ tmpData.push([points[i].database_id, points[i].x, points[i].y, points[i].color]);
165
+ }
166
+ document.getElementsByClassName('active canvas_data_field')[0].dataset.initialData = JSON.stringify(tmpData);
167
+ }
168
+
169
+ canvas.addEventListener('click', isPixelCollision, false);
170
+ canvas.addEventListener('auxclick', isPixelCollision, false);
171
+ canvas.addEventListener('contextmenu', isPixelCollision, false);
172
+ initCircles();
173
+
174
+ var tableRows = document.getElementsByClassName('request_row');
175
+ var markRequestRow = function() {
176
+ for (var i = 0; i < tableRows.length; i++) {
177
+ tableRows[i].classList.remove('active');
178
+ }
179
+ for (var i = 0; i < data_fields.length; i++) {
180
+ data_fields[i].classList.remove('active');
181
+ }
182
+ this.classList.add('active');
183
+ this.getElementsByClassName('canvas_data_field')[0].classList.add('active');
184
+ refreshAll();
185
+ };
186
+
187
+ for (var i = 0; i < tableRows.length; i++) {
188
+ tableRows[i].addEventListener('click', markRequestRow, false);
189
+ }
190
+ }
191
+ }
192
+ }, false);
@@ -0,0 +1,42 @@
1
+ var canvases = document.getElementsByClassName('canvas_field');
2
+ if (canvases) {
3
+ for (o = 0; o < canvases.length; o++) {
4
+ var canvas = canvases[o];
5
+ canvas.width = canvas.dataset.width;
6
+ canvas.height = canvas.dataset.height;
7
+ var context = canvas.getContext('2d');
8
+ var points = [];
9
+
10
+ function initCircles() {
11
+ var initialData = JSON.parse(canvas.dataset.initialData);
12
+ for (i = 0; i < initialData.length; i++) {
13
+ var point = buildCircle(initialData[i][1], initialData[i][2], initialData[i][3]);
14
+ point.database_id = initialData[i][0];
15
+ points.push(point);
16
+ }
17
+ redrawAllCircles();
18
+ }
19
+
20
+ function buildCircle(x, y, e) {
21
+ var c = new Path2D(),
22
+ offset = 3.5;
23
+
24
+ c.arc(x - offset, y - offset, 7, 0, Math.PI * 2);
25
+ c.color = (typeof e === 'string') ? e : '#ff0000'
26
+ c.x = x;
27
+ c.y = y;
28
+ return c;
29
+ }
30
+
31
+ function redrawAllCircles() {
32
+ context.clearRect(0, 0, canvas.width, canvas.height);
33
+ for (i = 0; i < points.length; i++) {
34
+ context.fillStyle = points[i].color;
35
+ context.fill(points[i], 'nonzero');
36
+ context.stroke(points[i], 'nonzero');
37
+ }
38
+ }
39
+
40
+ initCircles();
41
+ }
42
+ }
@@ -0,0 +1,24 @@
1
+ #canvas_field {
2
+ border: 1px groove lightgrey;
3
+ }
4
+
5
+ .canvas_field {
6
+ border: 1px groove lightgrey;
7
+ }
8
+
9
+ .canvas_data_field {
10
+ display: none;
11
+ }
12
+
13
+ .canvas_legend_sub {
14
+ height: 30px;
15
+ font-weight: 600;
16
+ padding-top: 9px;
17
+ text-align: center;
18
+ }
19
+
20
+ tr.active {
21
+ -webkit-box-shadow: 0px 0px 25px -2px #967474 inset;
22
+ -moz-box-shadow: 0px 0px 25px -2px #967474 inset;
23
+ box-shadow: 0px 0px 25px -2px #967474 inset;
24
+ }
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CanvasFieldHelper
4
+ def canvas_field(options = {})
5
+ url = '/'
6
+ url += options[:namespace].to_s + '/' if options[:namespace]
7
+ url += options[:controller] || 'canvas_fields'
8
+
9
+ background_url = options[:background_url].blank? ? '' : "url(#{options[:background_url]})"
10
+ background = "background: #fff #{background_url} no-repeat center top"
11
+ failure_message = 'Your browser does not support the canvas element.'
12
+
13
+ content_tag :canvas, failure_message, id: :canvas_field, data: collect_data(url, options), style: background
14
+ end
15
+
16
+ def canvas_data_field(active = false, options = {})
17
+ klass = active ? 'active' : ''
18
+ data = { additional_data: options[:additional_data].to_json,
19
+ initial_data: options[:initial_data].to_json,
20
+ content: options[:content] || '' }
21
+ content_tag(:span, '', class: "#{klass} canvas_data_field", data: data)
22
+ end
23
+
24
+ def canvas_legend_field(options = {})
25
+ locals = {
26
+ left_text: options[:left_text] || '',
27
+ middle_text: options[:middle_text] || '',
28
+ right_text: options[:right_text] || '',
29
+ left_color: options[:left_color] || '#ff0000',
30
+ middle_color: options[:middle_color] || '#00ff00',
31
+ right_color: options[:right_color] || '#0000ff',
32
+ no_icon: options[:no_icon] || false,
33
+ no_header: options[:no_header] || false
34
+ }
35
+ render partial: 'ajax_canvas_field/canvas_legend', locals: locals
36
+ end
37
+
38
+ def ro_canvas_field(options = {})
39
+ background_url = options[:background_url].blank? ? '' : "url(#{options[:background_url]})"
40
+ background = "background: #fff #{background_url} no-repeat center top"
41
+ failure_message = 'Your browser does not support the canvas element.'
42
+
43
+ content_tag :canvas, failure_message, data: collect_ro_data(options), style: background, class: 'canvas_field'
44
+ end
45
+
46
+ private
47
+
48
+ def collect_data(url, options)
49
+ { url: url,
50
+ strong_param: options[:param] || options[:controller]&.singularize || 'canvas_field',
51
+ token: options[:token],
52
+ width: options[:width] || AjaxCanvasField.config[:default_width],
53
+ height: options[:height] || AjaxCanvasField.config[:default_height],
54
+ left_color: options[:left_color] || '#ff0000',
55
+ middle_color: options[:middle_color] || '#00ff00',
56
+ right_color: options[:right_color] || '#0000ff' }
57
+ end
58
+
59
+ def collect_ro_data(options)
60
+ { width: options[:width] || AjaxCanvasField.config[:default_width],
61
+ height: options[:height] || AjaxCanvasField.config[:default_height],
62
+ left_color: options[:left_color] || '#ff0000',
63
+ middle_color: options[:middle_color] || '#00ff00',
64
+ right_color: options[:right_color] || '#0000ff',
65
+ initial_data: options[:initial_data].to_json }
66
+ end
67
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ module AjaxCanvasField
6
+ # Configuration defaults
7
+ @config = {
8
+ default_height: 470,
9
+ default_width: 470,
10
+ default_left_color: '#ff0000',
11
+ default_middle_color: '#00ff00',
12
+ default_right_color: '#0000ff'
13
+ }
14
+
15
+ @valid_config_keys = @config.keys
16
+
17
+ # Configure through hash
18
+ def self.configure(opts = {})
19
+ opts.each { |k, v| @config[k.to_sym] = v if @valid_config_keys.include? k.to_sym }
20
+ end
21
+
22
+ # Configure through yaml file
23
+ def self.configure_with(path_to_yaml_file)
24
+ begin
25
+ config = YAML.safe_load(IO.read(path_to_yaml_file))
26
+ rescue Errno::ENOENT
27
+ log(:warning, "YAML configuration file couldn't be found. Using defaults."); return
28
+ rescue Psych::SyntaxError
29
+ log(:warning, 'YAML configuration file contains invalid syntax. Using defaults.'); return
30
+ end
31
+
32
+ configure(config)
33
+ end
34
+
35
+ def self.config
36
+ @config
37
+ end
38
+ end
@@ -0,0 +1,12 @@
1
+ module AjaxCanvasField #:nodoc:
2
+ module Rails #:nodoc:
3
+ class Engine < ::Rails::Engine
4
+ initializer 'ajax_canvas_field.assets.precompile' do |app|
5
+ %w(stylesheets javascripts images).each do |sub|
6
+ app.config.assets.paths << root.join('app/assets', sub).to_s
7
+ end
8
+ app.config.assets.precompile += %w( mouse_left.png mouse_right.png mouse_middle.png )
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ module AjaxCanvasField #:nodoc:
2
+ module Rails #:nodoc:
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ require 'ajax_canvas_field/rails/engine' if ::Rails.version >= '3.1'
2
+ require 'ajax_canvas_field/rails/version'
3
+
4
+ module AjaxCanvasField #:nodoc:
5
+ module Rails #:nodoc:
6
+ end
7
+ end
@@ -0,0 +1,2 @@
1
+ require 'ajax_canvas_field/rails'
2
+ require 'ajax_canvas_field/config'
@@ -0,0 +1,15 @@
1
+ require 'rails/generators/base'
2
+
3
+ class AjaxCanvasFieldGenerator < Rails::Generators::Base
4
+ source_root File.expand_path("../templates", __FILE__)
5
+
6
+ desc "Copy the initializer for AjaxCanvasField"
7
+ def copy_initializer_file
8
+ copy_file "initializer.rb", "config/initializers/ajax_canvas_field.rb"
9
+
10
+ inject_into_file 'app/assets/javascripts/application.js', "//= require ajax_canvas_field\n", before: "//= require_tree ." rescue nil
11
+ inject_into_file 'app/assets/stylesheets/application.scss', " *= require ajax_canvas_field\n", before: " *= require_tree ." rescue nil
12
+ inject_into_file 'app/assets/stylesheets/application.scss.erb', " *= require ajax_canvas_field\n", before: " *= require_tree ." rescue nil
13
+ inject_into_file 'app/assets/stylesheets/application.css.scss', " *= require ajax_canvas_field\n", before: " *= require_tree ." rescue nil
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ AjaxCanvasField.configure(default_height: 400,
4
+ default_width: 400,
5
+ default_left_color: '#ff0000',
6
+ default_middle_color: '#00ff00',
7
+ default_right_color: '#0000ff')
@@ -0,0 +1,21 @@
1
+ %table
2
+ - unless no_header
3
+ %thead
4
+ %tr
5
+ %th.canvas_legend_sub Linke Maustaste
6
+ %th.canvas_legend_sub Mittlere Maustaste
7
+ %th.canvas_legend_sub Rechte Maustaste
8
+ %tbody
9
+ - unless no_icon
10
+ %tr
11
+ %td.canvas_legend_sub= image_tag('mouse_left.png', size: '50x50')
12
+ %td.canvas_legend_sub= image_tag('mouse_middle.png', size: '50x50')
13
+ %td.canvas_legend_sub= image_tag('mouse_right.png', size: '50x50')
14
+ %tr
15
+ %td.canvas_legend_sub= left_text
16
+ %td.canvas_legend_sub= middle_text
17
+ %td.canvas_legend_sub= right_text
18
+ %tr
19
+ %td.canvas_legend_sub{ style: "background-color: #{left_color}" }
20
+ %td.canvas_legend_sub{ style: "background-color: #{middle_color}" }
21
+ %td.canvas_legend_sub{ style: "background-color: #{right_color}" }
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ajax_canvas_field
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - datyv
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-10-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.15'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.15'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Add a CanvasField to point out errors in three different colors
42
+ email:
43
+ - yvesgoizet@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - Gemfile
49
+ - README.md
50
+ - Rakefile
51
+ - ajax_canvas_field.gemspec
52
+ - app/assets/images/mouse_left.png
53
+ - app/assets/images/mouse_middle.png
54
+ - app/assets/images/mouse_right.png
55
+ - app/assets/javascripts/ajax_canvas_field.js
56
+ - app/assets/javascripts/ro_canvas_field.js
57
+ - app/assets/stylesheets/ajax_canvas_field.css
58
+ - app/helpers/canvas_field_helper.rb
59
+ - app/views/ajax_canvas_field/_canvas_legend.html.haml
60
+ - assets/images/mouse_left.png
61
+ - assets/images/mouse_middle.png
62
+ - assets/images/mouse_right.png
63
+ - assets/javascripts/ajax_canvas_field.js
64
+ - assets/javascripts/ro_canvas_field.js
65
+ - assets/stylesheets/ajax_canvas_field.css
66
+ - helpers/canvas_field_helper.rb
67
+ - lib/ajax_canvas_field.rb
68
+ - lib/ajax_canvas_field/config.rb
69
+ - lib/ajax_canvas_field/rails.rb
70
+ - lib/ajax_canvas_field/rails/engine.rb
71
+ - lib/ajax_canvas_field/rails/version.rb
72
+ - lib/generators/ajax_canvas_field/ajax_canvas_field_generator.rb
73
+ - lib/generators/ajax_canvas_field/templates/initializer.rb
74
+ - views/ajax_canvas_field/_canvas_legend.html.haml
75
+ homepage: https://github.com/Datyv/ajax_canvas_field
76
+ licenses:
77
+ - MIT
78
+ metadata:
79
+ allowed_push_host: https://rubygems.org
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - app
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 2.5.2
98
+ signing_key:
99
+ specification_version: 4
100
+ summary: HTML5 CanvasField Support
101
+ test_files: []