以HTML5响应画布文本为中心

时间:2018-02-08 06:36:17

标签: javascript html html5 canvas center

我使用以下功能允许应用用户在其画布照片上插入文字。当文本接近边缘时,它的工作正如预期的那样缩小,但如果文本不大于画布,我无法弄清楚如何使文本居中。

var canvas4 = document.getElementById("canvas4");
        var ctx4 = canvas4.getContext("2d");

        canvas4.width = $(window).width();
        canvas4.height = $(window).height();

        var txt = value,
            tw,
            oc, octx;
        ctx4.font = '40px sans-serif';
        ctx4.fillStyle = 'blue';
        ctx4.textBaseline = 'top';
        ctx4.globalAlpha = 0.50;

        tw = ctx4.measureText(txt).width;

        if (tw > canvas4.width - 20) {
                oc = document.createElement('canvas');
                octx = oc.getContext('2d');
                oc.width = tw;
                oc.height = parseInt(ctx4.font, 10) * 1.2;
                octx.font = '40px sans-serif';
                octx.textBaseline = 'top';
                octx.fillText(txt, 0, 0);
                ctx4.drawImage(oc, 10, canvas4.height - 100, canvas4.width - 20, (canvas4.width - 20) / tw * oc.height);
        } else {
            ctx4.fillText(txt, 10, canvas4.height - 100);
        };

我尝试过文字对齐,例如 ctx4.textAlign = 'center, canvas4.width / 2, canvas4.height - 100';

2 个答案:

答案 0 :(得分:1)

import requests
import os
from Tkinter import Label, Frame, Tk, BOTH, TOP, LEFT, X, Button, Entry, FLAT, StringVar, DISABLED
from ttk import Progressbar
import tkFont
import tkMessageBox

