From d50d075a98c73595312f5c0992dd6b01170137c5 Mon Sep 17 00:00:00 2001 From: Torsten Date: Thu, 29 Dec 2022 21:20:23 +0200 Subject: [PATCH] image editing by vue app, no server yet --- app/controllers/merged/images_controller.rb | 1 + app/views/merged/images/_editor.haml | 67 ++++++++++++++++++++ app/views/merged/images/_range_slider.haml | 25 ++++++++ app/views/merged/images/show.haml | 70 ++++++++++++--------- 4 files changed, 133 insertions(+), 30 deletions(-) create mode 100644 app/views/merged/images/_editor.haml create mode 100644 app/views/merged/images/_range_slider.haml diff --git a/app/controllers/merged/images_controller.rb b/app/controllers/merged/images_controller.rb index 37a16dc..cb302d2 100644 --- a/app/controllers/merged/images_controller.rb +++ b/app/controllers/merged/images_controller.rb @@ -27,6 +27,7 @@ module Merged @sections = Section.where(image_id: params[:id].to_i) @cards = Card.where(image_id: params[:id].to_i) @used = ((@cards.length > 0) || (@sections.length > 0)) + @image_data = @image.attributes end def create diff --git a/app/views/merged/images/_editor.haml b/app/views/merged/images/_editor.haml new file mode 100644 index 0000000..e2f8545 --- /dev/null +++ b/app/views/merged/images/_editor.haml @@ -0,0 +1,67 @@ += render "range_slider" + + +%section.image + .flex.justify-center + %range-slider.justify-self-start{"v-model":"scale" , ":min":0, ":max":100 , + ":step": "1"} Scale {{scaled_x}} x {{scaled_y}} == {{scale}} % + .flex.justify-between + %range-slider.justify-self-start.horizontal{"v-model":"off_y" , ":min":0, ":max":"size_y" , + ":step": "1"} Y Offset {{off_y}} + %range-slider{"v-model":"off_x" , ":min":0, ":max":"#{image.height}" , + ":step": "1"} X Offset {{off_x}} + %range-slider{"v-model":"size_x" , ":min":0, ":max":"#{image.width}" , + ":step": "1"} X Size {{size_x}} + %range-slider.justify-self-end.horizontal{"v-model":"size_y" , ":min":0, ":max":"#{image.height}" , + ":step": "1"} Y Size {{size_y}} + .flex.justify-center + .image-container.overflow-hidden.relative{ "v-bind:style": "{height: scaled_y + 'px' , width: scaled_x + 'px'} " } + = image_tag(image.asset_name , class: "") + .absolute.bg-transparent.border-4.border-black{ "v-bind:style": "{height: size_y + 'px' , width: size_x + 'px' , top: off_y + 'px', left: off_x + 'px' }" } + +:ruby2js + class Images < Vue + options el: '.image' + def initialize + @image_data = #{@image_data.to_json.html_safe} + @off_x = 0 + @off_y = 0 + @scale = 100 + @initial_x = @image_data[:width] + @initial_y = @image_data[:height] + @size_x = @image_data[:width] + @size_y = @image_data[:height] + end + def scaled_x + (@initial_x * @scale / 100).to_i + end + def scaled_y + (@initial_y * @scale / 100).to_i + end + def filter_and_sort + dat = @image_data + if(@search_name.length > 0) + dat = dat.filter do |item| + return item["name"].toLowerCase().indexOf(@search_name) > -1 + end + end + if(@search_tag.length > 0) + dat = dat.filter do |item| + return (item.tags.toLowerCase().indexOf(@search_tag) > -1) + end + end + dat = dat.slice().sort do |a, b| #a, b image data hashes + aa = a[@sort_by] + bb = b[@sort_by] + return (aa === bb ? 0 : (aa > bb ? 1 : -1) ) * @sort_dir + end + dat + end + def toggle_new() + if @show_new == true + @show_new = false + else + @show_new = true + end + end + end diff --git a/app/views/merged/images/_range_slider.haml b/app/views/merged/images/_range_slider.haml new file mode 100644 index 0000000..33664dc --- /dev/null +++ b/app/views/merged/images/_range_slider.haml @@ -0,0 +1,25 @@ +%script{'type'=>"text/x-template", id: 'range-slider'} + .rangeslider + %slot + %b {{value}} + %br/ + %input{":max" => "max", ":min" => "min_v", ":step" => "step_v", :type => "range", "v-bind:value" => "value", "v-on:input" => "handleValue($event)"}/ + +:ruby2js + class RangeSlider < Vue + template "#range-slider" + props [:value , :max , :text , :min , :type , :step] + + def initialize + end + def min_v + return (self.min == null) ? 0 : self.min + end + def step_v + return (self.min == null) ? 1 : self.step + end + def handleValue(event) + value = event.target.value + Vue.emit('input', parseFloat(value)) + end + end diff --git a/app/views/merged/images/show.haml b/app/views/merged/images/show.haml index 551b232..e672fb7 100644 --- a/app/views/merged/images/show.haml +++ b/app/views/merged/images/show.haml @@ -2,9 +2,14 @@ .text-xl.font-bold.text-gray-900 Image: #{@image.name} +- if Rails.env.development? + = javascript_include_tag "merged/vue.js" +-else + = javascript_include_tag "merged/vue.min.js" + = render "layouts/merged_header" -.flex.justify-center.gap-2 +.flex.gap-2.m-20 %p .font-bold.mr-2 Name = @image.name @@ -21,35 +26,40 @@ .font-bold Ratio = @image.ratio.round(2) = @image.aspect_ratio --if @used - .grid.grid-cols-2.m-20 - %p - Sections - =@sections.length - %p - Cards - =@cards.length - %div - -@sections.each do |section| - %p - = link_to section.header , merged.section_path(section) - on Page - = link_to section.page.name , merged.page_sections_path(section.page) - %div - -@cards.each do |card| - %p - = link_to card.header , merged.section_cards_path(card.section) - on Page - = link_to card.section.page.name , merged.page_sections_path(card.section.page) --else - .grid.grid-cols-2.m-20 - %div - %p Not used, you may delete - %div +=render "editor" , image: @image +.flex.gap-2.m-20 + -if @used + .grid.grid-cols-2 %p - = form_tag( merged.image_path(@image.id) , {method: :delete } ) do - =submit_button( "Delete" , true) + Sections + =@sections.length + %p + Cards + =@cards.length + %div + -@sections.each do |section| + %p + = link_to section.header , merged.section_path(section) + on Page + = link_to section.page.name , merged.page_sections_path(section.page) + %div + -@cards.each do |card| + %p + = link_to card.header , merged.section_cards_path(card.section) + on Page + = link_to card.section.page.name , merged.page_sections_path(card.section.page) -.m-20 - = image_tag(@image.asset_name) + -else + .grid.grid-cols-2 + %div + %p Not used, you may delete + %div + %p + = form_tag( merged.image_path(@image.id) , {method: :delete } ) do + =submit_button( "Delete" , true) + +:css + .horizontal input { + transform:rotate(270deg); + };