class Downloader:

    def __init__(self,parent):
        self.parent = parent
        self.parent.title("downloader")

        self.parent_frame = Frame(self.parent)
        self.parent_frame.pack(fill=BOTH,expand=True)   # expands fill all remining spaces
        self.control_button_frame=Frame(self.parent_frame)
        self.control_button_frame.pack(side=TOP,fill=X)

        self.downloading_url=StringVar()
        self.downloading_url.set("paste downloadable url here (use ctrl + v)")  # make a Tkinter StringVar between root = Tk() window

        self.req_obj = None
        self.source_file_size = None

        self.error_msg = None
        self.downloaded_file_size = 0

        self.pause_flag = 0
        self.cancel_flag = 0

        self.AddContainers()
        self.AddWidgets()

    def AddContainers(self):

        self.top_frame = Frame(self.parent_frame)
        self.top_frame.pack(side=TOP,pady=10,padx=10,fill=X)

        self.downloads_details_frame=Frame(self.parent_frame)
        self.downloads_details_frame.pack(side=TOP,padx=10,fill=X)

        self.status_history_buttons_frame=Frame(self.downloads_details_frame)
        self.status_history_buttons_frame.pack(side=TOP,fill=X)

        self.downloads_status_show_frame=Frame(self.downloads_details_frame,bg="white")
        self.downloads_status_show_frame.pack(side=TOP,fill=X)

        self.downloads_status_show_left_frame = Frame(self.downloads_status_show_frame)
        self.downloads_status_show_left_frame.pack(side=LEFT, fill=X)

        self.downloads_status_show_right_frame = Frame(self.downloads_status_show_frame)
        self.downloads_status_show_right_frame.pack(side=LEFT, fill=X)

        self.progress_bar_frame = Frame(self.parent_frame)
        self.progress_bar_frame.pack(side=TOP,fill=X)

        self.control_button_frame=Frame(self.parent_frame)
        self.control_button_frame.pack(side=TOP,fill=X)

    def AddWidgets(self):

        label_names = ["Status","File size","Downloaded","Transfer rate","Time left","Resume Capability"]
        self.downloading_status_data_label = {}

        address_label = Label(self.top_frame, text ="Address")
        address_label.pack(side="left")
        self.url_font_style = tkFont.Font(family = 'ms sans Serif', size = 9, weight = "normal" )

        self.url_entry_field = Entry(self.top_frame,width=60,font = self.url_font_style,textvariable=self.downloading_url)
        self.url_entry_field.pack(side="left",padx=5,fill=X,expand=True)

        self.url_ok_button = Button(self.top_frame, text ="Download", width = 8, command = self.UrlProcessing)
        self.url_ok_button.pack(side="left")

        self.status_button = Button(self.status_history_buttons_frame,text="Download Status",relief=FLAT,bg="white",anchor="w", width=13)
        self.status_button.pack(side="left")

        self.show_history_button=Button(self.status_history_buttons_frame,text="History")
        self.show_history_button.pack(side="left")

        for names in label_names:
            lab = Label(self.downloads_status_show_left_frame, text=names, anchor="w",bg="white", width=16)
            lab.pack(side=TOP,fill=X)

        self.status_data_label = Label(self.downloads_status_show_right_frame, text = "N/A", anchor="w",bg="white")
        self.status_data_label.pack(side=TOP,fill=X)

        self.file_size_data_label = Label(self.downloads_status_show_right_frame, text = "N/A", anchor="w",bg="white")
        self.file_size_data_label.pack(side=TOP,fill=X)

        self.downloaded_data_label = Label(self.downloads_status_show_right_frame, text = "N/A", anchor="w",bg="white")
        self.downloaded_data_label.pack(side=TOP,fill=X)

        self.transfer_rate_data_label = Label(self.downloads_status_show_right_frame, text = "N/A", anchor="w",bg="white")
        self.transfer_rate_data_label.pack(side=TOP,fill=X)

        self.time_left_data_label = Label(self.downloads_status_show_right_frame, text = "N/A", anchor="w",bg="white")
        self.time_left_data_label.pack(side=TOP,fill=X)

        self.resume_status_data_label = Label(self.downloads_status_show_right_frame, text = "N/A", anchor="w",bg="white")
        self.resume_status_data_label.pack(side=TOP,fill=X)

        self.progress=Progressbar(self.progress_bar_frame,orient="horizontal",length=200,mode="determinate")
        self.progress.pack(fill=X,side="left",expand=True)

        self.progress["value"] = 0

        self.cancel_button=Button(self.control_button_frame,text="cancel",width=8, command = self.CancelDownload)
        self.cancel_button.pack(side="right",padx=10,pady=5)

        self.start_pause_button=Button(self.control_button_frame,text="pause",width=8, command = self.StartPause)
        self.start_pause_button.pack(side="right",padx=10,pady=5)

    def ErrorMessageHandler(self,err_message):
        tkMessageBox.showerror("Error",err_message)

    def ShowMessage(self,title,message):
        tkMessageBox.showinfo(title,message)

    def UpdateDownloadingDetails(self,meta_data):

        self.status_data_label.config(text=meta_data["Status"])
        self.file_size_data_label.config(text=meta_data["File size"])
        self.downloaded_data_label.config(text=meta_data["Downloaded"])
        self.transfer_rate_data_label.config(text=meta_data["Transfer rate"])
        self.time_left_data_label.config(text=meta_data["Time left"])
        self.parent.update()

    def CancelDownload(self):
        self.cancel_flag = 1

    def StartPause(self):

        if self.pause_flag == 0:
            self.start_pause_button.config(text ="start")
            self.parent.update()
            self.pause_flag = 1
        else:
            self.start_pause_button.config(text ="pause")
            self.parent.update()
            self.pause_flag = 0
            self.UrlProcessing()

    def MakeRequest(self,source_url):
        start_byte_pos = 0
        start_header = {'Range': 'bytes=%d-' % start_byte_pos}
        try:
            self.req_obj = requests.get(source_url, headers=start_header, stream = True)

            if self.req_obj.status_code == 206:                
                self.source_file_size = int(self.req_obj.headers['Content-Length'])
                self.progress["maximum"] = self.source_file_size
                return True

        except HTTPError, e:
            self.error_msg = 'HTTPError = ' + str(e.code)
            return False
        except URLError, e:
            self.error_msg = 'URLError = ' + str(e.reason)
            return False
        except httplib.HTTPException, e:
            self.error_msg = 'HTTPException'
            return False
        except Exception:            
            self.error_msg = 'generic exception: ' + "Unknown Url Type"     #traceback.format_exc()
            return False

    def GetSizeInFormat(self, total_bytes):

        formatted_size = None

        if total_bytes < 1024:
            formatted_size= str(total_bytes)+" Bytes"
        elif total_bytes < 1048576:
            formatted_size = str(float(total_bytes/1024))+" KB"

            if (total_bytes % 1024) >= 8:
                formatted_size = str(total_bytes/1024) + "."+str(int ( (total_bytes % 1024 ) / 8)) + " KB"
        elif total_bytes < 1073741824:
            formatted_size = str(float(total_bytes/1048576))+" MB"

            if (total_bytes % 1048576) >= 1024:
                formatted_size = str(total_bytes/1048576) + "."+str(int ( (total_bytes % 1048576 ) / 1024)) + " MB"
        elif total_bytes >= 1073741824:

            formatted_size = str(float(total_bytes/1073741824))+" GB"

            if (total_bytes % 1073741824) >= 1048576:
                formatted_size = str(total_bytes/1073741824) + "."+str(int ( (total_bytes % 1073741824 ) / 1048576)) + " GB"

        return formatted_size

    def GetTimeInFormat(self, total_seconds):

        formatted_time = None

        if total_seconds >= 3600:
            formatted_time = str(total_seconds/3600)+" hr"

            if (total_seconds % 3600) >= 60:
                formatted_time = formatted_time+" "+str( (total_seconds % 3600) / 60)+" min"
            elif (total_seconds % 3600) < 60 and (total_seconds % 3600) > 0:
                formatted_time = formatted_time +" "+str(total_seconds%3600)+" sec"

        elif total_seconds >= 60:
            formatted_time = str(total_seconds / 60)+" min"

            if (total_seconds % 60) >0:
                formatted_time = formatted_time+" "+str(total_seconds % 60)+" sec"
        else:
            formatted_time = str(total_seconds)+" sec"

        return formatted_time


    def GetFileName(self,source_url):
        file_name = None

        temp = source_url.split('/')[-1]

        for raw_data in ['<','>',':','"','/','|','?','*']:
            if raw_data in temp:
                temp = temp.replace(raw_data,'_')

        file_name = temp

        return file_name

    def CheckFileExistence(self,file_name):

        if os.path.exists(file_name):
            return True
        else:
            return False

    def GetLocalFileSize(self,file_name):
        return os.path.getsize(file_name)

    def SetResumeDownload(self,fileurl, resume_byte_pos):
        resume_header = {'Range': 'bytes=%d-' % resume_byte_pos}
        return requests.get(fileurl, headers=resume_header, stream=True)    

    def DownloadFile(self,file_ptr):

        chunk_size = (1024*1024)

        self.status_data_label.config(text="downloading")
        self.file_size_data_label.config(text=self.GetSizeInFormat(self.source_file_size))
        self.downloaded_data_label.config(text=self.GetSizeInFormat(self.downloaded_file_size))

        self.transfer_rate_data_label.config(text = self.GetSizeInFormat(1024*1024))

        temp = (self.source_file_size-self.downloaded_file_size)/chunk_size
        self.time_left_data_label.config(text= self.GetTimeInFormat(temp))

        self.resume_status_data_label.config(text="yes", fg="blue")

        self.parent.update()

        for chunk in self.req_obj.iter_content(chunk_size):

            self.parent.update()

            if chunk:                
                self.downloaded_file_size = self.downloaded_file_size + len(chunk)
                file_ptr.write(chunk)

            self.downloaded_data_label.config(text=self.GetSizeInFormat(self.downloaded_file_size))
            temp = (self.source_file_size-self.downloaded_file_size)/chunk_size

            self.time_left_data_label.config(text= self.GetTimeInFormat(temp))

            self.progress["value"] = self.downloaded_file_size

            self.parent.update()

            if self.pause_flag == 1:
                self.req_obj.close()
                break

            if self.cancel_flag ==1:
                file_ptr.flush()
                file_ptr.close()
                self.req_obj.close()
                self.parent.destroy()    

    def UrlProcessing(self):


        self.url_ok_button.config(state=DISABLED)

        self.parent.update()        

        self.url = self.downloading_url.get()

        file_name = self.GetFileName(self.url)

        if self.CheckFileExistence(file_name):

            if self.MakeRequest(self.url):

                temp_file_size = self.GetLocalFileSize(file_name)

                if temp_file_size == self.source_file_size:
                    self.ShowMessage(file_name,"File is already downloaded")
                else:

                    self.status_data_label.config(text = "connecting",fg="blue")
                    self.parent.update()

                    self.req_obj.close()

                    self.req_obj = self.SetResumeDownload(self.url,temp_file_size)

                    file_ptr = open(file_name, 'ab')

                    self.DownloadFile(file_ptr)
                    file_ptr.flush()
                    file_ptr.close()
                    self.req_obj.close()

                    if self.source_file_size == self.downloaded_file_size:
                        self.ShowMessage(file_name,"Downloading Completed")
                        self.parent.destroy()
            else:
                self.ErrorMessageHandler(self.error_msg)

        else:
            self.status_data_label.config(text = "connecting",fg="blue")
            self.parent.update()

            if self.MakeRequest(self.url):
                file_ptr = open(file_name, 'wb')


                self.DownloadFile(file_ptr)

                file_ptr.flush()
                file_ptr.close()
                self.req_obj.close()

                if self.source_file_size == self.downloaded_file_size:
                    self.ShowMessage(file_name,"Downloading Completed")
                    self.parent.destroy()
            else:
                self.ErrorMessageHandler(self.error_msg)

if __name__=='__main__' :
    root = Tk() 
    app = Downloader(root)
    root.mainloop()    

我没有使用canvas元素的经验。但这会对你有所帮助。

答案 1 :(得分:0)

textAlign只需一个字"center"。剩下的就在你的fillText电话中。

ctx4.textAlign = 'center';
ctx4.fillText(txt, canvas4.width / 2, canvas4.height - 100);

textAlign设置为"center"会使文本的中心显示在fillText调用中指定的位置。如果该点在画布上居中,则整个文本将在画布上居中。